Merge branch 'clean-up-metadata' into 'master'

collection of cleanups, tests and minor refactoring related to metadata

See merge request fdroid/fdroidserver!1351
This commit is contained in:
Michael Pöhn 2023-05-04 12:55:38 +00:00
commit acc774f91e
8 changed files with 231 additions and 206 deletions

View File

@ -110,7 +110,7 @@ def check_tags(app, pattern):
vcs.gotorevision(None)
last_build = app.get_last_build()
last_build = get_last_build_from_app(app)
try_init_submodules(app, last_build, vcs)
@ -252,10 +252,7 @@ def check_repomanifest(app, branch=None):
elif repotype == 'bzr':
vcs.gotorevision(None)
last_build = metadata.Build()
if app.get('Builds', []):
last_build = app.get('Builds', [])[-1]
last_build = get_last_build_from_app(app)
try_init_submodules(app, last_build, vcs)
hpak = None
@ -364,7 +361,7 @@ def possible_subdirs(app):
else:
build_dir = Path('build') / app.id
last_build = app.get_last_build()
last_build = get_last_build_from_app(app)
for d in dirs_with_manifest(build_dir):
m_paths = common.manifest_paths(d, last_build.gradle)
@ -399,7 +396,7 @@ def fetch_autoname(app, tag):
except VCSException:
return None
last_build = app.get_last_build()
last_build = get_last_build_from_app(app)
logging.debug("...fetch auto name from " + str(build_dir))
new_name = None
@ -579,6 +576,13 @@ def checkupdates_app(app):
raise FDroidException("Git commit failed")
def get_last_build_from_app(app):
if app.get('Builds'):
return app['Builds'][-1]
else:
return metadata.Build()
def status_update_json(processed, failed):
"""Output a JSON file with metadata about this run."""
logging.debug(_('Outputting JSON'))

View File

