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:
commit
acc774f91e
|
@ -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'))
|
||||
|
|
|
@ -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."),
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue