mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-03 17:50:11 +02:00
Merge branch 'multi' into 'master'
Support autoupdate multi build blocks See merge request fdroid/fdroidserver!1169
This commit is contained in:
commit
6071ae8f38
@ -379,7 +379,6 @@ def _getcvname(app):
|
||||
|
||||
|
||||
def fetch_autoname(app, tag):
|
||||
|
||||
if not app.RepoType or app.UpdateCheckMode in ('None', 'Static') \
|
||||
or app.UpdateCheckName == "Ignore":
|
||||
return None
|
||||
@ -417,14 +416,23 @@ def fetch_autoname(app, tag):
|
||||
return commitmsg
|
||||
|
||||
|
||||
def checkupdates_app(app):
|
||||
def operate_vercode(operation, vercode):
|
||||
if not common.VERCODE_OPERATION_RE.match(operation):
|
||||
raise MetaDataException(_('Invalid VercodeOperation: {field}')
|
||||
.format(field=operation))
|
||||
oldvercode = vercode
|
||||
op = operation.replace("%c", str(oldvercode))
|
||||
vercode = common.calculate_math_string(op)
|
||||
logging.debug("Applied vercode operation: %d -> %d" % (oldvercode, vercode))
|
||||
return vercode
|
||||
|
||||
|
||||
def checkupdates_app(app):
|
||||
# If a change is made, commitmsg should be set to a description of it.
|
||||
# Only if this is set will changes be written back to the metadata.
|
||||
commitmsg = None
|
||||
|
||||
tag = None
|
||||
vercode = None
|
||||
mode = app.UpdateCheckMode
|
||||
if mode.startswith('Tags'):
|
||||
pattern = mode[5:] if len(mode) > 4 else None
|
||||
@ -444,30 +452,33 @@ def checkupdates_app(app):
|
||||
else:
|
||||
raise MetaDataException(_('Invalid UpdateCheckMode: {mode}').format(mode=mode))
|
||||
|
||||
if version and vercode and app.VercodeOperation:
|
||||
if not common.VERCODE_OPERATION_RE.match(app.VercodeOperation):
|
||||
raise MetaDataException(_('Invalid VercodeOperation: {field}')
|
||||
.format(field=app.VercodeOperation))
|
||||
oldvercode = str(int(vercode))
|
||||
op = app.VercodeOperation.replace("%c", oldvercode)
|
||||
vercode = str(common.calculate_math_string(op))
|
||||
logging.debug("Applied vercode operation: %s -> %s" % (oldvercode, vercode))
|
||||
if not version or not vercode:
|
||||
raise FDroidException(_('no version information found'))
|
||||
|
||||
if app.VercodeOperation:
|
||||
if isinstance(app.VercodeOperation, str):
|
||||
vercodes = [operate_vercode(app.VercodeOperation, vercode)]
|
||||
else:
|
||||
vercodes = sorted([
|
||||
operate_vercode(operation, vercode)
|
||||
for operation in app.VercodeOperation
|
||||
])
|
||||
else:
|
||||
vercodes = [vercode]
|
||||
|
||||
updating = False
|
||||
if version is None:
|
||||
raise FDroidException(_('no version information found'))
|
||||
elif vercode == app.CurrentVersionCode:
|
||||
if vercodes[-1] == app.CurrentVersionCode:
|
||||
logging.debug("...up to date")
|
||||
elif vercode > app.CurrentVersionCode:
|
||||
elif vercodes[-1] > app.CurrentVersionCode:
|
||||
logging.debug("...updating - old vercode={0}, new vercode={1}".format(
|
||||
app.CurrentVersionCode, vercode))
|
||||
app.CurrentVersionCode, vercodes[-1]))
|
||||
app.CurrentVersion = version
|
||||
app.CurrentVersionCode = vercode
|
||||
app.CurrentVersionCode = vercodes[-1]
|
||||
updating = True
|
||||
else:
|
||||
raise FDroidException(
|
||||
_('current version is newer: old vercode={old}, new vercode={new}').format(
|
||||
old=app.CurrentVersionCode, new=vercode
|
||||
old=app.CurrentVersionCode, new=vercodes[-1]
|
||||
)
|
||||
)
|
||||
|
||||
@ -498,35 +509,38 @@ def checkupdates_app(app):
|
||||
|
||||
gotcur = False
|
||||
latest = None
|
||||
for build in app.get('Builds', []):
|
||||
if build.versionCode >= app.CurrentVersionCode:
|
||||
gotcur = True
|
||||
if not latest or build.versionCode > latest.versionCode:
|
||||
latest = build
|
||||
builds = app.get('Builds', [])
|
||||
|
||||
if latest.versionCode > app.CurrentVersionCode:
|
||||
raise FDroidException(
|
||||
_(
|
||||
'latest build recipe is newer: old vercode={old}, new vercode={new}'
|
||||
).format(old=latest.versionCode, new=app.CurrentVersionCode)
|
||||
)
|
||||
if builds:
|
||||
latest = builds[-1]
|
||||
if latest.versionCode == app.CurrentVersionCode:
|
||||
gotcur = True
|
||||
elif latest.versionCode > app.CurrentVersionCode:
|
||||
raise FDroidException(
|
||||
_(
|
||||
'latest build recipe is newer: '
|
||||
'old vercode={old}, new vercode={new}'
|
||||
).format(old=latest.versionCode, new=app.CurrentVersionCode)
|
||||
)
|
||||
|
||||
if not gotcur:
|
||||
newbuild = copy.deepcopy(latest)
|
||||
newbuild.disable = False
|
||||
newbuild.versionCode = app.CurrentVersionCode
|
||||
newbuild.versionName = app.CurrentVersion + suffix.replace(
|
||||
'%c', str(newbuild.versionCode)
|
||||
)
|
||||
logging.info("...auto-generating build for " + newbuild.versionName)
|
||||
if tag:
|
||||
newbuild.commit = tag
|
||||
else:
|
||||
commit = pattern.replace('%v', str(app.CurrentVersion))
|
||||
commit = commit.replace('%c', str(newbuild.versionCode))
|
||||
newbuild.commit = commit
|
||||
newbuilds = copy.deepcopy(builds[-len(vercodes):])
|
||||
for b, v in zip(newbuilds, vercodes):
|
||||
b.disable = False
|
||||
b.versionCode = v
|
||||
b.versionName = app.CurrentVersion + suffix.replace(
|
||||
'%c', str(v)
|
||||
)
|
||||
logging.info("...auto-generating build for " + b.versionName)
|
||||
if tag:
|
||||
b.commit = tag
|
||||
else:
|
||||
commit = pattern.replace('%v', app.CurrentVersion)
|
||||
commit = commit.replace('%c', str(v))
|
||||
b.commit = commit
|
||||
|
||||
app['Builds'].extend(newbuilds)
|
||||
|
||||
app['Builds'].append(newbuild)
|
||||
name = _getappname(app)
|
||||
ver = _getcvname(app)
|
||||
commitmsg = "Update %s to %s" % (name, ver)
|
||||
|
@ -262,10 +262,21 @@ def check_update_check_data_url(app): # noqa: D403
|
||||
|
||||
|
||||
def check_vercode_operation(app):
|
||||
if app.VercodeOperation and not common.VERCODE_OPERATION_RE.match(
|
||||
app.VercodeOperation
|
||||
):
|
||||
yield _('Invalid VercodeOperation: {field}').format(field=app.VercodeOperation)
|
||||
if not app.VercodeOperation:
|
||||
return
|
||||
ops = (
|
||||
[app.VercodeOperation]
|
||||
if isinstance(app.VercodeOperation, str)
|
||||
else app.VercodeOperation
|
||||
)
|
||||
invalid_ops = []
|
||||
for op in ops:
|
||||
if not common.VERCODE_OPERATION_RE.match(op):
|
||||
invalid_ops += op
|
||||
if invalid_ops:
|
||||
yield _('Invalid VercodeOperation: {invalid_ops}').format(
|
||||
invalid_ops=invalid_ops
|
||||
)
|
||||
|
||||
|
||||
def check_ucm_tags(app):
|
||||
|
@ -56,9 +56,10 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()):
|
||||
with mock.patch('subprocess.call', lambda cmd: 0):
|
||||
fdroidserver.checkupdates.checkupdates_app(app)
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, '1.1.9')
|
||||
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, '1.1.9')
|
||||
|
||||
with mock.patch(
|
||||
'fdroidserver.checkupdates.check_http', lambda app: ('1.7.9', 10107)
|
||||
@ -67,9 +68,10 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
with mock.patch('subprocess.call', lambda cmd: 0):
|
||||
with self.assertRaises(FDroidException):
|
||||
fdroidserver.checkupdates.checkupdates_app(app)
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, '1.1.9')
|
||||
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, '1.1.9')
|
||||
|
||||
def test_autoupdatemode_suffix(self):
|
||||
fdroidserver.checkupdates.options = mock.Mock()
|
||||
@ -95,9 +97,60 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()):
|
||||
with mock.patch('subprocess.call', lambda cmd: 0):
|
||||
fdroidserver.checkupdates.checkupdates_app(app)
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9.10109-fdroid')
|
||||
self.assertEqual(build.commit, 'v1.1.9_10109')
|
||||
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9.10109-fdroid')
|
||||
self.assertEqual(build.commit, 'v1.1.9_10109')
|
||||
|
||||
def test_autoupdate_multi_variants(self):
|
||||
fdroidserver.checkupdates.options = mock.Mock()
|
||||
fdroidserver.checkupdates.options.auto = 'bleh'
|
||||
fdroidserver.checkupdates.config = {}
|
||||
|
||||
app = fdroidserver.metadata.App()
|
||||
app.id = 'loop.starts.shooting'
|
||||
app.metadatapath = 'metadata/' + app.id + '.yml'
|
||||
app.CurrentVersion = '1.1.8'
|
||||
app.CurrentVersionCode = 101083
|
||||
app.UpdateCheckMode = 'Tags'
|
||||
app.AutoUpdateMode = r'Version'
|
||||
app.VercodeOperation = [
|
||||
"10*%c+1",
|
||||
"10*%c+3",
|
||||
]
|
||||
|
||||
build = fdroidserver.metadata.Build()
|
||||
build.versionCode = app.CurrentVersionCode - 2
|
||||
build.versionName = app.CurrentVersion
|
||||
build.gradle = ["arm"]
|
||||
app['Builds'].append(build)
|
||||
|
||||
build = fdroidserver.metadata.Build()
|
||||
build.versionCode = app.CurrentVersionCode
|
||||
build.versionName = app.CurrentVersion
|
||||
build.gradle = ["x86"]
|
||||
app['Builds'].append(build)
|
||||
|
||||
with mock.patch(
|
||||
'fdroidserver.checkupdates.check_tags',
|
||||
lambda app, pattern: ('1.1.9', 10109, 'v1.1.9'),
|
||||
):
|
||||
with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()):
|
||||
with mock.patch('subprocess.call', lambda cmd: 0):
|
||||
fdroidserver.checkupdates.checkupdates_app(app)
|
||||
|
||||
build = app['Builds'][-2]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.versionCode, 101091)
|
||||
self.assertEqual(build.gradle, ["arm"])
|
||||
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.versionCode, 101093)
|
||||
self.assertEqual(build.gradle, ["x86"])
|
||||
|
||||
self.assertEqual(app.CurrentVersion, '1.1.9')
|
||||
self.assertEqual(app.CurrentVersionCode, 101093)
|
||||
|
||||
def test_checkupdates_app_http(self):
|
||||
fdroidserver.checkupdates.options = mock.Mock()
|
||||
@ -159,9 +212,10 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
with mock.patch('fdroidserver.metadata.write_metadata', mock.Mock()):
|
||||
with mock.patch('subprocess.call', lambda cmd: 0):
|
||||
fdroidserver.checkupdates.checkupdates_app(app)
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, 'v1.1.9')
|
||||
|
||||
build = app['Builds'][-1]
|
||||
self.assertEqual(build.versionName, '1.1.9')
|
||||
self.assertEqual(build.commit, 'v1.1.9')
|
||||
|
||||
def test_check_http(self):
|
||||
fdroidserver.checkupdates.options = mock.Mock()
|
||||
@ -178,8 +232,8 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
respmock.read = lambda: 'v1.1.9\nc10109'.encode('utf-8')
|
||||
with mock.patch('urllib.request.urlopen', lambda a, b, c: respmock):
|
||||
vername, vercode = fdroidserver.checkupdates.check_http(app)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
|
||||
def test_check_http_blocks_unknown_schemes(self):
|
||||
app = fdroidserver.metadata.App()
|
||||
@ -206,7 +260,7 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
respmock.read = lambda: 'v1.1.9-beta\nc10109'.encode('utf-8')
|
||||
with mock.patch('urllib.request.urlopen', lambda a, b, c: respmock):
|
||||
vername, vercode = fdroidserver.checkupdates.check_http(app)
|
||||
self.assertEqual(vername, None)
|
||||
self.assertEqual(vername, None)
|
||||
|
||||
def test_check_tags_data(self):
|
||||
fdroidserver.checkupdates.options = mock.Mock()
|
||||
@ -229,8 +283,8 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
_ignored # silence the linters
|
||||
mock_path.is_file.return_falue = True
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
|
||||
app.UpdateCheckData = r'b.txt|c(.*)|.|v(.*)'
|
||||
with mock.patch(
|
||||
@ -241,8 +295,8 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
_ignored # silence the linters
|
||||
mock_path.is_file.return_falue = True
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 10109)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 10109)
|
||||
|
||||
app.UpdateCheckData = r'b.txt|c(.*)||'
|
||||
with mock.patch(
|
||||
@ -253,8 +307,8 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
_ignored # silence the linters
|
||||
mock_path.is_file.return_falue = True
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
self.assertEqual(vername, '1.1.9')
|
||||
self.assertEqual(vercode, 10109)
|
||||
|
||||
vcs.latesttags.return_value = ['Android-1.1.0', '1.1.8']
|
||||
app.UpdateCheckData = r'b.txt|c(.*)||Android-([\d.]+)'
|
||||
@ -266,22 +320,22 @@ class CheckupdatesTest(unittest.TestCase):
|
||||
_ignored # silence the linters
|
||||
mock_path.is_file.return_falue = True
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 10109)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 10109)
|
||||
|
||||
app.UpdateCheckData = r'|\+(\d+)||Android-([\d.]+)'
|
||||
vcs.latesttags.return_value = ['Android-1.1.0+1']
|
||||
with mock.patch('fdroidserver.common.getvcs', return_value=vcs):
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 1)
|
||||
self.assertEqual(vername, '1.1.0')
|
||||
self.assertEqual(vercode, 1)
|
||||
|
||||
app.UpdateCheckData = '|||'
|
||||
vcs.latesttags.return_value = ['2']
|
||||
with mock.patch('fdroidserver.common.getvcs', return_value=vcs):
|
||||
vername, vercode, _tag = fdroidserver.checkupdates.check_tags(app, None)
|
||||
self.assertEqual(vername, '2')
|
||||
self.assertEqual(vercode, 2)
|
||||
self.assertEqual(vername, '2')
|
||||
self.assertEqual(vercode, 2)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Loading…
Reference in New Issue
Block a user