@ -24,14 +24,12 @@ import platform
import os
import re
import logging
import importlib
import ruamel.yaml
from collections import OrderedDict
from ruamel.yaml import YAML, YAMLError
from . import common
from . import _
from .exception import MetaDataException, FDroidException
from .exception import MetaDataException
srclibs = None
warnings_action = None
@ -109,7 +107,6 @@ yaml_app_fields = [x for x in yaml_app_field_order if x != '\n']
class App(dict):
def __init__(self, copydict=None):
if copydict:
super().__init__(copydict)
@ -177,12 +174,6 @@ class App(dict):
else:
raise AttributeError("No such attribute: " + name)
def get_last_build(self):
if len(self.Builds) > 0:
return self.Builds[-1]
else:
return Build()
TYPE_STRING = 2
TYPE_BOOL = 3
@ -252,7 +243,6 @@ build_flags = [
class Build(dict):
def __init__(self, copydict=None):
super().__init__()
self.disable = ''
@ -307,6 +297,10 @@ class Build(dict):
else:
raise AttributeError("No such attribute: " + name)
@classmethod
def to_yaml(cls, representer, node):
return representer.represent_dict(node)
def build_method(self):
for f in ['maven', 'gradle']:
if self.get(f):
@ -375,7 +369,7 @@ def flagtype(name):
return TYPE_STRING
class FieldValidator():
class FieldValidator:
"""Designate App metadata field types and checks that it matches.
'name' - The long name of the field type
@ -399,8 +393,13 @@ class FieldValidator():
values = [v]
for v in values:
if not self.compiled.match(v):
_warn_or_exception(_("'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}")
.format(value=v, field=self.name, appid=appid, pattern=self.matching))
_warn_or_exception(
_(
"'{value}' is not a valid {field} in {appid}. Regex pattern: {pattern}"
).format(
value=v, field=self.name, appid=appid, pattern=self.matching
)
)
# Generic value types
@ -471,21 +470,19 @@ def check_metadata(app):
def parse_yaml_srclib(metadatapath):
thisinfo = {'RepoType': '',
'Repo': '',
'Subdir': None,
'Prepare': None}
thisinfo = {'RepoType': '', 'Repo': '', 'Subdir': None, 'Prepare': None}
if not metadatapath.exists():
_warn_or_exception(_("Invalid scrlib metadata: '{file}' "
"does not exist"
.format(file=metadatapath)))
_warn_or_exception(
_("Invalid scrlib metadata: '{file}' does not exist").format(
file=metadatapath
)
)
return thisinfo
with metadatapath.open("r", encoding="utf-8") as f:
try:
yaml = YAML(typ='safe')
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(f)
if type(data) is not dict:
if platform.system() == 'Windows':
@ -495,9 +492,10 @@ def parse_yaml_srclib(metadatapath):
with symlink.open("r", encoding="utf-8") as s:
data = yaml.load(s)
if type(data) is not dict:
raise YAMLError(_('{file} is blank or corrupt!')
.format(file=metadatapath))
except YAMLError as e:
raise ruamel.yaml.YAMLError(
_('{file} is blank or corrupt!').format(file=metadatapath)
)
except ruamel.yaml.YAMLError as e:
_warn_or_exception(_("Invalid srclib metadata: could not "
"parse '{file}'")
.format(file=metadatapath) + '\n'
@ -507,9 +505,11 @@ def parse_yaml_srclib(metadatapath):
for key in data:
if key not in thisinfo:
_warn_or_exception(_("Invalid srclib metadata: unknown key "
"'{key}' in '{file}'")
.format(key=key, file=metadatapath))
_warn_or_exception(
_("Invalid srclib metadata: unknown key '{key}' in '{file}'").format(
key=key, file=metadatapath
)
)
return thisinfo
else:
if key == 'Subdir':
@ -580,7 +580,8 @@ def read_metadata(appids={}, sort_by_time=False):
metadatafiles = common.get_metadata_files(vercodes)
else:
metadatafiles = list(Path('metadata').glob('*.yml')) + list(
Path('.').glob('.fdroid.yml'))
Path('.').glob('.fdroid.yml')
)
if sort_by_time:
entries = ((path.stat().st_mtime, path) for path in metadatafiles)
@ -594,11 +595,15 @@ def read_metadata(appids={}, sort_by_time=False):
for metadatapath in metadatafiles:
appid = metadatapath.stem
if appid != '.fdroid' and not common.is_valid_package_name(appid):
_warn_or_exception(_("{appid} from {path} is not a valid Java Package Name!")
.format(appid=appid, path=metadatapath))
_warn_or_exception(
_("{appid} from {path} is not a valid Java Package Name!").format(
appid=appid, path=metadatapath
)
)
if appid in apps:
_warn_or_exception(_("Found multiple metadata files for {appid}")
.format(appid=appid))
_warn_or_exception(
_("Found multiple metadata files for {appid}").format(appid=appid)
)
app = parse_metadata(metadatapath)
check_metadata(app)
apps[app.id] = app
@ -654,8 +659,9 @@ def parse_metadata(metadatapath):
with metadatapath.open('r', encoding='utf-8') as mf:
app.update(parse_yaml_metadata(mf))
else:
_warn_or_exception(_('Unknown metadata format: {path} (use: *.yml)')
.format(path=metadatapath))
_warn_or_exception(
_('Unknown metadata format: {path} (use: *.yml)').format(path=metadatapath)
)
if metadatapath.name != '.fdroid.yml' and app.Repo:
build_dir = common.get_build_dir(app)
@ -663,11 +669,15 @@ def parse_metadata(metadatapath):
if metadata_in_repo.is_file():
try:
commit_id = common.get_head_commit_id(git.Repo(build_dir))
logging.debug(_('Including metadata from %s@%s') % (metadata_in_repo, commit_id))
logging.debug(
_('Including metadata from %s@%s') % (metadata_in_repo, commit_id)
)
# See https://github.com/PyCQA/pylint/issues/2856 .
# pylint: disable-next=no-member
except git.exc.InvalidGitRepositoryError:
logging.debug(_('Including metadata from {path}').format(metadata_in_repo))
logging.debug(
_('Including metadata from {path}').format(metadata_in_repo)
)
app_in_repo = parse_metadata(metadata_in_repo)
for k, v in app_in_repo.items():
if k not in app:
@ -708,13 +718,15 @@ def parse_yaml_metadata(mf):
"""
try:
yaml = YAML(typ='safe')
yaml = ruamel.yaml.YAML(typ='safe')
yamldata = yaml.load(mf)
except YAMLError as e:
_warn_or_exception(_("could not parse '{path}'")
.format(path=mf.name) + '\n'
+ common.run_yamllint(mf.name, indent=4),
cause=e)
except ruamel.yaml.YAMLError as e:
_warn_or_exception(
_("could not parse '{path}'").format(path=mf.name)
+ '\n'
+ common.run_yamllint(mf.name, indent=4),
cause=e,
)
if yamldata is None or yamldata == '':
yamldata = dict()
@ -788,15 +800,16 @@ def post_parse_yaml_metadata(yamldata):
"""
for k, v in yamldata.items():
if fieldtype(k) == TYPE_LIST:
_fieldtype = fieldtype(k)
if _fieldtype == TYPE_LIST:
if isinstance(v, str):
yamldata[k] = [v, ]
yamldata[k] = [v]
elif v:
yamldata[k] = [str(i) for i in v]
elif fieldtype(k) == TYPE_INT:
elif _fieldtype == TYPE_INT:
if v:
yamldata[k] = int(v)
elif fieldtype(k) == TYPE_STRING:
elif _fieldtype == TYPE_STRING:
if v or v == 0:
yamldata[k] = _normalize_type_string(v)
else:
@ -810,10 +823,10 @@ def post_parse_yaml_metadata(yamldata):
continue
_flagtype = flagtype(k)
if _flagtype is TYPE_STRING:
if _flagtype == TYPE_STRING:
if v or v == 0:
build[k] = _normalize_type_string(v)
elif _flagtype is TYPE_INT:
elif _flagtype == TYPE_INT:
build[k] = v
# versionCode must be int
if not isinstance(v, int):
@ -851,33 +864,18 @@ def write_yaml(mf, app):
app
app metadata to written to the yaml file
"""
# import rumael.yaml and check version
try:
import ruamel.yaml
except ImportError as e:
raise FDroidException('ruamel.yaml not installed, can not write metadata.') from e
if not ruamel.yaml.__version__:
raise FDroidException('ruamel.yaml.__version__ not accessible. Please make sure a ruamel.yaml >= 0.13 is installed..')
m = re.match(r'(?P<major>[0-9]+)\.(?P<minor>[0-9]+)\.(?P<patch>[0-9]+)(-.+)?',
ruamel.yaml.__version__)
if not m:
raise FDroidException('ruamel.yaml version malfored, please install an upstream version of ruamel.yaml')
if int(m.group('major')) < 0 or int(m.group('minor')) < 13:
raise FDroidException('currently installed version of ruamel.yaml ({}) is too old, >= 1.13 required.'.format(ruamel.yaml.__version__))
# suiteable version ruamel.yaml imported successfully
def _field_to_yaml(typ, value):
"""Convert data to YAML 1.2 format that keeps the right TYPE_*."""
if typ is TYPE_STRING:
if typ == TYPE_STRING:
return str(value)
elif typ is TYPE_INT:
elif typ == TYPE_INT:
return int(value)
elif typ is TYPE_MULTILINE:
elif typ == TYPE_MULTILINE:
if '\n' in value:
return ruamel.yaml.scalarstring.preserve_literal(str(value))
else:
return str(value)
elif typ is TYPE_SCRIPT:
elif typ == TYPE_SCRIPT:
if type(value) == list:
if len(value) == 1:
return value[0]
@ -930,7 +928,9 @@ def write_yaml(mf, app):
if hasattr(build, field):
value = getattr(build, field)
if field == 'gradle' and value == ['off']:
value = [ruamel.yaml.scalarstring.SingleQuotedScalarString('off')]
value = [
ruamel.yaml.scalarstring.SingleQuotedScalarString('off')
]
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):
@ -945,27 +945,25 @@ def write_yaml(mf, app):
return builds
yaml_app = _app_to_yaml(app)
try:
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.dump(yaml_app, stream=mf)
except AttributeError: # Debian/stretch's version does not have YAML()
ruamel.yaml.round_trip_dump(yaml_app, mf, indent=4, block_seq_indent=2)
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4, sequence=4, offset=2)
yaml.dump(yaml_app, stream=mf)
def write_metadata(metadatapath, app):
metadatapath = Path(metadatapath)
if metadatapath.suffix == '.yml':
if importlib.util.find_spec('ruamel.yaml'):
with metadatapath.open('w') as mf:
return write_yaml(mf, app)
else:
raise FDroidException(_('ruamel.yaml not installed, can not write metadata.'))
with metadatapath.open('w') as mf:
return write_yaml(mf, app)
_warn_or_exception(_('Unknown metadata format: %s') % metadatapath)
def add_metadata_arguments(parser):
"""Add common command line flags related to metadata processing."""
parser.add_argument("-W", choices=['error', 'warn', 'ignore'], default='error',
help=_("force metadata errors (default) to be warnings, or to be ignored."))
parser.add_argument(
"-W",
choices=['error', 'warn', 'ignore'],
default='error',
help=_("force metadata errors (default) to be warnings, or to be ignored."),
)

