1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-04 16:30:12 +02:00

metadata.py/rewritemeta.py: use pathlib and support Windows

This commit is contained in:
linsui 2021-06-08 21:31:55 +08:00
parent 5635815898
commit 8f21f1e510
8 changed files with 768 additions and 511 deletions

View File

@ -669,8 +669,8 @@ def get_metadata_files(vercodes):
found_invalid = False
metadatafiles = []
for appid in vercodes.keys():
f = os.path.join('metadata', '%s.yml' % appid)
if os.path.exists(f):
f = Path('metadata') / ('%s.yml' % appid)
if f.exists():
metadatafiles.append(f)
else:
found_invalid = True
@ -795,9 +795,9 @@ def get_build_dir(app):
'''get the dir that this app will be built in'''
if app.RepoType == 'srclib':
return os.path.join('build', 'srclib', app.Repo)
return Path('build/srclib') / app.Repo
return os.path.join('build', app.id)
return Path('build') / app.id
class Encoder(json.JSONEncoder):
@ -869,6 +869,8 @@ def get_head_commit_id(git_repo):
def setup_vcs(app):
'''checkout code from VCS and return instance of vcs and the build dir'''
build_dir = get_build_dir(app)
# TODO: Remove this
build_dir = str(build_dir)
# Set up vcs interface and make sure we have the latest code...
logging.debug("Getting {0} vcs interface for {1}"
@ -3982,6 +3984,8 @@ YAML_LINT_CONFIG = {'extends': 'default',
def run_yamllint(path, indent=0):
# TODO: Remove this
path = str(path)
try:
import yamllint.config
import yamllint.linter

View File

@ -19,9 +19,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import git
import os
from pathlib import Path, PurePosixPath
import platform
import re
import glob
import logging
import yaml
try:
@ -31,9 +31,9 @@ except ImportError:
import importlib
from collections import OrderedDict
import fdroidserver.common
from fdroidserver import _
from fdroidserver.exception import MetaDataException, FDroidException
from . import common
from . import _
from .exception import MetaDataException, FDroidException
srclibs = None
warnings_action = None
@ -330,7 +330,7 @@ class Build(dict):
ndk = self.ndk
if isinstance(ndk, list):
ndk = self.ndk[0]
return fdroidserver.common.config['ndk_paths'].get(ndk, '')
return common.config['ndk_paths'].get(ndk, '')
flagtypes = {
@ -470,15 +470,22 @@ def parse_yaml_srclib(metadatapath):
'Subdir': None,
'Prepare': None}
if not os.path.exists(metadatapath):
if not metadatapath.exists():
_warn_or_exception(_("Invalid scrlib metadata: '{file}' "
"does not exist"
.format(file=metadatapath)))
return thisinfo
with open(metadatapath, "r", encoding="utf-8") as f:
with metadatapath.open("r", encoding="utf-8") as f:
try:
data = yaml.load(f, Loader=SafeLoader)
if type(data) is not dict:
if platform.system() == 'Windows':
# Handle symlink on Windows
symlink = metadatapath.parent / metadatapath.read_text()
if symlink.is_file():
with symlink.open("r", encoding="utf-8") as s:
data = yaml.load(s, Loader=SafeLoader)
if type(data) is not dict:
raise yaml.error.YAMLError(_('{file} is blank or corrupt!')
.format(file=metadatapath))
@ -486,8 +493,7 @@ def parse_yaml_srclib(metadatapath):
_warn_or_exception(_("Invalid srclib metadata: could not "
"parse '{file}'")
.format(file=metadatapath) + '\n'
+ fdroidserver.common.run_yamllint(metadatapath,
indent=4),
+ common.run_yamllint(metadatapath, indent=4),
cause=e)
return thisinfo
@ -531,13 +537,11 @@ def read_srclibs():
srclibs = {}
srcdir = 'srclibs'
if not os.path.exists(srcdir):
os.makedirs(srcdir)
srcdir = Path('srclibs')
srcdir.mkdir(exist_ok=True)
for metadatapath in sorted(glob.glob(os.path.join(srcdir, '*.yml'))):
srclibname = os.path.basename(metadatapath[:-4])
srclibs[srclibname] = parse_yaml_srclib(metadatapath)
for metadatapath in sorted(srcdir.glob('*.yml')):
srclibs[metadatapath.stem] = parse_yaml_srclib(metadatapath)
def read_metadata(appids={}, sort_by_time=False):
@ -559,18 +563,17 @@ def read_metadata(appids={}, sort_by_time=False):
apps = OrderedDict()
for basedir in ('metadata', 'tmp'):
if not os.path.exists(basedir):
os.makedirs(basedir)
Path(basedir).mkdir(exist_ok=True)
if appids:
vercodes = fdroidserver.common.read_pkg_args(appids)
metadatafiles = fdroidserver.common.get_metadata_files(vercodes)
vercodes = common.read_pkg_args(appids)
metadatafiles = common.get_metadata_files(vercodes)
else:
metadatafiles = (glob.glob(os.path.join('metadata', '*.yml'))
+ glob.glob('.fdroid.yml'))
metadatafiles = list(Path('metadata').glob('*.yml')) + list(
Path('.').glob('.fdroid.yml'))
if sort_by_time:
entries = ((os.stat(path).st_mtime, path) for path in metadatafiles)
entries = ((path.stat().st_mtime, path) for path in metadatafiles)
metadatafiles = []
for _ignored, path in sorted(entries, reverse=True):
metadatafiles.append(path)
@ -579,8 +582,8 @@ def read_metadata(appids={}, sort_by_time=False):
metadatafiles = sorted(metadatafiles)
for metadatapath in metadatafiles:
appid, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath))
if appid != '.fdroid' and not fdroidserver.common.is_valid_package_name(appid):
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))
if appid in apps:
@ -684,7 +687,7 @@ def post_metadata_parse(app):
# Parse metadata for a single application.
#
# 'metadatapath' - the filename to read. The "Application ID" aka
# 'metadatapath' - the file path to read. The "Application ID" aka
# "Package Name" for the application comes from this
# filename. Pass None to get a blank entry.
#
@ -729,27 +732,27 @@ def parse_metadata(metadatapath):
the source code.
"""
metadatapath = Path(metadatapath)
app = App()
app.metadatapath = metadatapath
metadata_file = os.path.basename(metadatapath)
name, _ignored = fdroidserver.common.get_extension(metadata_file)
app.metadatapath = str(PurePosixPath(metadatapath))
name = metadatapath.stem
if name != '.fdroid':
app.id = name
if metadatapath.endswith('.yml'):
with open(metadatapath, 'r') as mf:
if metadatapath.suffix == '.yml':
with metadatapath.open('r') as mf:
parse_yaml_metadata(mf, app)
else:
_warn_or_exception(_('Unknown metadata format: {path} (use: *.yml)')
.format(path=metadatapath))
if metadata_file != '.fdroid.yml' and app.Repo:
build_dir = fdroidserver.common.get_build_dir(app)
metadata_in_repo = os.path.join(build_dir, '.fdroid.yml')
if os.path.isfile(metadata_in_repo):
if metadatapath.name != '.fdroid.yml' and app.Repo:
build_dir = common.get_build_dir(app)
metadata_in_repo = build_dir / '.fdroid.yml'
if metadata_in_repo.is_file():
try:
commit_id = fdroidserver.common.get_head_commit_id(git.repo.Repo(build_dir))
# TODO: Python3.6: Should accept path-like
commit_id = common.get_head_commit_id(git.Repo(str(build_dir)))
logging.debug(_('Including metadata from %s@%s') % (metadata_in_repo, commit_id))
except git.exc.InvalidGitRepositoryError:
logging.debug(_('Including metadata from {path}').format(metadata_in_repo))
@ -764,11 +767,11 @@ def parse_metadata(metadatapath):
if app.get('Builds'):
build = app['Builds'][-1]
if build.subdir:
root_dir = build.subdir
root_dir = Path(build.subdir)
else:
root_dir = '.'
paths = fdroidserver.common.manifest_paths(root_dir, build.gradle)
_ignored, _ignored, app.id = fdroidserver.common.parse_androidmanifests(paths, app)
root_dir = Path('.')
paths = common.manifest_paths(root_dir, build.gradle)
_ignored, _ignored, app.id = common.parse_androidmanifests(paths, app)
return app
@ -790,8 +793,7 @@ def parse_yaml_metadata(mf, app):
except yaml.YAMLError as e:
_warn_or_exception(_("could not parse '{path}'")
.format(path=mf.name) + '\n'
+ fdroidserver.common.run_yamllint(mf.name,
indent=4),
+ common.run_yamllint(mf.name, indent=4),
cause=e)
deprecated_in_yaml = ['Provides']
@ -801,7 +803,7 @@ def parse_yaml_metadata(mf, app):
if field not in yaml_app_fields + deprecated_in_yaml:
msg = (_("Unrecognised app field '{fieldname}' in '{path}'")
.format(fieldname=field, path=mf.name))
if os.path.basename(mf.name) == '.fdroid.yml':
if Path(mf.name).name == '.fdroid.yml':
logging.error(msg)
del yamldata[field]
else:
@ -978,11 +980,10 @@ build_cont = re.compile(r'^[ \t]')
def write_metadata(metadatapath, app):
# TODO: Remove this
metadatapath = str(metadatapath)
if metadatapath.endswith('.yml'):
metadatapath = Path(metadatapath)
if metadatapath.suffix == '.yml':
if importlib.util.find_spec('ruamel.yaml'):
with open(metadatapath, 'w') as mf:
with metadatapath.open('w') as mf:
return write_yaml(mf, app)
else:
raise FDroidException(_('ruamel.yaml not installed, can not write metadata.'))

View File

@ -18,11 +18,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from argparse import ArgumentParser
import os
import logging
import io
import tempfile
import shutil
from pathlib import Path
from . import _
from . import common
@ -36,9 +36,8 @@ def proper_format(app):
s = io.StringIO()
# TODO: currently reading entire file again, should reuse first
# read in metadata.py
with open(app.metadatapath, 'r') as f:
cur_content = f.read()
if app.metadatapath.endswith('.yml'):
cur_content = Path(app.metadatapath).read_text()
if Path(app.metadatapath).suffix == '.yml':
metadata.write_yaml(s, app)
content = s.getvalue()
s.close()
@ -65,8 +64,8 @@ def main():
apps = common.read_app_args(options.appid, allapps, False)
for appid, app in apps.items():
path = app.metadatapath
if path.endswith('.yml'):
path = Path(app.metadatapath)
if path.suffix == '.yml':
logging.info(_("Rewriting '{appid}'").format(appid=appid))
else:
logging.warning(_('Cannot rewrite "{path}"').format(path=path))
@ -91,9 +90,10 @@ def main():
# rewrite to temporary file before overwriting existsing
# file in case there's a bug in write_metadata
with tempfile.TemporaryDirectory() as tmpdir:
tmp_path = os.path.join(tmpdir, os.path.basename(path))
tmp_path = Path(tmpdir) / path.name
metadata.write_metadata(tmp_path, app)
shutil.move(tmp_path, path)
# TODO: Python3.6: Accept path-lik
shutil.move(str(tmp_path), str(path))
logging.debug(_("Finished"))

View File

@ -14,6 +14,7 @@ import unittest
import yaml
import zipfile
from unittest import mock
from pathlib import Path
localmodule = os.path.realpath(
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')
@ -67,31 +68,134 @@ class BuildTest(unittest.TestCase):
pass # aapt is not required if androguard is present
testcases = [
('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1', None),
('org.bitbucket.tickytacky.mirrormirror_1.apk', 'org.bitbucket.tickytacky.mirrormirror', '1', '1.0', None),
('org.bitbucket.tickytacky.mirrormirror_2.apk', 'org.bitbucket.tickytacky.mirrormirror', '2', '1.0.1', None),
('org.bitbucket.tickytacky.mirrormirror_3.apk', 'org.bitbucket.tickytacky.mirrormirror', '3', '1.0.2', None),
('org.bitbucket.tickytacky.mirrormirror_4.apk', 'org.bitbucket.tickytacky.mirrormirror', '4', '1.0.3', None),
('org.dyndns.fules.ck_20.apk', 'org.dyndns.fules.ck', '20', 'v1.6pre2',
['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']),
(
'repo/obb.main.twoversions_1101613.apk',
'obb.main.twoversions',
'1101613',
'0.1',
None,
),
(
'org.bitbucket.tickytacky.mirrormirror_1.apk',
'org.bitbucket.tickytacky.mirrormirror',
'1',
'1.0',
None,
),
(
'org.bitbucket.tickytacky.mirrormirror_2.apk',
'org.bitbucket.tickytacky.mirrormirror',
'2',
'1.0.1',
None,
),
(
'org.bitbucket.tickytacky.mirrormirror_3.apk',
'org.bitbucket.tickytacky.mirrormirror',
'3',
'1.0.2',
None,
),
(
'org.bitbucket.tickytacky.mirrormirror_4.apk',
'org.bitbucket.tickytacky.mirrormirror',
'4',
'1.0.3',
None,
),
(
'org.dyndns.fules.ck_20.apk',
'org.dyndns.fules.ck',
'20',
'v1.6pre2',
[
'arm64-v8a',
'armeabi',
'armeabi-v7a',
'mips',
'mips64',
'x86',
'x86_64',
],
),
('urzip.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-badcert.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-badsig.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-release.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-release-unsigned.apk', 'info.guardianproject.urzip', '100', '0.1', None),
(
'urzip-release-unsigned.apk',
'info.guardianproject.urzip',
'100',
'0.1',
None,
),
('repo/com.politedroid_3.apk', 'com.politedroid', '3', '1.2', None),
('repo/com.politedroid_4.apk', 'com.politedroid', '4', '1.3', None),
('repo/com.politedroid_5.apk', 'com.politedroid', '5', '1.4', None),
('repo/com.politedroid_6.apk', 'com.politedroid', '6', '1.5', None),
('repo/duplicate.permisssions_9999999.apk', 'duplicate.permisssions', '9999999', '', None),
('repo/info.zwanenburg.caffeinetile_4.apk', 'info.zwanenburg.caffeinetile', '4', '1.3', None),
('repo/obb.main.oldversion_1444412523.apk', 'obb.main.oldversion', '1444412523', '0.1', None),
('repo/obb.mainpatch.current_1619_another-release-key.apk', 'obb.mainpatch.current', '1619', '0.1', None),
('repo/obb.mainpatch.current_1619.apk', 'obb.mainpatch.current', '1619', '0.1', None),
('repo/obb.main.twoversions_1101613.apk', 'obb.main.twoversions', '1101613', '0.1', None),
('repo/obb.main.twoversions_1101615.apk', 'obb.main.twoversions', '1101615', '0.1', None),
('repo/obb.main.twoversions_1101617.apk', 'obb.main.twoversions', '1101617', '0.1', None),
('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk', 'info.guardianproject.urzip', '100', '0.1', None),
(
'repo/duplicate.permisssions_9999999.apk',
'duplicate.permisssions',
'9999999',
'',
None,
),
(
'repo/info.zwanenburg.caffeinetile_4.apk',
'info.zwanenburg.caffeinetile',
'4',
'1.3',
None,
),
(
'repo/obb.main.oldversion_1444412523.apk',
'obb.main.oldversion',
'1444412523',
'0.1',
None,
),
(
'repo/obb.mainpatch.current_1619_another-release-key.apk',
'obb.mainpatch.current',
'1619',
'0.1',
None,
),
(
'repo/obb.mainpatch.current_1619.apk',
'obb.mainpatch.current',
'1619',
'0.1',
None,
),
(
'repo/obb.main.twoversions_1101613.apk',
'obb.main.twoversions',
'1101613',
'0.1',
None,
),
(
'repo/obb.main.twoversions_1101615.apk',
'obb.main.twoversions',
'1101615',
'0.1',
None,
),
(
'repo/obb.main.twoversions_1101617.apk',
'obb.main.twoversions',
'1101617',
'0.1',
None,
),
(
'repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk',
'info.guardianproject.urzip',
'100',
'0.1',
None,
),
]
for apkfilename, appid, versionCode, versionName, nativecode in testcases:
app = fdroidserver.metadata.App()
@ -259,14 +363,26 @@ class BuildTest(unittest.TestCase):
with mock.patch('fdroidserver.common.replace_build_vars', wraps=make_fake_apk):
with mock.patch('fdroidserver.common.get_native_code', return_value='x86'):
with mock.patch('fdroidserver.common.get_apk_id',
return_value=(app.id, build.versionCode, build.versionName)):
with mock.patch('fdroidserver.common.is_apk_and_debuggable', return_value=False):
with mock.patch(
'fdroidserver.common.get_apk_id',
return_value=(app.id, build.versionCode, build.versionName),
):
with mock.patch(
'fdroidserver.common.is_apk_and_debuggable', return_value=False
):
fdroidserver.build.build_local(
app, build, vcs,
build_dir=testdir, output_dir=testdir,
log_dir=None, srclib_dir=None, extlib_dir=None, tmp_dir=None,
force=False, onserver=False, refresh=False
app,
build,
vcs,
build_dir=testdir,
output_dir=testdir,
log_dir=None,
srclib_dir=None,
extlib_dir=None,
tmp_dir=None,
force=False,
onserver=False,
refresh=False,
)
self.assertTrue(os.path.exists('foo.aar'))
@ -360,7 +476,7 @@ class BuildTest(unittest.TestCase):
}
)
app['Builds'] = [build]
fdroidserver.metadata.write_metadata(metadata_file, app)
fdroidserver.metadata.write_metadata(Path(metadata_file), app)
os.makedirs(os.path.join('unsigned', 'binaries'))
production_result = os.path.join(

View File

@ -220,9 +220,6 @@ class CheckupdatesTest(unittest.TestCase):
if __name__ == "__main__":
# TODO: Python3.6: Accept path-like object.
os.chdir(str(Path(__file__).parent))
parser = optparse.OptionParser()
parser.add_option(
"-v",

View File

@ -121,9 +121,6 @@ class ImportTest(unittest.TestCase):
if __name__ == "__main__":
# TODO: Python3.6: Support added to accept objects implementing the os.PathLike interface.
os.chdir(str(Path(__file__).parent))
parser = optparse.OptionParser()
parser.add_option(
"-v",

View File

@ -1,10 +1,6 @@
#!/usr/bin/env python3
# http://www.drdobbs.com/testing/unit-testing-with-python/240165163
import io
import glob
import inspect
import logging
import optparse
import os
@ -12,25 +8,27 @@ import random
import shutil
import sys
import unittest
import yaml
from unittest import mock
import tempfile
import textwrap
from collections import OrderedDict
from unittest import mock
from pathlib import Path
import yaml
from testcommon import TmpCwd
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader
localmodule = os.path.realpath(
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')
)
print('localmodule: ' + localmodule)
localmodule = Path(__file__).resolve().parent.parent
print('localmodule: ' + str(localmodule))
if localmodule not in sys.path:
sys.path.insert(0, localmodule)
sys.path.insert(0, str(localmodule))
from testcommon import TmpCwd
import fdroidserver.common
import fdroidserver.metadata
@ -42,11 +40,11 @@ class MetadataTest(unittest.TestCase):
def setUp(self):
logging.basicConfig(level=logging.DEBUG)
self.basedir = os.path.join(localmodule, 'tests')
self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles'))
if not os.path.exists(self.tmpdir):
os.makedirs(self.tmpdir)
os.chdir(self.basedir)
self.basedir = localmodule / 'tests'
self.tmpdir = localmodule / '.testfiles'
self.tmpdir.mkdir(exist_ok=True)
# TODO: Python3.6: Accepts a path-like object.
os.chdir(str(self.basedir))
def test_FieldValidator_BitcoinAddress(self):
validator = None
@ -59,23 +57,53 @@ class MetadataTest(unittest.TestCase):
fdroidserver.metadata.warnings_action = 'error'
# some valid addresses (P2PKH, P2SH, Bech32)
self.assertIsNone(validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id'))
self.assertIsNone(validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id'))
self.assertIsNone(validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id'))
self.assertIsNone(
validator.check('1BrrrrErsrWetrTrnrrrrm4GFg7xJaNVN2', 'fake.app.id')
)
self.assertIsNone(
validator.check('3JrrrrWrEZr3rNrrvrecrnyirrnqRhWNLy', 'fake.app.id')
)
self.assertIsNone(
validator.check('bc1qar0srrr7xrkvr5lr43lrdnwrre5rgtrzrf5rrq', 'fake.app.id')
)
# some invalid addresses
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'21BvMrSYsrWrtrrlL5A10mlGFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'L1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id')
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'21BvMrSYsrWrtrrlL5A10mlGFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'5Hrgr3ur5rGLrfKrrrrrrHSrqJrroGrrzrQrrrrrrLNrsrDrrrA',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'L1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx',
'fake.app.id',
)
def test_FieldValidator_LitecoinAddress(self):
validator = None
@ -88,27 +116,55 @@ class MetadataTest(unittest.TestCase):
fdroidserver.metadata.warnings_action = 'error'
# some valid addresses (L, M, 3)
self.assertIsNone(validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id'))
self.assertIsNone(validator.check('MrrrrrrrJAxyXpanPtrrRAX5QHxvUJo8id', 'fake.app.id'))
self.assertIsNone(
validator.check('LgeGrrrrJAxyXprrPrrBrrX5Qrrrrrrrrd', 'fake.app.id')
)
self.assertIsNone(
validator.check('MrrrrrrrJAxyXpanPtrrRAX5QHxvUJo8id', 'fake.app.id')
)
self.assertIsNone(validator.check('3rereVr9rAryrranrrrrrAXrrHx', 'fake.app.id'))
# some invalid addresses (various special use/testnet addresses, invalid chars)
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'21BvMrSYsrWrtrrrn5Au4l4GFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'5Hrgr3ur5rGLrfKrrrrrr1SrqJrroGrrzrQrrrrrrLNrsrDrrrA', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'L0000rSYsrWrtrrrn5Au4m4GFr7rrarrN2', 'fake.app.id')
self.assertRaises(fdroidserver.exception.MetaDataException, validator.check,
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx', 'fake.app.id')
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'21BvMrSYsrWrtrrrn5Au4l4GFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'5Hrgr3ur5rGLrfKrrrrrr1SrqJrroGrrzrQrrrrrrLNrsrDrrrA',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'92rr46rUrgTrrromrVrirW6r1rrrdrerrdbJrrrhrCsYrrrrrrc',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'K1BvMrSYsrWrtrrrn5Au4m4GFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'L0000rSYsrWrtrrrn5Au4m4GFr7rrarrN2',
'fake.app.id',
)
self.assertRaises(
fdroidserver.exception.MetaDataException,
validator.check,
'tb1qw5r8drrejxrrg4y5rrrrrraryrrrrwrkxrjrsx',
'fake.app.id',
)
def test_valid_funding_yml_regex(self):
"""Check the regex can find all the cases"""
with open(os.path.join(self.basedir, 'funding-usernames.yaml')) as fp:
with (self.basedir / 'funding-usernames.yaml').open() as fp:
data = yaml.load(fp, Loader=SafeLoader)
for k, entries in data.items():
@ -117,12 +173,15 @@ class MetadataTest(unittest.TestCase):
if k == 'custom':
pass
elif k == 'bad':
self.assertIsNone(m, 'this is an invalid %s username: {%s}' % (k, entry))
self.assertIsNone(
m, 'this is an invalid %s username: {%s}' % (k, entry)
)
else:
self.assertIsNotNone(m, 'this is a valid %s username: {%s}' % (k, entry))
self.assertIsNotNone(
m, 'this is a valid %s username: {%s}' % (k, entry)
)
def test_read_metadata(self):
def _build_yaml_representer(dumper, data):
'''Creates a YAML representation of a Build instance'''
return dumper.represent_dict(data)
@ -141,22 +200,22 @@ class MetadataTest(unittest.TestCase):
'org.videolan.vlc',
'com.politedroid',
):
savepath = os.path.join('metadata', 'dump', appid + '.yaml')
savepath = Path('metadata/dump') / (appid + '.yaml')
frommeta = dict(apps[appid])
self.assertTrue(appid in apps)
with open(savepath, 'r') as f:
with savepath.open('r') as f:
from_yaml = yaml.load(f, Loader=SafeLoader)
self.assertEqual(frommeta, from_yaml)
# comment above assert and uncomment below to update test
# files when new metadata fields are added
# with open(savepath, 'w') as f:
# with savepath.open('w') as f:
# yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer)
# yaml.dump(frommeta, f, default_flow_style=False)
def test_rewrite_yaml_fakeotaupdate(self):
testdir = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
# TODO: Pytohn3.6: The dir parameter now accepts a path-like object.
with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir:
testdir = Path(testdir)
fdroidserver.common.config = {'accepted_formats': ['yml']}
fdroidserver.metadata.warnings_action = None
@ -165,19 +224,21 @@ class MetadataTest(unittest.TestCase):
for appid, app in allapps.items():
if appid == 'fake.ota.update':
fdroidserver.metadata.write_metadata(
os.path.join(testdir, appid + '.yml'), app
testdir / (appid + '.yml'), app
)
# assert rewrite result
with open(os.path.join(testdir, 'fake.ota.update.yml'), 'r') as result:
with open('metadata-rewrite-yml/fake.ota.update.yml', 'r') as orig:
self.maxDiff = None
self.assertEqual(result.read(), orig.read())
file_name = 'fake.ota.update.yml'
self.assertEqual(
(testdir / file_name).read_text(),
(Path('metadata-rewrite-yml') / file_name).read_text(),
)
def test_rewrite_yaml_fdroidclient(self):
testdir = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
# TODO: Pytohn3.6: The dir parameter now accepts a path-like object.
with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir:
testdir = Path(testdir)
fdroidserver.common.config = {'accepted_formats': ['yml']}
# rewrite metadata
@ -185,33 +246,37 @@ class MetadataTest(unittest.TestCase):
for appid, app in allapps.items():
if appid == 'org.fdroid.fdroid':
fdroidserver.metadata.write_metadata(
os.path.join(testdir, appid + '.yml'), app
testdir / (appid + '.yml'), app
)
# assert rewrite result
with open(os.path.join(testdir, 'org.fdroid.fdroid.yml'), 'r') as result:
with open('metadata-rewrite-yml/org.fdroid.fdroid.yml', 'r') as orig:
self.maxDiff = None
self.assertEqual(result.read(), orig.read())
file_name = 'org.fdroid.fdroid.yml'
self.assertEqual(
(testdir / file_name).read_text(),
(Path('metadata-rewrite-yml') / file_name).read_text(),
)
def test_rewrite_yaml_special_build_params(self):
testdir = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
# TODO: Pytohn3.6: The dir parameter now accepts a path-like object.
with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir:
testdir = Path(testdir)
# rewrite metadata
allapps = fdroidserver.metadata.read_metadata()
for appid, app in allapps.items():
if appid == 'app.with.special.build.params':
fdroidserver.metadata.write_metadata(
os.path.join(testdir, appid + '.yml'), app
testdir / (appid + '.yml'), app
)
# assert rewrite result
with open(os.path.join(testdir, 'app.with.special.build.params.yml'), 'r') as result:
with open('metadata-rewrite-yml/app.with.special.build.params.yml', 'r') as orig:
self.maxDiff = None
self.assertEqual(result.read(), orig.read())
file_name = 'app.with.special.build.params.yml'
self.assertEqual(
(testdir / file_name).read_text(),
(Path('metadata-rewrite-yml') / file_name).read_text(),
)
def test_post_parse_yaml_metadata(self):
fdroidserver.metadata.warnings_action = 'error'
@ -222,12 +287,18 @@ class MetadataTest(unittest.TestCase):
builds.append(build)
build['versionCode'] = 1.1
self.assertRaises(fdroidserver.exception.MetaDataException,
fdroidserver.metadata.post_parse_yaml_metadata, yamldata)
self.assertRaises(
fdroidserver.exception.MetaDataException,
fdroidserver.metadata.post_parse_yaml_metadata,
yamldata,
)
build['versionCode'] = '1'
self.assertRaises(fdroidserver.exception.MetaDataException,
fdroidserver.metadata.post_parse_yaml_metadata, yamldata)
self.assertRaises(
fdroidserver.exception.MetaDataException,
fdroidserver.metadata.post_parse_yaml_metadata,
yamldata,
)
build['versionCode'] = 1
build['versionName'] = 1
@ -258,25 +329,28 @@ class MetadataTest(unittest.TestCase):
self.assertEqual('1234567890', yamldata['Builds'][0]['commit'])
def test_read_metadata_sort_by_time(self):
testdir = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
metadatadir = os.path.join(testdir, 'metadata')
os.makedirs(metadatadir)
# TODO: Pytohn3.6: The dir parameter now accepts a path-like object.
with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir, TmpCwd(
testdir
):
testdir = Path(testdir)
metadatadir = testdir / 'metadata'
metadatadir.mkdir()
randomlist = []
randomapps = glob.glob(os.path.join(self.basedir, 'metadata', '*.yml'))
randomapps = list((self.basedir / 'metadata').glob('*.yml'))
random.shuffle(randomapps)
i = 1
for f in randomapps:
shutil.copy(f, metadatadir)
new = os.path.join(metadatadir, os.path.basename(f))
stat = os.stat(new)
os.utime(new, (stat.st_ctime, stat.st_mtime + i))
# TODO: Pytohn3.6: The parameter now accepts a path-like object.
shutil.copy(str(f), str(metadatadir))
new = metadatadir / f.name
stat = new.stat()
# TODO: Changed in version 3.6: Accepts a path-like object.
os.utime(str(new), (stat.st_ctime, stat.st_mtime + i))
# prepend new item so newest is always first
randomlist = [os.path.basename(f)[:-4]] + randomlist
randomlist = [f.stem] + randomlist
i += 1
os.chdir(testdir)
allapps = fdroidserver.metadata.read_metadata(sort_by_time=True)
allappids = []
for appid, app in allapps.items():
@ -314,12 +388,12 @@ class MetadataTest(unittest.TestCase):
fdroidserver.metadata.parse_yaml_metadata(mf, {})
def test_parse_yaml_srclib_corrupt_file(self):
testdir = tempfile.mkdtemp(
prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir
)
srclibfile = os.path.join(testdir, 'srclib', 'mock.yml')
os.mkdir(os.path.dirname(srclibfile))
with open(srclibfile, 'w') as fp:
# TODO: Pytohn3.6: The dir parameter now accepts a path-like object.
with tempfile.TemporaryDirectory(dir=str(self.tmpdir)) as testdir:
testdir = Path(testdir)
srclibfile = testdir / 'srclib/mock.yml'
srclibfile.parent.mkdir()
with srclibfile.open('w') as fp:
fp.write(
textwrap.dedent(
"""
@ -413,9 +487,14 @@ class MetadataTest(unittest.TestCase):
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
fdroidserver.metadata.parse_yaml_metadata(mf, result)
self.maxDiff = None
self.assertDictEqual(result, {'AutoName': 'F-Droid',
self.assertDictEqual(
result,
{
'AutoName': 'F-Droid',
'RepoType': 'git',
'Builds': [{'versionCode': 1,
'Builds': [
{
'versionCode': 1,
'versionName': 'v0.1.0',
'sudo': "apt-get update && "
"apt-get install -y whatever && "
@ -425,7 +504,11 @@ class MetadataTest(unittest.TestCase):
'prebuild': "npm something && echo 'important setting' >> /a/file",
'build': "./gradlew someSpecialTask && "
"sed -i 'd/that wrong config/' gradle.properties && "
"./gradlew compile"}]})
"./gradlew compile",
}
],
},
)
def test_parse_yaml_metadata_prebuild_strings(self):
mf = io.StringIO(
@ -451,9 +534,14 @@ class MetadataTest(unittest.TestCase):
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
fdroidserver.metadata.parse_yaml_metadata(mf, result)
self.maxDiff = None
self.assertDictEqual(result, {'AutoName': 'F-Droid',
self.assertDictEqual(
result,
{
'AutoName': 'F-Droid',
'RepoType': 'git',
'Builds': [{'versionCode': 1,
'Builds': [
{
'versionCode': 1,
'versionName': 'v0.1.0',
'sudo': "apt-get update && "
"apt-get install -y whatever && "
@ -463,7 +551,11 @@ class MetadataTest(unittest.TestCase):
'prebuild': "npm something && echo 'important setting' >> /a/file",
'build': "./gradlew someSpecialTask && "
"sed -i 'd/that wrong config/' gradle.properties && "
"./gradlew compile"}]})
"./gradlew compile",
}
],
},
)
def test_parse_yaml_metadata_prebuild_string(self):
mf = io.StringIO(
@ -484,12 +576,20 @@ class MetadataTest(unittest.TestCase):
result = {}
with mock.patch('fdroidserver.metadata.warnings_action', 'error'):
fdroidserver.metadata.parse_yaml_metadata(mf, result)
self.assertDictEqual(result, {'AutoName': 'F-Droid',
self.assertDictEqual(
result,
{
'AutoName': 'F-Droid',
'RepoType': 'git',
'Builds': [{'versionCode': 1,
'Builds': [
{
'versionCode': 1,
'versionName': 'v0.1.0',
'prebuild': "a && b && "
"sed -i 's,a,b,'"}]})
'prebuild': "a && b && " "sed -i 's,a,b,'",
}
],
},
)
def test_parse_yaml_provides_should_be_ignored(self):
mf = io.StringIO(
@ -596,16 +696,21 @@ class MetadataTest(unittest.TestCase):
build = fdroidserver.metadata.Build()
build.versionCode = 102030
build.versionName = 'v1.2.3'
build.sudo = ["apt-get update",
build.sudo = [
"apt-get update",
"apt-get install -y whatever",
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml"]
build.init = ["bash generate_some_file.sh",
"sed -i -e 'g/what/ever/' /some/file"]
build.prebuild = ["npm something",
"echo 'important setting' >> /a/file"]
build.build = ["./gradlew someSpecialTask",
"sed -i -e 's/<that attr=\"bad\"/<that attr=\"good\"/' ~/.whatever/config.xml",
]
build.init = [
"bash generate_some_file.sh",
"sed -i -e 'g/what/ever/' /some/file",
]
build.prebuild = ["npm something", "echo 'important setting' >> /a/file"]
build.build = [
"./gradlew someSpecialTask",
"sed -i 'd/that wrong config/' gradle.properties",
"./gradlew compile"]
"./gradlew compile",
]
app['Builds'].append(build)
fdroidserver.metadata.write_yaml(mf, app)
mf.seek(0)
@ -724,46 +829,62 @@ 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 open('test.yml', 'w', encoding='utf-8') as f:
f.write(textwrap.dedent('''\
with Path('test.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
RepoType: git
Repo: https://example.com/test.git
Evil: I should not be here.
'''))
with self.assertRaisesRegex(MetaDataException,
"Invalid srclib metadata: "
"unknown key 'Evil' in "
"'test.yml'"):
fdroidserver.metadata.parse_yaml_srclib('test.yml')
'''
)
)
with self.assertRaisesRegex(
MetaDataException,
"Invalid srclib metadata: " "unknown key 'Evil' in " "'test.yml'",
):
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,
with self.assertRaisesRegex(
MetaDataException,
"Invalid scrlib metadata: "
"'non/existent-test-srclib.yml' "
"does not exist"):
fdroidserver.metadata.parse_yaml_srclib('non/existent-test-srclib.yml')
r"'non(/|\\)existent-test-srclib.yml' "
"does not exist",
):
fdroidserver.metadata.parse_yaml_srclib(
Path('non/existent-test-srclib.yml')
)
def test_parse_yaml_srclib_simple(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with open('simple.yml', 'w', encoding='utf-8') as f:
f.write(textwrap.dedent('''\
with Path('simple.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
# this should be simple
RepoType: git
Repo: https://git.host/repo.git
'''))
srclib = fdroidserver.metadata.parse_yaml_srclib('simple.yml')
self.assertDictEqual({'Repo': 'https://git.host/repo.git',
'''
)
)
srclib = fdroidserver.metadata.parse_yaml_srclib(Path('simple.yml'))
self.assertDictEqual(
{
'Repo': 'https://git.host/repo.git',
'RepoType': 'git',
'Subdir': None,
'Prepare': None},
srclib)
'Prepare': None,
},
srclib,
)
def test_parse_yaml_srclib_simple_with_blanks(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with open('simple.yml', 'w', encoding='utf-8') as f:
with Path('simple.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -779,17 +900,21 @@ class MetadataTest(unittest.TestCase):
'''
)
)
srclib = fdroidserver.metadata.parse_yaml_srclib('simple.yml')
self.assertDictEqual({'Repo': 'https://git.host/repo.git',
srclib = fdroidserver.metadata.parse_yaml_srclib(Path('simple.yml'))
self.assertDictEqual(
{
'Repo': 'https://git.host/repo.git',
'RepoType': 'git',
'Subdir': [''],
'Prepare': ''},
srclib)
'Prepare': '',
},
srclib,
)
def test_parse_yaml_srclib_Changelog_cketti(self):
fdroidserver.metadata.warnings_action = 'error'
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
with open('Changelog-cketti.yml', 'w', encoding='utf-8') as f:
with Path('Changelog-cketti.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -801,21 +926,27 @@ class MetadataTest(unittest.TestCase):
'''
)
)
srclib = fdroidserver.metadata.parse_yaml_srclib('Changelog-cketti.yml')
self.assertDictEqual(srclib,
{'Repo': 'https://github.com/cketti/ckChangeLog',
srclib = fdroidserver.metadata.parse_yaml_srclib(
Path('Changelog-cketti.yml')
)
self.assertDictEqual(
srclib,
{
'Repo': 'https://github.com/cketti/ckChangeLog',
'RepoType': 'git',
'Subdir': ['library', 'ckChangeLog/src/main'],
'Prepare': "[ -f project.properties ] || echo 'source.dir=java' > "
"ant.properties && echo -e "
"'android.library=true\\ntarget=android-19' > project.properties"})
"'android.library=true\\ntarget=android-19' > project.properties",
},
)
def test_read_srclibs_yml_subdir_list(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
os.mkdir('srclibs')
with open('srclibs/with-list.yml', 'w', encoding='utf-8') as f:
Path('srclibs').mkdir()
with Path('srclibs/with-list.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -839,25 +970,33 @@ class MetadataTest(unittest.TestCase):
)
fdroidserver.metadata.read_srclibs()
self.maxDiff = None
self.assertDictEqual(fdroidserver.metadata.srclibs,
{'with-list': {'RepoType': 'git',
self.assertDictEqual(
fdroidserver.metadata.srclibs,
{
'with-list': {
'RepoType': 'git',
'Repo': 'https://git.host/repo.git',
'Subdir': ['This is your last chance.',
'Subdir': [
'This is your last chance.',
'After this, there is no turning back.',
'You take the blue pill—the story ends,',
'you wake up in your bed',
'and believe whatever you want to believe.',
'You take the red pill—you stay in Wonderland',
'and I show you how deep the rabbit-hole goes.'],
'and I show you how deep the rabbit-hole goes.',
],
'Prepare': 'There is a difference between knowing the path '
'and walking the path.'}})
'and walking the path.',
}
},
)
def test_read_srclibs_yml_prepare_list(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
os.mkdir('srclibs')
with open('srclibs/with-list.yml', 'w', encoding='utf-8') as f:
Path('srclibs').mkdir()
with Path('srclibs/with-list.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -880,8 +1019,11 @@ class MetadataTest(unittest.TestCase):
)
fdroidserver.metadata.read_srclibs()
self.maxDiff = None
self.assertDictEqual(fdroidserver.metadata.srclibs,
{'with-list': {'RepoType': 'git',
self.assertDictEqual(
fdroidserver.metadata.srclibs,
{
'with-list': {
'RepoType': 'git',
'Repo': 'https://git.host/repo.git',
'Subdir': [''],
'Prepare': 'The Matrix is a system, Neo. && '
@ -891,14 +1033,17 @@ class MetadataTest(unittest.TestCase):
'The very minds of the people we are trying to save. && '
'But until we do, these people are still a part of that system and that makes them our enemy. && '
'You have to understand, most of these people are not ready to be unplugged. && '
'And many of them are so inert, so hopelessly dependent on the system that they will fight to protect it.'}})
'And many of them are so inert, so hopelessly dependent on the system that they will fight to protect it.',
}
},
)
def test_read_srclibs(self):
fdroidserver.metadata.warnings_action = 'error'
fdroidserver.metadata.srclibs = None
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
os.mkdir('srclibs')
with open('srclibs/simple.yml', 'w', encoding='utf-8') as f:
Path('srclibs').mkdir()
with Path('srclibs/simple.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -907,7 +1052,7 @@ class MetadataTest(unittest.TestCase):
'''
)
)
with open('srclibs/simple-wb.yml', 'w', encoding='utf-8') as f:
with Path('srclibs/simple-wb.yml').open('w', encoding='utf-8') as f:
f.write(
textwrap.dedent(
'''\
@ -921,20 +1066,26 @@ class MetadataTest(unittest.TestCase):
)
)
fdroidserver.metadata.read_srclibs()
self.assertDictEqual(fdroidserver.metadata.srclibs,
{'simple-wb': {'RepoType': 'git',
self.assertDictEqual(
fdroidserver.metadata.srclibs,
{
'simple-wb': {
'RepoType': 'git',
'Repo': 'https://git.host/repo.git',
'Subdir': [''],
'Prepare': ''},
'simple': {'RepoType': 'git',
'Prepare': '',
},
'simple': {
'RepoType': 'git',
'Repo': 'https://git.host/repo.git',
'Subdir': None,
'Prepare': None}})
'Prepare': None,
},
},
)
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
parser = optparse.OptionParser()
parser.add_option(
"-v",

View File

@ -1,6 +1,5 @@
#!/usr/bin/env python3
import inspect
import logging
import optparse
import os
@ -9,14 +8,15 @@ import unittest
import tempfile
import textwrap
from unittest import mock
from pathlib import Path
from testcommon import TmpCwd
localmodule = os.path.realpath(
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')
)
print('localmodule: ' + localmodule)
localmodule = Path(__file__).resolve().parent.parent
print('localmodule: ' + str(localmodule))
if localmodule not in sys.path:
sys.path.insert(0, localmodule)
sys.path.insert(0, str(localmodule))
from fdroidserver import common
from fdroidserver import rewritemeta
@ -28,28 +28,27 @@ class RewriteMetaTest(unittest.TestCase):
def setUp(self):
logging.basicConfig(level=logging.DEBUG)
self.basedir = os.path.join(localmodule, 'tests')
self.tmpdir = os.path.abspath(os.path.join(self.basedir, '..', '.testfiles'))
if not os.path.exists(self.tmpdir):
os.makedirs(self.tmpdir)
os.chdir(self.basedir)
self.basedir = localmodule / 'tests'
self.tmpdir = localmodule / '.testfiles'
self.tmpdir.mkdir(exist_ok=True)
# TODO: Python3.6: Accepts a path-like object.
os.chdir(str(self.basedir))
def test_rewrite_scenario_trivial(self):
sys.argv = ['rewritemeta', 'a', 'b']
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
os.mkdir('metadata')
with open('metadata/a.yml', 'w') as f:
Path('metadata').mkdir()
with Path('metadata/a.yml').open('w') as f:
f.write('AutoName: a')
with open('metadata/b.yml', 'w') as f:
with Path('metadata/b.yml').open('w') as f:
f.write('AutoName: b')
rewritemeta.main()
with open('metadata/a.yml') as f:
self.assertEqual(
f.read(),
Path('metadata/a.yml').read_text(),
textwrap.dedent(
'''\
License: Unknown
@ -62,9 +61,8 @@ class RewriteMetaTest(unittest.TestCase):
),
)
with open('metadata/b.yml') as f:
self.assertEqual(
f.read(),
Path('metadata/b.yml').read_text(),
textwrap.dedent(
'''\
License: Unknown
@ -80,8 +78,8 @@ class RewriteMetaTest(unittest.TestCase):
def test_rewrite_scenario_yml_no_ruamel(self):
sys.argv = ['rewritemeta', 'a']
with tempfile.TemporaryDirectory() as tmpdir, TmpCwd(tmpdir):
os.mkdir('metadata')
with open('metadata/a.yml', 'w') as f:
Path('metadata').mkdir()
with Path('metadata/a.yml').open('w') as f:
f.write('AutoName: a')
def boom(*args):
@ -91,19 +89,12 @@ class RewriteMetaTest(unittest.TestCase):
with self.assertRaises(FDroidException):
rewritemeta.main()
with open('metadata/a.yml') as f:
self.assertEqual(
f.read(),
textwrap.dedent(
'''\
AutoName: a'''
),
Path('metadata/a.yml').read_text(), 'AutoName: a'
)
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
parser = optparse.OptionParser()
parser.add_option(
"-v",