diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 69b85283..aaa6312b 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -761,6 +761,23 @@ def parse_yaml_metadata(mf): return yamldata +def _normalize_type_string(v): + """Normalize any data to TYPE_STRING. + + YAML 1.2's booleans are all lowercase. + + Things like versionName are strings, but without quotes can be + numbers. Like "versionName: 1.0" would be a YAML float, but + should be a string. + + """ + if isinstance(v, bool): + if v: + return 'true' + return 'false' + return str(v) + + def post_parse_yaml_metadata(yamldata): """Convert human-readable metadata data structures into consistent data structures. @@ -769,19 +786,6 @@ def post_parse_yaml_metadata(yamldata): fixed value type, regardless of YAML 1.2's type auto-detection. """ - - def _normalize_type_string(v): - """YAML 1.2's booleans are all lowercase. - - Things like versionName are strings, but without quotes can be - numbers. Like "versionName: 1.0" would be a YAML float, but - should be a string. - - """ - if isinstance(v, bool): - return str(v).lower() - return str(v) - for k, v in yamldata.items(): if fieldtype(k) == TYPE_LIST: if isinstance(v, str): @@ -792,7 +796,7 @@ def post_parse_yaml_metadata(yamldata): if v: yamldata[k] = int(v) elif fieldtype(k) == TYPE_STRING: - if v: + if v or v == 0: yamldata[k] = _normalize_type_string(v) else: if type(v) in (float, int): @@ -806,7 +810,8 @@ def post_parse_yaml_metadata(yamldata): _flagtype = flagtype(k) if _flagtype is TYPE_STRING: - build[k] = _normalize_type_string(v) + if v or v == 0: + build[k] = _normalize_type_string(v) elif _flagtype is TYPE_INT: build[k] = v # versionCode must be int diff --git a/tests/metadata.TestCase b/tests/metadata.TestCase index 0ef9bdc1..67d63f24 100755 --- a/tests/metadata.TestCase +++ b/tests/metadata.TestCase @@ -288,6 +288,18 @@ class MetadataTest(unittest.TestCase): (Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'), ) + def test_normalize_type_string(self): + """TYPE_STRING currently has some quirky behavior.""" + self.assertEqual('123456', metadata._normalize_type_string(123456)) + self.assertEqual('1.0', metadata._normalize_type_string(1.0)) + self.assertEqual('0', metadata._normalize_type_string(0)) + self.assertEqual('0.0', metadata._normalize_type_string(0.0)) + self.assertEqual('0.1', metadata._normalize_type_string(0.1)) + self.assertEqual('[]', metadata._normalize_type_string(list())) + self.assertEqual('{}', metadata._normalize_type_string(dict())) + self.assertEqual('false', metadata._normalize_type_string(False)) + self.assertEqual('true', metadata._normalize_type_string(True)) + def test_post_parse_yaml_metadata(self): fdroidserver.metadata.warnings_action = 'error' yamldata = OrderedDict() @@ -1267,7 +1279,7 @@ class PostMetadataParseTest(unittest.TestCase): def test_post_metadata_parse_int_0(self): """Run the int 0 through the various field and flag types.""" self.assertEqual(*self._post_metadata_parse_app_list(0, 0)) - self.assertEqual(*self._post_metadata_parse_app_string(0, 0)) + self.assertEqual(*self._post_metadata_parse_app_string(0, '0')) self.assertEqual(*self._post_metadata_parse_build_bool(0, 0)) self.assertEqual(*self._post_metadata_parse_build_int(0, 0)) self.assertEqual(*self._post_metadata_parse_build_list(0, ['0'])) @@ -1277,7 +1289,7 @@ class PostMetadataParseTest(unittest.TestCase): def test_post_metadata_parse_float_0_0(self): """Run the float 0.0 through the various field and flag types.""" self.assertEqual(*self._post_metadata_parse_app_list(0.0, 0.0)) - self.assertEqual(*self._post_metadata_parse_app_string(0.0, 0.0)) + self.assertEqual(*self._post_metadata_parse_app_string(0.0, '0.0')) self.assertEqual(*self._post_metadata_parse_build_bool(0.0, 0.0)) with self.assertRaises(MetaDataException): self._post_metadata_parse_build_int(0.0, MetaDataException) @@ -1317,7 +1329,7 @@ class PostMetadataParseTest(unittest.TestCase): self._post_metadata_parse_build_int(list(), MetaDataException) self.assertEqual(*self._post_metadata_parse_build_list(list(), list())) self.assertEqual(*self._post_metadata_parse_build_script(list(), list())) - self.assertEqual(*self._post_metadata_parse_build_string(list(), '[]')) + self.assertEqual(*self._post_metadata_parse_build_string(list(), list())) def test_post_metadata_parse_set_of_1(self): self.assertEqual(*self._post_metadata_parse_app_list({1}, ['1'])) @@ -1337,7 +1349,7 @@ class PostMetadataParseTest(unittest.TestCase): self._post_metadata_parse_build_int(dict(), MetaDataException) self.assertEqual(*self._post_metadata_parse_build_list(dict(), dict())) self.assertEqual(*self._post_metadata_parse_build_script(dict(), dict())) - self.assertEqual(*self._post_metadata_parse_build_string(dict(), '{}')) + self.assertEqual(*self._post_metadata_parse_build_string(dict(), dict())) def test_post_metadata_parse_list_int_string(self): self.assertEqual(*self._post_metadata_parse_app_list([1, 'a'], ['1', 'a'])) @@ -1361,7 +1373,7 @@ class PostMetadataParseTest(unittest.TestCase): def test_post_metadata_parse_false(self): self.assertEqual(*self._post_metadata_parse_app_list(False, False)) - self.assertEqual(*self._post_metadata_parse_app_string(False, False)) + self.assertEqual(*self._post_metadata_parse_app_string(False, 'false')) self.assertEqual(*self._post_metadata_parse_build_bool(False, False)) self.assertEqual(*self._post_metadata_parse_build_int(False, False)) self.assertEqual(*self._post_metadata_parse_build_list(False, ['false']))