metadata: handle TYPE_STRINGMAP when writing out YAML

This commit is contained in:
Hans-Christoph Steiner 2023-05-08 22:03:25 +02:00
parent e8ab84b583
commit 0393e46af9
5 changed files with 218 additions and 6 deletions

View File

@ -1033,6 +1033,53 @@ def post_parse_yaml_metadata(yamldata):
}
def _format_stringmap(appid, field, stringmap, versionCode=None):
"""Format TYPE_STRINGMAP taking into account localized files in the metadata dir.
If there are any localized versions on the filesystem already,
then move them all there. Otherwise, keep them in the .yml file.
The directory for the localized files that is named after the
field is all lower case, following the convention set by Fastlane
metadata, and used by fdroidserver.
"""
app_dir = Path('metadata', appid)
try:
next(app_dir.glob('*/%s/*.txt' % field.lower()))
files = []
for name, descdict in stringmap.items():
for locale, desc in descdict.items():
outdir = app_dir / locale / field.lower()
if versionCode:
filename = '%d_%s.txt' % (versionCode, name)
else:
filename = '%s.txt' % name
outfile = outdir / filename
files.append(str(outfile))
with outfile.open('w') as fp:
fp.write(desc)
logging.warning(
_('Moving Anti-Features declarations to localized files:')
+ '\n'
+ '\n'.join(sorted(files))
)
return
except StopIteration:
pass
make_list = True
outlist = []
for name in sorted(stringmap):
outlist.append(name)
descdict = stringmap.get(name)
if descdict and any(descdict.values()):
make_list = False
break
if make_list:
return outlist
return stringmap
def _del_duplicated_NoSourceSince(app):
# noqa: D403 NoSourceSince is the word.
"""NoSourceSince gets auto-added to AntiFeatures, but can also be manually added."""
@ -1080,8 +1127,13 @@ def _builds_to_yaml(app):
]
typ = flagtype(field)
# don't check value == True for TYPE_INT as it could be 0
if value is not None and (typ == TYPE_INT or value):
if value and typ == TYPE_STRINGMAP:
v = _format_stringmap(app['id'], field, value, build['versionCode'])
if v:
b[field] = v
elif value is not None and (typ == TYPE_INT or value):
b.update({field: _field_to_yaml(typ, value)})
builds.append(b)
# insert extra empty lines between build entries
@ -1107,6 +1159,10 @@ def _app_to_yaml(app):
cm.update({field: _builds_to_yaml(app)})
elif field == 'CurrentVersionCode':
cm[field] = _field_to_yaml(TYPE_INT, value)
elif field == 'AntiFeatures':
v = _format_stringmap(app['id'], field, value)
if v:
cm[field] = v
elif field == 'AllowedAPKSigningKeys':
value = [str(i).lower() for i in value]
if len(value) == 1:

View File

@ -99,6 +99,7 @@ def main():
print(path)
continue
# TODO these should be moved to metadata.write_yaml()
builds = remove_blank_flags_from_builds(app.get('Builds'))
if builds:
app['Builds'] = builds

View File

@ -1,5 +1,5 @@
AntiFeatures:
UpstreamNonFree: {}
- UpstreamNonFree
Categories:
- System
License: GPL-3.0-only

View File

@ -1296,6 +1296,87 @@ class MetadataTest(unittest.TestCase):
),
)
def test_write_yaml_build_antifeatures(self):
mf = io.StringIO()
app = metadata.App(
{
'License': 'Apache-2.0',
'Builds': [
metadata.Build(
{
'versionCode': 102030,
'versionName': 'v1.2.3',
'gradle': ['yes'],
'antifeatures': {
'a': {},
'b': {'de': 'Probe', 'en-US': 'test'},
},
}
),
],
'id': 'placeholder',
}
)
metadata.write_yaml(mf, app)
mf.seek(0)
self.assertEqual(
mf.read(),
textwrap.dedent(
"""\
License: Apache-2.0
Builds:
- versionName: v1.2.3
versionCode: 102030
gradle:
- yes
antifeatures:
a: {}
b:
de: Probe
en-US: test
"""
),
)
def test_write_yaml_build_antifeatures_old_style(self):
mf = io.StringIO()
app = metadata.App(
{
'License': 'Apache-2.0',
'Builds': [
metadata.Build(
{
'versionCode': 102030,
'versionName': 'v1.2.3',
'gradle': ['yes'],
'antifeatures': {'b': {}, 'a': {}},
}
),
],
'id': 'placeholder',
}
)
metadata.write_yaml(mf, app)
mf.seek(0)
self.assertEqual(
mf.read(),
textwrap.dedent(
"""\
License: Apache-2.0
Builds:
- versionName: v1.2.3
versionCode: 102030
gradle:
- yes
antifeatures:
- a
- b
"""
),
)
def test_write_yaml_make_sure_provides_does_not_get_written(self):
mf = io.StringIO()
app = fdroidserver.metadata.App()
@ -1649,7 +1730,7 @@ class MetadataTest(unittest.TestCase):
textwrap.dedent(
"""\
AntiFeatures:
NonFreeNet: {}
- NonFreeNet
Categories:
- Time
License: GPL-3.0-only
@ -1669,9 +1750,9 @@ class MetadataTest(unittest.TestCase):
commit: 6a548e4b19
target: android-10
antifeatures:
KnownVuln: {}
UpstreamNonFree: {}
NonFreeAssets: {}
- KnownVuln
- NonFreeAssets
- UpstreamNonFree
ArchivePolicy: 4 versions
AutoUpdateMode: Version v%v
@ -1727,6 +1808,56 @@ class MetadataTest(unittest.TestCase):
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 0}))
self.assertFalse('CurrentVersionCode' in cm)
def test_format_stringmap_empty(self):
self.assertEqual(
metadata._format_stringmap('🔥', 'test', dict()),
list(),
)
def test_format_stringmap_one_list(self):
self.assertEqual(
metadata._format_stringmap('🔥', 'test', {'Tracking': {}, 'Ads': {}}),
['Ads', 'Tracking'],
)
def test_format_stringmap_one_list_empty_desc(self):
self.assertEqual(
metadata._format_stringmap('🔥', 'test', {'NonFree': {}, 'Ads': {'en': ''}}),
['Ads', 'NonFree'],
)
def test_format_stringmap_three_list(self):
self.assertEqual(
metadata._format_stringmap('🔥', 'test', {'B': {}, 'A': {}, 'C': {}}),
['A', 'B', 'C'],
)
def test_format_stringmap_two_dict(self):
self.assertEqual(
metadata._format_stringmap('🔥', 'test', {'1': {'uz': 'a'}, '2': {}}),
{'1': {'uz': 'a'}, '2': {}},
)
def test_format_stringmap_three_locales(self):
self.assertEqual(
metadata._format_stringmap(
'🔥', 'test', {'AF': {'uz': 'a', 'ko': 'b', 'zh': 'c'}}
),
{'AF': {'ko': 'b', 'uz': 'a', 'zh': 'c'}},
)
def test_format_stringmap_move_build_antifeatures_to_filesystem(self):
os.chdir(self.testdir)
appid = 'a'
yml = Path('metadata/a.yml')
yml.parent.mkdir()
self.assertEqual(
metadata._format_stringmap(
appid, 'antifeatures', {'AF': {'uz': 'a', 'ko': 'b', 'zh': 'c'}}
),
{'AF': {'ko': 'b', 'uz': 'a', 'zh': 'c'}},
)
class PostMetadataParseTest(unittest.TestCase):
"""Test the functions that post process the YAML input.

View File

@ -180,6 +180,30 @@ class RewriteMetaTest(unittest.TestCase):
},
)
def test_remove_blank_flags_from_builds_app_with_special_build_params_af(self):
"""Unset fields in Builds: entries should be removed."""
appid = 'app.with.special.build.params'
app = metadata.read_metadata({appid: -1})[appid]
builds = rewritemeta.remove_blank_flags_from_builds(app.get('Builds'))
self.assertEqual(
builds[-2],
{
'antifeatures': {
'Ads': {'en-US': 'includes ad lib\n', 'zh-CN': '包括广告图书馆\n'},
'Tracking': {'en-US': 'standard suspects\n'},
},
'commit': '2.1.1',
'maven': '2',
'patch': [
'manifest-ads.patch',
'mobilecore.patch',
],
'srclibs': ['FacebookSDK@sdk-version-3.0.2'],
'versionCode': 50,
'versionName': '2.1.1-c',
},
)
def test_rewrite_scenario_trivial(self):
sys.argv = ['rewritemeta', 'a', 'b']