1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-10-06 11:00:13 +02:00

Merge branch 'more-1.0-polishing' into 'master'

More 1.0 polishing

Closes #402

See merge request fdroid/fdroidserver!362
This commit is contained in:
Hans-Christoph Steiner 2017-10-27 07:11:50 +00:00
commit e666cd9b35
16 changed files with 178 additions and 107 deletions

View File

@ -19,6 +19,9 @@ matrix:
env: ANDROID_SDK_ROOT=/usr/local/share/android-sdk
env: ANDROID_HOME=/usr/local/share/android-sdk
# On Ubuntu/trusty 14.04, the PPA is needed on to provide lots of the
# dependencies, but this then also serves as a test of the PPA, which
# is used on Windows Subsystem for Linux.
addons:
apt:
sources:
@ -46,15 +49,13 @@ android:
- 'android-sdk-preview-.+'
- 'android-sdk-license-.+'
# the PPA is needed on Ubuntu 14.04 precise, and with python3, trusty too
# the pip thing is a hack that can go away with trusty.
#
# * ensure java8 is installed since Android SDK doesn't work with Java9
# * Java needs to be at least 1.8.0_131 to have MD5 properly disabled
# https://blogs.oracle.com/java-platform-group/oracle-jre-will-no-longer-trust-md5-signed-code-by-default
# https://opsech.io/posts/2017/Jun/09/openjdk-april-2017-security-update-131-8u131-and-md5-signed-jars.html
install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
set -x;
brew update > /dev/null;
brew install dash bash python3 gradle jenv;
brew install gnu-sed --with-default-names;
@ -74,6 +75,8 @@ install:
sudo pip3 install --quiet --editable . ;
sudo rm -rf fdroidserver.egg-info;
ls -l /System/Library/Java/JavaVirtualMachines || true;
ls -l /Library/Java/JavaVirtualMachines || true;
echo $PATH;
echo $JAVA_HOME;
jenv versions;
@ -86,11 +89,19 @@ install:
which jarsigner;
keytool -help;
which keytool;
set +x;
fi
# The OSX tests seem to run slower, they often timeout. So only run
# the test suite with the installed version of fdroid, instead of the
# three rounds that ./complete-ci-tests does.
script:
- cd tests
- ./complete-ci-tests
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
./run-tests;
else
./complete-ci-tests;
fi
after_failure:
- cd $TRAVIS_BUILD_DIR

View File

