update: keep CVC of an app out of the archive

We want to keep the stable version (CV) of an app in /repo with highest
priority and only move it to /archive when ArchivePolicy is set to 0.

For this to work we need two changes here:

1) when sorting apks by version code we insert the apk corresponding to
the CVC of the app afterwards with highest priority. So when walking the
list of apks afterwards the CVC apk is always kept first.

2) Instead of the two pass algorithm of moving things back and forth to
the archive we instead figure out where each apk of an app goes in first
before actually moving them into the right place.

Fixes: fdroid/fdroidserver#385
This commit is contained in:
Marcus Hoffmann 2019-12-23 16:32:14 +01:00
parent 7f6efa74f5
commit a7a83e1ee3

View file

@ -1823,12 +1823,20 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi
def filter_apk_list_sorted(apk_list): def filter_apk_list_sorted(apk_list):
res = [] res = []
currentVersionApk = None
for apk in apk_list: for apk in apk_list:
if apk['packageName'] == appid: if apk['packageName'] == appid:
if apk['versionCode'] == common.version_code_string_to_int(app.CurrentVersionCode):
currentVersionApk = apk
continue
res.append(apk) res.append(apk)
# Sort the apk list by version code. First is highest/newest. # Sort the apk list by version code. First is highest/newest.
return sorted(res, key=lambda apk: apk['versionCode'], reverse=True) sorted_list = sorted(res, key=lambda apk: apk['versionCode'], reverse=True)
if currentVersionApk:
# Insert apk which corresponds to currentVersion at the front
sorted_list.insert(0, currentVersionApk)
return sorted_list
for appid, app in apps.items(): for appid, app in apps.items():
@ -1840,26 +1848,28 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi
logging.debug(_("Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}") logging.debug(_("Checking archiving for {appid} - apks:{integer}, keepversions:{keep}, archapks:{arch}")
.format(appid=appid, integer=len(apks), keep=keepversions, arch=len(archapks))) .format(appid=appid, integer=len(apks), keep=keepversions, arch=len(archapks)))
current_app_apks = filter_apk_list_sorted(apks) all_app_apks = filter_apk_list_sorted(apks + archapks)
if len(current_app_apks) > keepversions:
# Move back the ones we don't want.
for apk in current_app_apks[keepversions:]:
move_apk_between_sections(repodir, archivedir, apk)
archapks.append(apk)
apks.remove(apk)
current_app_archapks = filter_apk_list_sorted(archapks) # determine which apks to keep in repo
if len(current_app_apks) < keepversions and len(current_app_archapks) > 0: keep = []
kept = 0 for apk in all_app_apks:
# Move forward the ones we want again, except DisableAlgorithm if len(keep) == keepversions:
for apk in current_app_archapks: break
if 'DisabledAlgorithm' not in apk['antiFeatures']: if 'antiFeatures' not in apk:
move_apk_between_sections(archivedir, repodir, apk) keep.append(apk)
elif 'DisabledAlgorithm' not in apk['antiFeatures']:
keep.append(apk)
# actually move apks to the target section
for apk in all_app_apks:
if apk in apks and apk not in keep:
apks.remove(apk)
archapks.append(apk)
move_apk_between_sections(repodir, archivedir, apk)
elif apk in archapks and apk in keep:
archapks.remove(apk) archapks.remove(apk)
apks.append(apk) apks.append(apk)
kept += 1 move_apk_between_sections(archivedir, repodir, apk)
if kept == keepversions:
break
def move_apk_between_sections(from_dir, to_dir, apk): def move_apk_between_sections(from_dir, to_dir, apk):