1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-11-19 21:30:10 +01:00

Merge branch 'repomaker-api-fixes' into 'master'

repomaker/issuebot API fixes

See merge request fdroid/fdroidserver!807
This commit is contained in:
Hans-Christoph Steiner 2020-10-08 06:06:20 +00:00
commit 2952e74b71
4 changed files with 110 additions and 61 deletions

View File

@ -61,7 +61,7 @@ def make(apps, apks, repodir, archive):
common.assert_config_keystore(common.config)
# Historically the index has been sorted by App Name, so we enforce this ordering here
sortedids = sorted(apps, key=lambda appid: apps[appid].Name.upper())
sortedids = sorted(apps, key=lambda appid: apps[appid]['Name'].upper())
sortedapps = collections.OrderedDict()
for appid in sortedids:
sortedapps[appid] = apps[appid]
@ -593,8 +593,21 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing
# Copy the repo icon into the repo directory...
icon_dir = os.path.join(repodir, 'icons')
iconfilename = os.path.join(icon_dir, os.path.basename(common.config['repo_icon']))
repo_icon = common.config.get('repo_icon', common.default_config['repo_icon'])
iconfilename = os.path.join(icon_dir, os.path.basename(repo_icon))
if os.path.exists(repo_icon):
shutil.copyfile(common.config['repo_icon'], iconfilename)
else:
logging.warning(_('repo_icon %s does not exist, generating placeholder.')
% repo_icon)
os.makedirs(os.path.dirname(iconfilename), exist_ok=True)
try:
import qrcode
qrcode.make(common.config['repo_url']).save(iconfilename)
except Exception:
exampleicon = os.path.join(common.get_examples_dir(),
common.default_config['repo_icon'])
shutil.copy(exampleicon, iconfilename)
def extract_pubkey():

View File