View File

@ -6,22 +6,17 @@ import logging
import optparse
import os
import random
import ruamel.yaml
import shutil
import sys
import unittest
from unittest import mock
import tempfile
import textwrap
from collections import OrderedDict
from pathlib import Path
from testcommon import TmpCwd
from ruamel.yaml import YAML
yaml = YAML(typ='safe')
localmodule = Path(__file__).resolve().parent.parent
print('localmodule: ' + str(localmodule))
if localmodule not in sys.path:
@ -32,6 +27,12 @@ from fdroidserver import metadata
from fdroidserver.exception import MetaDataException
def _get_mock_mf(s):
mf = io.StringIO(s)
mf.name = 'mock_filename.yaml'
return mf
class MetadataTest(unittest.TestCase):
'''fdroidserver/metadata.py'''
@ -39,6 +40,7 @@ class MetadataTest(unittest.TestCase):
logging.basicConfig(level=logging.DEBUG)
self.basedir = localmodule / 'tests'
os.chdir(self.basedir)
fdroidserver.metadata.warnings_action = 'error'
def tearDown(self):
# auto-generated dirs by functions, not tests, so they are not always cleaned up
@ -67,8 +69,6 @@ class MetadataTest(unittest.TestCase):
break
self.assertIsNotNone(validator, "could not find 'Bitcoin address' validator")
fdroidserver.metadata.warnings_action = 'error'
# some valid addresses (P2PKH, P2SH, Bech32)
self.assertIsNone(
validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id')
@ -126,8 +126,6 @@ class MetadataTest(unittest.TestCase):
break
self.assertIsNotNone(validator, "could not find 'Litecoin address' validator")
fdroidserver.metadata.warnings_action = 'error'
# some valid addresses (L, M, 3, segwit)
self.assertIsNone(
validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id')
@ -180,9 +178,30 @@ class MetadataTest(unittest.TestCase):
'fake.app.id',
)
def test_check_metadata_AntiFeatures(self):
fdroidserver.metadata.warnings_action = 'error'
app = fdroidserver.metadata.App()
self.assertIsNone(metadata.check_metadata(app))
app['AntiFeatures'] = []
self.assertIsNone(metadata.check_metadata(app))
app['AntiFeatures'] = ['Ads', 'UpstreamNonFree']
self.assertIsNone(metadata.check_metadata(app))
app['AntiFeatures'] = ['Ad']
with self.assertRaises(fdroidserver.exception.MetaDataException):
metadata.check_metadata(app)
app['AntiFeatures'] = ['Adss']
with self.assertRaises(fdroidserver.exception.MetaDataException):
metadata.check_metadata(app)
def test_valid_funding_yml_regex(self):
"""Check the regex can find all the cases"""
with (self.basedir / 'funding-usernames.yaml').open() as fp:
yaml = ruamel.yaml.YAML(typ='safe')
data = yaml.load(fp)
for k, entries in data.items():
@ -200,10 +219,7 @@ class MetadataTest(unittest.TestCase):
)
def test_read_metadata(self):
def _build_yaml_representer(dumper, data):
'''Creates a YAML representation of a Build instance'''
return dumper.represent_dict(data)
"""Read specified metadata files included in tests/, compare to stored output"""
self.maxDiff = None
config = dict()
@ -211,6 +227,7 @@ class MetadataTest(unittest.TestCase):
fdroidserver.common.config = config
fdroidserver.metadata.warnings_action = None
yaml = ruamel.yaml.YAML(typ='safe')
apps = fdroidserver.metadata.read_metadata()
for appid in (
'org.smssecure.smssecure',
@ -226,9 +243,10 @@ class MetadataTest(unittest.TestCase):
self.assertEqual(frommeta, from_yaml)
# comment above assert and uncomment below to update test
# files when new metadata fields are added
# with savepath.open('w') as f:
# yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer)
# yaml.dump(frommeta, f, default_flow_style=False)
# with savepath.open('w') as fp:
# yaml.default_flow_style = False
# yaml.register_class(metadata.Build)
# yaml.dump(frommeta, fp)
def test_rewrite_yaml_fakeotaupdate(self):
with tempfile.TemporaryDirectory() as testdir:
@ -306,7 +324,20 @@ class MetadataTest(unittest.TestCase):
self.assertEqual('true', metadata._normalize_type_string(True))
def test_post_parse_yaml_metadata(self):
fdroidserver.metadata.warnings_action = 'error'
yamldata = dict()
metadata.post_parse_yaml_metadata(yamldata)
yamldata[
'AllowedAPKSigningKeys'
] = 'c03dac71394d6c26766f1b04d3e31cfcac5d03b55d8aa40cc9b9fa6b74354c66'
metadata.post_parse_yaml_metadata(yamldata)
def test_post_parse_yaml_metadata_fails(self):
yamldata = {'AllowedAPKSigningKeys': True}
with self.assertRaises(TypeError):
metadata.post_parse_yaml_metadata(yamldata)
def test_post_parse_yaml_metadata_builds(self):
yamldata = OrderedDict()
builds = []
yamldata['Builds'] = builds
@ -380,17 +411,45 @@ class MetadataTest(unittest.TestCase):
self.assertEqual(randomlist, allappids)
def test_parse_yaml_metadata_0size_file(self):
mf = io.StringIO('')
mf.name = 'mock_filename.yaml'
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
self.assertEqual(dict(), metadata.parse_yaml_metadata(_get_mock_mf('')))
def test_parse_yaml_metadata_empty_dict_file(self):
mf = io.StringIO('{}')
mf.name = 'mock_filename.yaml'
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
self.assertEqual(dict(), metadata.parse_yaml_metadata(_get_mock_mf('{}')))
def test_parse_yaml_metadata_empty_string_file(self):
mf = io.StringIO('""')
self.assertEqual(dict(), metadata.parse_yaml_metadata(_get_mock_mf('""')))
def test_parse_yaml_metadata_fail_on_root_list(self):
with self.assertRaises(MetaDataException):
metadata.parse_yaml_metadata(_get_mock_mf('-'))
with self.assertRaises(MetaDataException):
metadata.parse_yaml_metadata(_get_mock_mf('[]'))
with self.assertRaises(MetaDataException):
metadata.parse_yaml_metadata(_get_mock_mf('- AutoName: fake'))
def test_parse_yaml_metadata_type_list_str(self):
v = 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
mf = _get_mock_mf('AllowedAPKSigningKeys: "%s"' % v)
self.assertEqual(
v,
metadata.parse_yaml_metadata(mf)['AllowedAPKSigningKeys'][0],
)
def test_parse_yaml_metadata_type_list_build_str(self):
mf = _get_mock_mf('Builds: [{versionCode: 1, rm: s}]')
self.assertEqual(
metadata.parse_yaml_metadata(mf),
{'Builds': [{'rm': ['s'], 'versionCode': 1}]},
)
def test_parse_yaml_metadata_app_type_list_fails(self):
mf = _get_mock_mf('AllowedAPKSigningKeys: true')
with self.assertRaises(TypeError):
metadata.parse_yaml_metadata(mf)
mf = _get_mock_mf('AllowedAPKSigningKeys: 1')
with self.assertRaises(TypeError):
metadata.parse_yaml_metadata(mf)
mf.name = 'mock_filename.yaml'
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
@ -405,9 +464,8 @@ class MetadataTest(unittest.TestCase):
)
)
mf.name = 'mock_filename.yaml'
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_metadata(mf)
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_metadata(mf)
def test_parse_yaml_metadata_unknown_build_flag(self):
mf = io.StringIO(
@ -420,9 +478,8 @@ class MetadataTest(unittest.TestCase):
)
)
mf.name = 'mock_filename.yaml'
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_metadata(mf)
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_metadata(mf)
def test_parse_yaml_metadata_continue_on_warning(self):
"""When errors are disabled, parsing should provide something that can work.
@ -436,8 +493,7 @@ class MetadataTest(unittest.TestCase):
"""
fdroidserver.metadata.warnings_action = None
mf = io.StringIO('[AntiFeatures: Tracking]')
mf.name = 'mock_filename.yaml'
mf = _get_mock_mf('[AntiFeatures: Tracking]')
self.assertEqual(fdroidserver.metadata.parse_yaml_metadata(mf), dict())
def test_parse_yaml_srclib_corrupt_file(self):
@ -454,9 +510,8 @@ class MetadataTest(unittest.TestCase):
"""
)
)
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_srclib(srclibfile)
with self.assertRaises(MetaDataException):
fdroidserver.metadata.parse_yaml_srclib(srclibfile)
def test_write_yaml_with_placeholder_values(self):
mf = io.StringIO()
@ -535,8 +590,7 @@ class MetadataTest(unittest.TestCase):
)
mf.name = 'mock_filename.yaml'
mf.seek(0)
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
result = fdroidserver.metadata.parse_yaml_metadata(mf)
result = fdroidserver.metadata.parse_yaml_metadata(mf)
self.maxDiff = None
self.assertDictEqual(
result,
@ -590,8 +644,7 @@ class MetadataTest(unittest.TestCase):
)
mf.name = 'mock_filename.yaml'
mf.seek(0)
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
result = fdroidserver.metadata.parse_yaml_metadata(mf)
result = fdroidserver.metadata.parse_yaml_metadata(mf)
self.maxDiff = None
self.assertDictEqual(
result,
@ -640,8 +693,7 @@ class MetadataTest(unittest.TestCase):
)
mf.name = 'mock_filename.yaml'
mf.seek(0)
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
result = fdroidserver.metadata.parse_yaml_metadata(mf)
result = fdroidserver.metadata.parse_yaml_metadata(mf)
self.assertDictEqual(
result,
{
@ -674,10 +726,9 @@ class MetadataTest(unittest.TestCase):
)
mf.name = 'mock_filename.yaml'
mf.seek(0)
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
result = fdroidserver.metadata.parse_yaml_metadata(mf)
self.assertNotIn('Provides', result)
self.assertNotIn('provides', result)
result = fdroidserver.metadata.parse_yaml_metadata(mf)
self.assertNotIn('Provides', result)
self.assertNotIn('provides', result)
def test_write_yaml_1_line_scripts_as_string(self):
mf = io.StringIO()
@ -903,7 +954,6 @@ class MetadataTest(unittest.TestCase):
)
def test_parse_yaml_srclib_unknown_key(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with Path('test.yml').open('w', encoding='utf-8') as f:
f.write(
@ -922,7 +972,6 @@ class MetadataTest(unittest.TestCase):
fdroidserver.metadata.parse_yaml_srclib(Path('test.yml'))
def test_parse_yaml_srclib_does_not_exists(self):
fdroidserver.metadata.warnings_action = 'error'
with self.assertRaisesRegex(
MetaDataException,
"Invalid scrlib metadata: "
@ -934,7 +983,6 @@ class MetadataTest(unittest.TestCase):
)
def test_parse_yaml_srclib_simple(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with Path('simple.yml').open('w', encoding='utf-8') as f:
f.write(
@ -958,7 +1006,6 @@ class MetadataTest(unittest.TestCase):
)
def test_parse_yaml_srclib_simple_with_blanks(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with Path('simple.yml').open('w', encoding='utf-8') as f:
f.write(
@ -988,7 +1035,6 @@ class MetadataTest(unittest.TestCase):
)
def test_parse_yaml_srclib_Changelog_cketti(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with Path('Changelog-cketti.yml').open('w', encoding='utf-8') as f:
f.write(
@ -1020,7 +1066,6 @@ class MetadataTest(unittest.TestCase):
)
def test_read_srclibs_yml_subdir_list(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
Path('srclibs').mkdir()
@ -1072,7 +1117,6 @@ class MetadataTest(unittest.TestCase):
)
def test_read_srclibs_yml_prepare_list(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
Path('srclibs').mkdir()
@ -1113,7 +1157,6 @@ class MetadataTest(unittest.TestCase):
)
def test_read_srclibs(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
Path('srclibs').mkdir()

View File

@ -1,5 +1,6 @@
AllowedAPKSigningKeys: []
AntiFeatures: ['NonFreeNet']
AntiFeatures:
- NonFreeNet
ArchivePolicy: 4 versions
AuthorEmail: null
AuthorName: null
@ -130,7 +131,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null

View File

@ -15,7 +15,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: ea5378a94ee0dc1d99d2cec95fae7e6d81afb2b9
disable: ''
encoding: null
@ -51,7 +51,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 4128e59da2eac5c2904c7c7568d298ca51e79540
disable: ''
encoding: null
@ -88,7 +88,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 0b9985398b9eef7baf6aadd0dbb12002bc199d2e
disable: ''
encoding: null
@ -125,7 +125,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: ab27f4dab5f3ea5e228cfb4a6b0e1fbf53695f22
disable: ''
encoding: null
@ -162,7 +162,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 695e3801e4081026c8f7213a2345fc451d5eb89c
disable: ''
encoding: null
@ -199,7 +199,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 65138c11cc8b6affd28b68e125fbc1dff0886a4e
disable: ''
encoding: null
@ -271,7 +271,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: f811e53e1e1d2ee047b18715fd7d2072b90ae76b
disable: ''
encoding: null
@ -308,7 +308,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: ff97932761cdee68638dc2550751a64b2cbe18e7
disable: ''
encoding: null
@ -345,7 +345,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 33d4d80998f30bafc88c04c80cbae00b03916f99
disable: ''
encoding: null
@ -382,7 +382,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: 743d25a7e287505461f33f4b8e57e4cf988fffea
disable: ''
encoding: null
@ -419,7 +419,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: eaa07f4
disable: ''
encoding: null
@ -688,7 +688,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.1
disable: ''
encoding: null
@ -738,7 +738,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.3
disable: ''
encoding: null
@ -784,7 +784,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.6
disable: ''
encoding: null
@ -792,7 +792,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -822,7 +822,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.7
disable: ''
encoding: null
@ -830,7 +830,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -860,7 +860,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.8
disable: ''
encoding: null
@ -868,7 +868,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -898,7 +898,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.8.1
disable: ''
encoding: null
@ -906,7 +906,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -936,7 +936,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.9
disable: ''
encoding: null
@ -944,7 +944,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -974,7 +974,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.9.1
disable: ''
encoding: null
@ -982,7 +982,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -1012,7 +1012,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v2.9.2
disable: ''
encoding: null
@ -1020,7 +1020,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -1050,7 +1050,7 @@ Builds:
binary: null
build: ''
buildjni:
- 'yes'
- yes
commit: v3.0
disable: ''
encoding: null
@ -1058,7 +1058,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null

View File

@ -22,7 +22,7 @@ Builds:
forcevercode: true
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -83,7 +83,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -126,7 +126,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -167,7 +167,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -208,7 +208,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -248,7 +248,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -288,7 +288,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null
@ -328,7 +328,7 @@ Builds:
forcevercode: false
forceversion: false
gradle:
- 'yes'
- yes
gradleprops: []
init: ''
maven: null

View File

@ -2640,7 +2640,7 @@ UpdateCheckIgnore: null
UpdateCheckMode: Tags
UpdateCheckName: null
VercodeOperation:
- '%c + 5'
- '%c + 5'
WebSite: http://www.videolan.org/vlc/download-android.html
added: null
id: org.videolan.vlc

View File

@ -7,10 +7,8 @@ import sys
import unittest
import tempfile
import textwrap
from unittest import mock
from pathlib import Path
from testcommon import TmpCwd
localmodule = Path(__file__).resolve().parent.parent
@ -20,7 +18,6 @@ if localmodule not in sys.path:
from fdroidserver import common
from fdroidserver import rewritemeta
from fdroidserver.exception import FDroidException
class RewriteMetaTest(unittest.TestCase):
@ -71,24 +68,6 @@ class RewriteMetaTest(unittest.TestCase):
),
)
def test_rewrite_scenario_yml_no_ruamel(self):
sys.argv = ['rewritemeta', 'a']
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
Path('metadata').mkdir()
with Path('metadata/a.yml').open('w') as f:
f.write('AutoName: a')
def boom(*args):
raise FDroidException(' '.join((str(x) for x in args)))
with mock.patch('importlib.util.find_spec', boom):
with self.assertRaises(FDroidException):
rewritemeta.main()
self.assertEqual(
Path('metadata/a.yml').read_text(encoding='utf-8'), 'AutoName: a'
)
if __name__ == "__main__":
parser = optparse.OptionParser()