@ -132,6 +132,41 @@ def setup_global_opts(parser):
help=_("Restrict output to warnings and errors"))
def _add_java_paths_to_config(pathlist, thisconfig):
def path_version_key(s):
versionlist = []
for u in re.split('[^0-9]+', s):
try:
versionlist.append(int(u))
except ValueError:
pass
return versionlist
for d in sorted(pathlist, key=path_version_key):
if os.path.islink(d):
continue
j = os.path.basename(d)
# the last one found will be the canonical one, so order appropriately
for regex in [
r'^1\.([6-9])\.0\.jdk$', # OSX
r'^jdk1\.([6-9])\.0_[0-9]+.jdk$', # OSX and Oracle tarball
r'^jdk1\.([6-9])\.0_[0-9]+$', # Oracle Windows
r'^jdk([6-9])-openjdk$', # Arch
r'^java-([6-9])-openjdk$', # Arch
r'^java-([6-9])-jdk$', # Arch (oracle)
r'^java-1\.([6-9])\.0-.*$', # RedHat
r'^java-([6-9])-oracle$', # Debian WebUpd8
r'^jdk-([6-9])-oracle-.*$', # Debian make-jpkg
r'^java-([6-9])-openjdk-[^c][^o][^m].*$', # Debian
]:
m = re.match(regex, j)
if not m:
continue
for p in [d, os.path.join(d, 'Contents', 'Home')]:
if os.path.exists(os.path.join(p, 'bin', 'javac')):
thisconfig['java_paths'][m.group(1)] = p
def fill_config_defaults(thisconfig):
for k, v in default_config.items():
if k not in thisconfig:
@ -167,29 +202,7 @@ def fill_config_defaults(thisconfig):
pathlist.append(os.getenv('JAVA_HOME'))
if os.getenv('PROGRAMFILES') is not None:
pathlist += glob.glob(os.path.join(os.getenv('PROGRAMFILES'), 'Java', 'jdk1.[6-9].*'))
for d in sorted(pathlist):
if os.path.islink(d):
continue
j = os.path.basename(d)
# the last one found will be the canonical one, so order appropriately
for regex in [
r'^1\.([6-9])\.0\.jdk$', # OSX
r'^jdk1\.([6-9])\.0_[0-9]+.jdk$', # OSX and Oracle tarball
r'^jdk1\.([6-9])\.0_[0-9]+$', # Oracle Windows
r'^jdk([6-9])-openjdk$', # Arch
r'^java-([6-9])-openjdk$', # Arch
r'^java-([6-9])-jdk$', # Arch (oracle)
r'^java-1\.([6-9])\.0-.*$', # RedHat
r'^java-([6-9])-oracle$', # Debian WebUpd8
r'^jdk-([6-9])-oracle-.*$', # Debian make-jpkg
r'^java-([6-9])-openjdk-[^c][^o][^m].*$', # Debian
]:
m = re.match(regex, j)
if not m:
continue
for p in [d, os.path.join(d, 'Contents', 'Home')]:
if os.path.exists(os.path.join(p, 'bin', 'javac')):
thisconfig['java_paths'][m.group(1)] = p
_add_java_paths_to_config(pathlist, thisconfig)
for java_version in ('7', '8', '9'):
if java_version not in thisconfig['java_paths']:
@ -506,7 +519,7 @@ def get_extension(filename):
def has_extension(filename, ext):
_, f_ext = get_extension(filename)
_ignored, f_ext = get_extension(filename)
return ext == f_ext
@ -1732,7 +1745,7 @@ class KnownApks:
default_date = datetime.utcnow()
self.apks[apkName] = (app, default_date)
self.changed = True
_, added = self.apks[apkName]
_ignored, added = self.apks[apkName]
return added
def getapp(self, apkname):
@ -2238,15 +2251,15 @@ def apk_strip_signatures(signed_apk, strip_manifest=False):
os.rename(signed_apk, tmp_apk)
with ZipFile(tmp_apk, 'r') as in_apk:
with ZipFile(signed_apk, 'w') as out_apk:
for f in in_apk.infolist():
if not apk_sigfile.match(f.filename):
for info in in_apk.infolist():
if not apk_sigfile.match(info.filename):
if strip_manifest:
if f.filename != 'META-INF/MANIFEST.MF':
buf = in_apk.read(f.filename)
out_apk.writestr(f.filename, buf)
if info.filename != 'META-INF/MANIFEST.MF':
buf = in_apk.read(info.filename)
out_apk.writestr(info, buf)
else:
buf = in_apk.read(f.filename)
out_apk.writestr(f.filename, buf)
buf = in_apk.read(info.filename)
out_apk.writestr(info, buf)
def apk_implant_signatures(apkpath, signaturefile, signedfile, manifest):
@ -2259,19 +2272,21 @@ def apk_implant_signatures(apkpath, signaturefile, signedfile, manifest):
"""
# get list of available signature files in metadata
with tempfile.TemporaryDirectory() as tmpdir:
# orig_apk = os.path.join(tmpdir, 'orig.apk')
# os.rename(apkpath, orig_apk)
apkwithnewsig = os.path.join(tmpdir, 'newsig.apk')
with ZipFile(apkpath, 'r') as in_apk:
with ZipFile(apkwithnewsig, 'w') as out_apk:
for sig_file in [signaturefile, signedfile, manifest]:
out_apk.write(sig_file, arcname='META-INF/' +
os.path.basename(sig_file))
for f in in_apk.infolist():
if not apk_sigfile.match(f.filename):
if f.filename != 'META-INF/MANIFEST.MF':
buf = in_apk.read(f.filename)
out_apk.writestr(f.filename, buf)
with open(sig_file, 'rb') as fp:
buf = fp.read()
info = zipfile.ZipInfo('META-INF/' + os.path.basename(sig_file))
info.compress_type = zipfile.ZIP_DEFLATED
info.create_system = 0 # "Windows" aka "FAT", what Android SDK uses
out_apk.writestr(info, buf)
for info in in_apk.infolist():
if not apk_sigfile.match(info.filename):
if info.filename != 'META-INF/MANIFEST.MF':
buf = in_apk.read(info.filename)
out_apk.writestr(info, buf)
os.remove(apkpath)
p = SdkToolsPopen(['zipalign', '-v', '4', apkwithnewsig, apkpath])
if p.returncode != 0:

View File

@ -380,8 +380,8 @@ class FieldValidator():
values = [v]
for v in values:
if not self.compiled.match(v):
warn_or_exception("'%s' is not a valid %s in %s. Regex pattern: %s"
% (v, self.name, appid, 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
@ -534,7 +534,7 @@ class DescriptionFormatter:
if txt.startswith("[["):
index = txt.find("]]")
if index == -1:
warn_or_exception("Unterminated ]]")
warn_or_exception(_("Unterminated ]]"))
url = txt[2:index]
if self.linkResolver:
url, urltext = self.linkResolver(url)
@ -546,7 +546,7 @@ class DescriptionFormatter:
else:
index = txt.find("]")
if index == -1:
warn_or_exception("Unterminated ]")
warn_or_exception(_("Unterminated ]"))
url = txt[1:index]
index2 = url.find(' ')
if index2 == -1:
@ -555,7 +555,7 @@ class DescriptionFormatter:
urltxt = url[index2 + 1:]
url = url[:index2]
if url == urltxt:
warn_or_exception("Url title is just the URL - use [url]")
warn_or_exception(_("URL title is just the URL, use brackets: [URL]"))
res_html += '<a href="' + url + '">' + html.escape(urltxt, quote=False) + '</a>'
res_plain += urltxt
if urltxt != url:
@ -664,7 +664,7 @@ def parse_srclib(metadatapath):
try:
f, v = line.split(':', 1)
except ValueError:
warn_or_exception("Invalid metadata in %s:%d" % (line, n))
warn_or_exception(_("Invalid metadata in %s:%d") % (line, n))
if f == "Subdir":
thisinfo[f] = v.split(',')
@ -734,7 +734,8 @@ def read_metadata(xref=True, check_vcs=[]):
+ glob.glob('.fdroid.yml')):
packageName, _ignored = fdroidserver.common.get_extension(os.path.basename(metadatapath))
if packageName in apps:
warn_or_exception("Found multiple metadata files for " + packageName)
warn_or_exception(_("Found multiple metadata files for {appid}")
.format(path=packageName))
app = parse_metadata(metadatapath, packageName in check_vcs)
check_metadata(app)
apps[app.id] = app
@ -745,14 +746,14 @@ def read_metadata(xref=True, check_vcs=[]):
def linkres(appid):
if appid in apps:
return ("fdroid.app:" + appid, "Dummy name - don't know yet")
warn_or_exception("Cannot resolve app id " + appid)
warn_or_exception(_("Cannot resolve app id {appid}").format(appid=appid))
for appid, app in apps.items():
try:
description_html(app.Description, linkres)
except MetaDataException as e:
warn_or_exception("Problem with description of " + appid +
" - " + str(e))
warn_or_exception(_("Problem with description of {appid}: {error}")
.format(appid=appid, error=str(e)))
return apps
@ -795,7 +796,8 @@ def get_default_app_info(metadatapath=None):
manifestroot = fdroidserver.common.parse_xml(os.path.join(root, 'AndroidManifest.xml'))
break
if manifestroot is None:
warn_or_exception("Cannot find a packageName for {0}!".format(metadatapath))
warn_or_exception(_("Cannot find a packageName for {path}!")
.format(path=metadatapath))
appid = manifestroot.attrib['package']
app = App()
@ -915,17 +917,17 @@ def _decode_bool(s):
return True
if bool_false.match(s):
return False
warn_or_exception("Invalid bool '%s'" % s)
warn_or_exception(_("Invalid boolean '%s'") % s)
def parse_metadata(metadatapath, check_vcs=False):
'''parse metadata file, optionally checking the git repo for metadata first'''
_, ext = fdroidserver.common.get_extension(metadatapath)
_ignored, ext = fdroidserver.common.get_extension(metadatapath)
accepted = fdroidserver.common.config['accepted_formats']
if ext not in accepted:
warn_or_exception('"%s" is not an accepted format, convert to: %s' % (
metadatapath, ', '.join(accepted)))
warn_or_exception(_('"{path}" is not an accepted format, convert to: {formats}')
.format(path=metadatapath, formats=', '.join(accepted)))
app = App()
app.metadatapath = metadatapath
@ -943,7 +945,8 @@ def parse_metadata(metadatapath, check_vcs=False):
elif ext == 'yml':
parse_yaml_metadata(mf, app)
else:
warn_or_exception('Unknown metadata format: %s' % metadatapath)
warn_or_exception(_('Unknown metadata format: {path}')
.format(path=metadatapath))
if check_vcs and app.Repo:
build_dir = fdroidserver.common.get_build_dir(app)
@ -970,7 +973,7 @@ def parse_metadata(metadatapath, check_vcs=False):
else:
root_dir = '.'
paths = fdroidserver.common.manifest_paths(root_dir, build.gradle)
_, _, app.id = fdroidserver.common.parse_androidmanifests(paths, app)
_ignored, _ignored, app.id = fdroidserver.common.parse_androidmanifests(paths, app)
return app
@ -1162,12 +1165,12 @@ def parse_txt_metadata(mf, app):
def add_buildflag(p, build):
if not p.strip():
warn_or_exception("Empty build flag at {1}"
.format(buildlines[0], linedesc))
warn_or_exception(_("Empty build flag at {linedesc}")
.format(linedesc=linedesc))
bv = p.split('=', 1)
if len(bv) != 2:
warn_or_exception("Invalid build flag at {0} in {1}"
.format(buildlines[0], linedesc))
warn_or_exception(_("Invalid build flag at {line} in {linedesc}")
.format(line=buildlines[0], linedesc=linedesc))
pk, pv = bv
pk = pk.lstrip()
@ -1186,7 +1189,8 @@ def parse_txt_metadata(mf, app):
v = "".join(lines)
parts = [p.replace("\\,", ",") for p in re.split(build_line_sep, v)]
if len(parts) < 3:
warn_or_exception("Invalid build format: " + v + " in " + mf.name)
warn_or_exception(_("Invalid build format: {value} in {name}")
.format(value=v, name=mf.name))
build = Build()
build.versionName = parts[0]
build.versionCode = parts[1]
@ -1214,7 +1218,8 @@ def parse_txt_metadata(mf, app):
try:
int(versionCode)
except ValueError:
warn_or_exception('Invalid versionCode: "' + versionCode + '" is not an integer!')
warn_or_exception(_('Invalid versionCode: "{versionCode}" is not an integer!')
.format(versionCode=versionCode))
def add_comments(key):
if not curcomments:
@ -1247,8 +1252,8 @@ def parse_txt_metadata(mf, app):
del buildlines[:]
else:
if not build.commit and not build.disable:
warn_or_exception("No commit specified for {0} in {1}"
.format(build.versionName, linedesc))
warn_or_exception(_("No commit specified for {versionName} in {linedesc}")
.format(versionName=build.versionName, linedesc=linedesc))
app.builds.append(build)
add_comments('build:' + build.versionCode)
@ -1263,10 +1268,10 @@ def parse_txt_metadata(mf, app):
try:
f, v = line.split(':', 1)
except ValueError:
warn_or_exception("Invalid metadata in " + linedesc)
warn_or_exception(_("Invalid metadata in: ") + linedesc)
if f not in app_fields:
warn_or_exception('Unrecognised app field: ' + f)
warn_or_exception(_('Unrecognised app field: ') + f)
# Translate obsolete fields...
if f == 'Market Version':
@ -1282,8 +1287,8 @@ def parse_txt_metadata(mf, app):
if ftype == TYPE_MULTILINE:
mode = 1
if v:
warn_or_exception("Unexpected text on same line as "
+ f + " in " + linedesc)
warn_or_exception(_("Unexpected text on same line as {field} in {linedesc}")
.format(field=f, linedesc=linedesc))
elif ftype == TYPE_STRING:
app[f] = v
elif ftype == TYPE_LIST:
@ -1300,24 +1305,26 @@ def parse_txt_metadata(mf, app):
elif ftype == TYPE_BUILD_V2:
vv = v.split(',')
if len(vv) != 2:
warn_or_exception('Build should have comma-separated',
'versionName and versionCode,',
'not "{0}", in {1}'.format(v, linedesc))
warn_or_exception(_('Build should have comma-separated '
'versionName and versionCode, '
'not "{value}", in {linedesc}')
.format(value=v, linedesc=linedesc))
build = Build()
build.versionName = vv[0]
build.versionCode = vv[1]
check_versionCode(build.versionCode)
if build.versionCode in vc_seen:
warn_or_exception('Duplicate build recipe found for versionCode %s in %s'
% (build.versionCode, linedesc))
warn_or_exception(_('Duplicate build recipe found for versionCode {versionCode} in {linedesc}')
.format(versionCode=build.versionCode, linedesc=linedesc))
vc_seen.add(build.versionCode)
del buildlines[:]
mode = 3
elif ftype == TYPE_OBSOLETE:
pass # Just throw it away!
else:
warn_or_exception("Unrecognised field '" + f + "' in " + linedesc)
warn_or_exception(_("Unrecognised field '{field}' in {linedesc}")
.format(field=f, linedesc=linedesc))
elif mode == 1: # Multiline field
if line == '.':
mode = 0
@ -1338,11 +1345,14 @@ def parse_txt_metadata(mf, app):
# Mode at end of file should always be 0
if mode == 1:
warn_or_exception(f + " not terminated in " + mf.name)
warn_or_exception(_("{field} not terminated in {name}")
.format(field=f, name=mf.name))
if mode == 2:
warn_or_exception("Unterminated continuation in " + mf.name)
warn_or_exception(_("Unterminated continuation in {name}")
.format(name=mf.name))
if mode == 3:
warn_or_exception("Unterminated build in " + mf.name)
warn_or_exception(_("Unterminated build in {name}")
.format(name=mf.name))
return app
@ -1498,11 +1508,11 @@ def write_txt(mf, app):
def write_metadata(metadatapath, app):
_, ext = fdroidserver.common.get_extension(metadatapath)
_ignored, ext = fdroidserver.common.get_extension(metadatapath)
accepted = fdroidserver.common.config['accepted_formats']
if ext not in accepted:
warn_or_exception('Cannot write "%s", not an accepted format, use: %s'
% (metadatapath, ', '.join(accepted)))
warn_or_exception(_('Cannot write "{path}", not an accepted format, use: {formats}')
.format(path=metadatapath, formats=', '.join(accepted)))
try:
with open(metadatapath, 'w', encoding='utf8') as mf:
@ -1514,7 +1524,7 @@ def write_metadata(metadatapath, app):
os.remove(metadatapath)
raise e
warn_or_exception('Unknown metadata format: %s' % metadatapath)
warn_or_exception(_('Unknown metadata format: %s') % metadatapath)
def add_metadata_arguments(parser):

View File

@ -185,7 +185,7 @@ def scan_source(build_dir, build):
continue
path_in_build_dir = os.path.relpath(filepath, build_dir)
_, ext = common.get_extension(path_in_build_dir)
_ignored, ext = common.get_extension(path_in_build_dir)
if ext == 'so':
count += handleproblem('shared library', path_in_build_dir, filepath)

View File

@ -824,7 +824,7 @@ def insert_localized_app_metadata(apps):
locale = segments[-2]
destdir = os.path.join('repo', packageName, locale)
for f in glob.glob(os.path.join(root, d, '*.*')):
_, extension = common.get_extension(f)
_ignored, extension = common.get_extension(f)
if extension in ALLOWED_EXTENSIONS:
screenshotdestdir = os.path.join(destdir, d)
os.makedirs(screenshotdestdir, mode=0o755, exist_ok=True)
@ -846,24 +846,24 @@ def insert_localized_app_metadata(apps):
base, extension = common.get_extension(filename)
if packageName not in apps:
logging.warning('Found "%s" graphic without metadata for app "%s"!'
% (filename, packageName))
logging.warning(_('Found "{path}" graphic without metadata for app "{name}"!')
.format(path=filename, name=packageName))
continue
graphics = _get_localized_dict(apps[packageName], locale)
if extension not in ALLOWED_EXTENSIONS:
logging.warning('Only PNG and JPEG are supported for graphics, found: ' + f)
logging.warning(_('Only PNG and JPEG are supported for graphics, found: {path}').format(path=f))
elif base in GRAPHIC_NAMES:
# there can only be zero or one of these per locale
graphics[base] = filename
elif screenshotdir in SCREENSHOT_DIRS:
# there can any number of these per locale
logging.debug('adding to ' + screenshotdir + ': ' + f)
logging.debug(_('adding to {name}: {path}').format(name=screenshotdir, path=f))
if screenshotdir not in graphics:
graphics[screenshotdir] = []
graphics[screenshotdir].append(filename)
else:
logging.warning('Unsupported graphics file found: ' + f)
logging.warning(_('Unsupported graphics file found: {path}').format(path=f))
def scan_repo_files(apkcache, repodir, knownapks, use_date_from_file=False):
@ -1625,7 +1625,7 @@ def move_apk_between_sections(from_dir, to_dir, apk):
for density in all_screen_densities:
from_icon_dir = get_icon_dir(from_dir, density)
to_icon_dir = get_icon_dir(to_dir, density)
if density not in apk['icons']:
if density not in apk.get('icons', []):
continue
_move_file(from_icon_dir, to_icon_dir, apk['icons'][density], True)
if 'srcname' in apk:

View File

@ -74,4 +74,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(BuildTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -92,6 +92,41 @@ class CommonTest(unittest.TestCase):
else:
print('no build-tools found: ' + build_tools)
def test_find_java_root_path(self):
tmptestsdir = tempfile.mkdtemp(prefix='test_find_java_root_path', dir=self.tmpdir)
os.chdir(tmptestsdir)
all_pathlists = [
([ # Debian
'/usr/lib/jvm/java-1.5.0-gcj-5-amd64',
'/usr/lib/jvm/java-8-openjdk-amd64',
'/usr/lib/jvm/java-1.8.0-openjdk-amd64',
], '/usr/lib/jvm/java-8-openjdk-amd64'),
([ # OSX
'/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk',
'/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk',
'/System/Library/Java/JavaVirtualMachines/jdk1.7.0_45.jdk',
], '/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk'),
]
for pathlist, choice in all_pathlists:
# strip leading / to make relative paths to test without root
pathlist = [p[1:] for p in pathlist]
# create test file used in common._add_java_paths_to_config()
for p in pathlist:
if p.startswith('/System') or p.startswith('/Library'):
basedir = os.path.join(p, 'Contents', 'Home', 'bin')
else:
basedir = os.path.join(p, 'bin')
os.makedirs(basedir)
open(os.path.join(basedir, 'javac'), 'w').close()
config = dict()
config['java_paths'] = dict()
fdroidserver.common._add_java_paths_to_config(pathlist, config)
self.assertEqual(config['java_paths']['8'], choice[1:])
def testIsApkDebuggable(self):
config = dict()
fdroidserver.common.fill_config_defaults(config)
@ -177,7 +212,7 @@ class CommonTest(unittest.TestCase):
def test_prepare_sources_refresh(self):
packageName = 'org.fdroid.ci.test.app'
testdir = tempfile.mkdtemp(prefix='test_verify_apks', dir=self.tmpdir)
testdir = tempfile.mkdtemp(prefix='test_prepare_sources_refresh', dir=self.tmpdir)
print('testdir', testdir)
os.chdir(testdir)
os.mkdir('build')
@ -462,4 +497,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(CommonTest))
unittest.main()
unittest.main(failfast=True)

View File

@ -62,4 +62,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(ExceptionTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -54,4 +54,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(ImportTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -236,4 +236,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(IndexTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -43,4 +43,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(InstallTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -53,4 +53,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(LintTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -129,4 +129,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(MetadataTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -144,4 +144,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(PublishTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -62,4 +62,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(SignaturesTest))
unittest.main()
unittest.main(failfast=False)

View File

@ -576,4 +576,4 @@ if __name__ == "__main__":
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(UpdateTest))
unittest.main()
unittest.main(failfast=False)