@ -40,26 +40,7 @@ json_per_build = DEFAULT_JSON_PER_BUILD
MAVEN_URL_REGEX = re.compile(r"""\smaven\s*{.*?(?:setUrl|url)\s*=?\s*(?:uri)?\(?\s*["']?([^\s"']+)["']?[^}]*}""",
re.DOTALL)
def get_gradle_compile_commands(build):
compileCommands = ['compile',
'provided',
'apk',
'implementation',
'api',
'compileOnly',
'runtimeOnly']
buildTypes = ['', 'release']
flavors = ['']
if build.gradle and build.gradle != ['yes']:
flavors += build.gradle
commands = [''.join(c) for c in itertools.product(flavors, buildTypes, compileCommands)]
return [re.compile(r'\s*' + c, re.IGNORECASE) for c in commands]
def scan_binary(apkfile):
usual_suspects = {
CODE_SIGNATURES = {
# The `apkanalyzer dex packages` output looks like this:
# M d 1 1 93 <packagename> <other stuff>
# The first column has P/C/M/F for package, class, method or field
@ -74,29 +55,9 @@ def scan_binary(apkfile):
r'(com\.android\.billing[^\s]*)',
]
}
logging.info("Scanning APK for known non-free classes.")
result = common.SdkToolsPopen(["apkanalyzer", "dex", "packages", "--defined-only", apkfile], output=False)
problems = 0
for suspect, regexp in usual_suspects.items():
matches = regexp.findall(result.output)
if matches:
for m in set(matches):
logging.debug("Found class '%s'" % m)
problems += 1
if problems:
logging.critical("Found problems in %s" % apkfile)
return problems
def scan_source(build_dir, build=metadata.Build()):
"""Scan the source code in the given directory (and all subdirectories)
and return the number of fatal problems encountered
"""
count = 0
# Common known non-free blobs (always lower case):
usual_suspects = {
NON_FREE_GRADLE_LINES = {
exp: re.compile(r'.*' + exp, re.IGNORECASE) for exp in [
r'flurryagent',
r'paypal.*mpl',
@ -120,6 +81,46 @@ def scan_source(build_dir, build=metadata.Build()):
]
}
def get_gradle_compile_commands(build):
compileCommands = ['compile',
'provided',
'apk',
'implementation',
'api',
'compileOnly',
'runtimeOnly']
buildTypes = ['', 'release']
flavors = ['']
if build.gradle and build.gradle != ['yes']:
flavors += build.gradle
commands = [''.join(c) for c in itertools.product(flavors, buildTypes, compileCommands)]
return [re.compile(r'\s*' + c, re.IGNORECASE) for c in commands]
def scan_binary(apkfile):
logging.info("Scanning APK for known non-free classes.")
result = common.SdkToolsPopen(["apkanalyzer", "dex", "packages", "--defined-only", apkfile], output=False)
problems = 0
for suspect, regexp in CODE_SIGNATURES.items():
matches = regexp.findall(result.output)
if matches:
for m in set(matches):
logging.debug("Found class '%s'" % m)
problems += 1
if problems:
logging.critical("Found problems in %s" % apkfile)
return problems
def scan_source(build_dir, build=metadata.Build()):
"""Scan the source code in the given directory (and all subdirectories)
and return the number of fatal problems encountered
"""
count = 0
whitelisted = [
'firebase-jobdispatcher', # https://github.com/firebase/firebase-jobdispatcher-android/blob/master/LICENSE
'com.firebaseui', # https://github.com/firebase/FirebaseUI-Android/blob/master/LICENSE
@ -130,7 +131,7 @@ def scan_source(build_dir, build=metadata.Build()):
return any(wl in s for wl in whitelisted)
def suspects_found(s):
for n, r in usual_suspects.items():
for n, r in NON_FREE_GRADLE_LINES.items():
if r.match(s) and not is_whitelisted(s):
yield n

View File

@ -123,7 +123,9 @@ def get_all_icon_dirs(repodir):
def disabled_algorithms_allowed():
return options.allow_disabled_algorithms or config['allow_disabled_algorithms']
return ((options is not None and options.allow_disabled_algorithms)
or (config is not None and config['allow_disabled_algorithms'])
or common.default_config['allow_disabled_algorithms'])
def status_update_json(apps, apks):
@ -147,7 +149,7 @@ def status_update_json(apps, apks):
antiFeatures = output['antiFeatures'] # JSON camelCase
if af not in antiFeatures:
antiFeatures[af] = dict()
if appid not in antiFeatures[af]:
if 'apps' not in antiFeatures[af]:
antiFeatures[af]['apps'] = set()
antiFeatures[af]['apps'].add(appid)
@ -521,7 +523,7 @@ def get_cache():
"""
apkcachefile = get_cache_file()
ada = disabled_algorithms_allowed()
if not options.clean and os.path.exists(apkcachefile):
if options is not None and not options.clean and os.path.exists(apkcachefile):
with open(apkcachefile) as fp:
apkcache = json.load(fp, object_pairs_hook=collections.OrderedDict)
if apkcache.get("METADATA_VERSION") != METADATA_VERSION \
@ -1778,7 +1780,7 @@ def process_apks(apkcache, repodir, knownapks, use_date_from_apk=False):
for icon_dir in get_all_icon_dirs(repodir):
if os.path.exists(icon_dir):
if options.clean:
if options is not None and options.clean:
shutil.rmtree(icon_dir)
os.makedirs(icon_dir)
else:
@ -1971,26 +1973,26 @@ def apply_info_from_latest_apk(apps, apks):
bestver = apk['versionCode']
bestapk = apk
if app.NoSourceSince:
if app['NoSourceSince']:
apk['antiFeatures'].add('NoSourceSince')
if not app.added:
if not app['added']:
logging.debug("Don't know when " + appid + " was added")
if not app.lastUpdated:
if not app['lastUpdated']:
logging.debug("Don't know when " + appid + " was last updated")
if bestver == UNSET_VERSION_CODE:
if app.Name is None:
app.Name = app.AutoName or appid
app.icon = None
if app['Name'] is None:
app['Name'] = app['AutoName'] or appid
app['icon'] = None
logging.debug("Application " + appid + " has no packages")
else:
if app.Name is None:
app.Name = bestapk['name']
app.icon = bestapk['icon'] if 'icon' in bestapk else None
if app.CurrentVersionCode is None:
app.CurrentVersionCode = str(bestver)
if app['Name'] is None:
app['Name'] = bestapk['name']
app['icon'] = bestapk['icon'] if 'icon' in bestapk else None
if app['CurrentVersionCode'] is None:
app['CurrentVersionCode'] = str(bestver)
def make_categories_txt(repodir, categories):

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3
import datetime
import inspect
import logging
import optparse
@ -29,17 +30,25 @@ from testcommon import TmpCwd
GP_FINGERPRINT = 'B7C2EEFD8DAC7806AF67DFCD92EB18126BC08312A7F2D6F3862E46013C7A6135'
class Options:
nosign = True
pretty = False
verbose = False
class IndexTest(unittest.TestCase):
def setUp(self):
logging.basicConfig(level=logging.DEBUG)
self.basedir = os.path.join(localmodule, 'tests')
os.chmod(os.path.join(self.basedir, 'config.py'), 0o600)
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)
fdroidserver.common.config = None
fdroidserver.common.options = Options
config = fdroidserver.common.read_config(fdroidserver.common.options)
config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner')
fdroidserver.common.config = config
@ -215,6 +224,29 @@ class IndexTest(unittest.TestCase):
self.maxDiff = None
self.assertEqual(json.dumps(i, indent=2), json.dumps(o, indent=2))
def test_make_v0(self):
tmptestsdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name,
dir=self.tmpdir)
os.chdir(tmptestsdir)
os.mkdir('repo')
repo_icons_dir = os.path.join('repo', 'icons')
self.assertFalse(os.path.isdir(repo_icons_dir))
repodict = {
'address': 'https://example.com/fdroid/repo',
'description': 'This is just a test',
'icon': 'blahblah',
'name': 'test',
'timestamp': datetime.datetime.now(),
'version': 12,
}
requestsdict = {'install': [], 'uninstall': []}
fdroidserver.common.config['repo_pubkey'] = 'ffffffffffffffffffffffffffffffffff'
fdroidserver.index.make_v0({}, [], 'repo', repodict, requestsdict, [])
self.assertTrue(os.path.isdir(repo_icons_dir))
self.assertTrue(os.path.exists(os.path.join(repo_icons_dir,
fdroidserver.common.default_config['repo_icon'])))
self.assertTrue(os.path.exists(os.path.join('repo', 'index.xml')))
if __name__ == "__main__":
os.chdir(os.path.dirname(__file__))
@ -222,7 +254,8 @@ if __name__ == "__main__":
parser = optparse.OptionParser()
parser.add_option("-v", "--verbose", action="store_true", default=False,
help="Spew out even more information than normal")
(fdroidserver.common.options, args) = parser.parse_args(['--verbose'])
(options, args) = parser.parse_args()
Options.verbose = options.verbose
newSuite = unittest.TestSuite()
newSuite.addTest(unittest.makeSuite(IndexTest))