1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-09-17 10:40:12 +02:00

Merge branch 'metadata' into 'master'

metadata.py: use pathlib and support Windows

See merge request fdroid/fdroidserver!939
This commit is contained in:
Hans-Christoph Steiner 2021-06-08 15:02:54 +00:00
commit 8b17fbf703
8 changed files with 766 additions and 510 deletions

View File

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

View File

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

View File

@ -67,31 +67,134 @@ class BuildTest(unittest.TestCase):
pass # aapt is not required if androguard is present pass # aapt is not required if androguard is present
testcases = [ 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), 'repo/obb.main.twoversions_1101613.apk',
('org.bitbucket.tickytacky.mirrormirror_2.apk', 'org.bitbucket.tickytacky.mirrormirror', '2', '1.0.1', None), 'obb.main.twoversions',
('org.bitbucket.tickytacky.mirrormirror_3.apk', 'org.bitbucket.tickytacky.mirrormirror', '3', '1.0.2', None), '1101613',
('org.bitbucket.tickytacky.mirrormirror_4.apk', 'org.bitbucket.tickytacky.mirrormirror', '4', '1.0.3', None), '0.1',
('org.dyndns.fules.ck_20.apk', 'org.dyndns.fules.ck', '20', 'v1.6pre2', None,
['arm64-v8a', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'x86', 'x86_64']), ),
(
'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.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-badcert.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-badsig.apk', 'info.guardianproject.urzip', '100', '0.1', None),
('urzip-release.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_3.apk', 'com.politedroid', '3', '1.2', None),
('repo/com.politedroid_4.apk', 'com.politedroid', '4', '1.3', 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_5.apk', 'com.politedroid', '5', '1.4', None),
('repo/com.politedroid_6.apk', 'com.politedroid', '6', '1.5', 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/duplicate.permisssions_9999999.apk',
('repo/obb.main.oldversion_1444412523.apk', 'obb.main.oldversion', '1444412523', '0.1', None), 'duplicate.permisssions',
('repo/obb.mainpatch.current_1619_another-release-key.apk', 'obb.mainpatch.current', '1619', '0.1', None), '9999999',
('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), 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/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: for apkfilename, appid, versionCode, versionName, nativecode in testcases:
app = fdroidserver.metadata.App() app = fdroidserver.metadata.App()
@ -259,14 +362,26 @@ class BuildTest(unittest.TestCase):
with mock.patch('fdroidserver.common.replace_build_vars', wraps=make_fake_apk): 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_native_code', return_value='x86'):
with mock.patch('fdroidserver.common.get_apk_id', with mock.patch(
return_value=(app.id, build.versionCode, build.versionName)): 'fdroidserver.common.get_apk_id',
with mock.patch('fdroidserver.common.is_apk_and_debuggable', return_value=False): return_value=(app.id, build.versionCode, build.versionName),
):
with mock.patch(
'fdroidserver.common.is_apk_and_debuggable', return_value=False
):
fdroidserver.build.build_local( fdroidserver.build.build_local(
app, build, vcs, app,
build_dir=testdir, output_dir=testdir, build,
log_dir=None, srclib_dir=None, extlib_dir=None, tmp_dir=None, vcs,
force=False, onserver=False, refresh=False 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')) self.assertTrue(os.path.exists('foo.aar'))

View File

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

View File

@ -121,9 +121,6 @@ class ImportTest(unittest.TestCase):
if __name__ == "__main__": 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 = optparse.OptionParser()
parser.add_option( parser.add_option(
"-v", "-v",

File diff suppressed because it is too large Load Diff

View File

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