new config option: per-app repos to support nightly build repos

For devs that want to build and distribute nightly builds of their apps
using the fdroid tools.  The core idea here is to make the fdroidserver
tool suite the single set of tools for all types of builds and releases.
That will hopefully drive more free software developers to make
an core channel for official releases.
parent e614863c
......@@ -56,6 +56,12 @@ archive_description = """
The repository of older versions of applications from the main demo repository.
# Normally, all apps are collected into a single app repository, like on
# For certain situations, it is better to make a repo
# that is made up of APKs only from a single app. For example, an automated
# build server that publishes nightly builds.
# per_app_repos = True
# `fdroid update` will create a link to the current version of a given app.
# This provides a static path to the current APK. To disable the creation of
# this link, uncomment this:
......@@ -58,6 +58,7 @@ default_config = {
'mvn3': "mvn",
'gradle': 'gradle',
'sync_from_local_copy_dir': False,
'per_app_repos': False,
'make_current_version_link': True,
'current_version_name_source': 'Name',
'update_stats': False,
......@@ -2135,3 +2136,26 @@ def download_file(url, local_filename=None, dldir='tmp'):
return local_filename
def get_per_app_repos():
'''per-app repos are dirs named with the packageName of a single app'''
# Android packageNames are Java packages, they may contain uppercase or
# lowercase letters ('A' through 'Z'), numbers, and underscores
# ('_'). However, individual package name parts may only start with
# letters.
p = re.compile('^([a-zA-Z][a-zA-Z0-9_]*(\\.[a-zA-Z][a-zA-Z0-9_]*)*)?$')
repos = []
for root, dirs, files in os.walk(os.getcwd()):
for d in dirs:
print 'checking', root, 'for', d
if d in ('archive', 'metadata', 'repo', 'srclibs', 'tmp'):
# standard parts of an fdroid repo, so never packageNames
elif p.match(d) \
and os.path.exists(os.path.join(d, 'fdroid', 'repo', 'index.jar')):
return repos
......@@ -285,6 +285,8 @@ def main():
if not os.path.exists('archive'):
if config['per_app_repos']:
repo_sections += common.get_per_app_repos()
if args[0] == 'init':
ssh = paramiko.SSHClient()
......@@ -1016,6 +1016,28 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi
def add_apks_to_per_app_repos(repodir, apks):
apks_per_app = dict()
for apk in apks:
apk['per_app_dir'] = os.path.join(apk['id'], 'fdroid')
apk['per_app_repo'] = os.path.join(apk['per_app_dir'], 'repo')
apk['per_app_icons'] = os.path.join(apk['per_app_repo'], 'icons')
apks_per_app[apk['id']] = apk
if not os.path.exists(apk['per_app_icons']):'Adding new repo for only ' + apk['id'])
apkpath = os.path.join(repodir, apk['apkname'])
shutil.copy(apkpath, apk['per_app_repo'])
apksigpath = apkpath + '.sig'
if os.path.exists(apksigpath):
shutil.copy(apksigpath, apk['per_app_repo'])
apkascpath = apkpath + '.asc'
if os.path.exists(apkascpath):
shutil.copy(apkascpath, apk['per_app_repo'])
config = None
options = None
......@@ -1215,6 +1237,20 @@ def main():
# name comes from there!)
sortedids = sorted(apps.iterkeys(), key=lambda appid: apps[appid]['Name'].upper())
# APKs are placed into multiple repos based on the app package, providing
# per-app subscription feeds for nightly builds and things like it
if config['per_app_repos']:
add_apks_to_per_app_repos(repodirs[0], apks)
for appid, app in apps.iteritems():
repodir = os.path.join(appid, 'fdroid', 'repo')
appdict = dict()
appdict[appid] = app
if os.path.isdir(repodir):
make_index(appdict, [appid], apks, repodir, False, categories)
else:'Skipping index generation for ' + appid)
if len(repodirs) > 1:
archive_old_apks(apps, apks, archapks, repodirs[0], repodirs[1], config['archive_older'])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment