mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-03 17:50:11 +02:00
metadata: handle TYPE_STRINGMAP when writing out YAML
This commit is contained in:
parent
e8ab84b583
commit
0393e46af9
@ -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):
|
def _del_duplicated_NoSourceSince(app):
|
||||||
# noqa: D403 NoSourceSince is the word.
|
# noqa: D403 NoSourceSince is the word.
|
||||||
"""NoSourceSince gets auto-added to AntiFeatures, but can also be manually added."""
|
"""NoSourceSince gets auto-added to AntiFeatures, but can also be manually added."""
|
||||||
@ -1080,8 +1127,13 @@ def _builds_to_yaml(app):
|
|||||||
]
|
]
|
||||||
typ = flagtype(field)
|
typ = flagtype(field)
|
||||||
# don't check value == True for TYPE_INT as it could be 0
|
# 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)})
|
b.update({field: _field_to_yaml(typ, value)})
|
||||||
|
|
||||||
builds.append(b)
|
builds.append(b)
|
||||||
|
|
||||||
# insert extra empty lines between build entries
|
# insert extra empty lines between build entries
|
||||||
@ -1107,6 +1159,10 @@ def _app_to_yaml(app):
|
|||||||
cm.update({field: _builds_to_yaml(app)})
|
cm.update({field: _builds_to_yaml(app)})
|
||||||
elif field == 'CurrentVersionCode':
|
elif field == 'CurrentVersionCode':
|
||||||
cm[field] = _field_to_yaml(TYPE_INT, value)
|
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':
|
elif field == 'AllowedAPKSigningKeys':
|
||||||
value = [str(i).lower() for i in value]
|
value = [str(i).lower() for i in value]
|
||||||
if len(value) == 1:
|
if len(value) == 1:
|
||||||
|
@ -99,6 +99,7 @@ def main():
|
|||||||
print(path)
|
print(path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# TODO these should be moved to metadata.write_yaml()
|
||||||
builds = remove_blank_flags_from_builds(app.get('Builds'))
|
builds = remove_blank_flags_from_builds(app.get('Builds'))
|
||||||
if builds:
|
if builds:
|
||||||
app['Builds'] = builds
|
app['Builds'] = builds
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AntiFeatures:
|
AntiFeatures:
|
||||||
UpstreamNonFree: {}
|
- UpstreamNonFree
|
||||||
Categories:
|
Categories:
|
||||||
- System
|
- System
|
||||||
License: GPL-3.0-only
|
License: GPL-3.0-only
|
||||||
|
@ -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):
|
def test_write_yaml_make_sure_provides_does_not_get_written(self):
|
||||||
mf = io.StringIO()
|
mf = io.StringIO()
|
||||||
app = fdroidserver.metadata.App()
|
app = fdroidserver.metadata.App()
|
||||||
@ -1649,7 +1730,7 @@ class MetadataTest(unittest.TestCase):
|
|||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""\
|
"""\
|
||||||
AntiFeatures:
|
AntiFeatures:
|
||||||
NonFreeNet: {}
|
- NonFreeNet
|
||||||
Categories:
|
Categories:
|
||||||
- Time
|
- Time
|
||||||
License: GPL-3.0-only
|
License: GPL-3.0-only
|
||||||
@ -1669,9 +1750,9 @@ class MetadataTest(unittest.TestCase):
|
|||||||
commit: 6a548e4b19
|
commit: 6a548e4b19
|
||||||
target: android-10
|
target: android-10
|
||||||
antifeatures:
|
antifeatures:
|
||||||
KnownVuln: {}
|
- KnownVuln
|
||||||
UpstreamNonFree: {}
|
- NonFreeAssets
|
||||||
NonFreeAssets: {}
|
- UpstreamNonFree
|
||||||
|
|
||||||
ArchivePolicy: 4 versions
|
ArchivePolicy: 4 versions
|
||||||
AutoUpdateMode: Version v%v
|
AutoUpdateMode: Version v%v
|
||||||
@ -1727,6 +1808,56 @@ class MetadataTest(unittest.TestCase):
|
|||||||
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 0}))
|
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 0}))
|
||||||
self.assertFalse('CurrentVersionCode' in cm)
|
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):
|
class PostMetadataParseTest(unittest.TestCase):
|
||||||
"""Test the functions that post process the YAML input.
|
"""Test the functions that post process the YAML input.
|
||||||
|
@ -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):
|
def test_rewrite_scenario_trivial(self):
|
||||||
sys.argv = ['rewritemeta', 'a', 'b']
|
sys.argv = ['rewritemeta', 'a', 'b']
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user