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

Read new or old recipe formats, write new format

Slightly tested. See https://f-droid.org/wiki/page/Build_Recipe_Format
This commit is contained in:
Ciaran Gultnieks 2013-10-27 14:06:46 +00:00
parent 67021f8760
commit 327e472169
3 changed files with 100 additions and 35 deletions

View File

@ -1068,7 +1068,7 @@ gradle build system and store version info in a separate file; if the
developers make a new branch for each release and don't make tags; or if you've
changed the package name or version code logic.
@item
@code{Static} - No checking is doneeither development has ceased or new versions
@code{Static} - No checking is done - either development has ceased or new versions
are not desired. This method is also used when there is no other checking method
available and the upstream developer keeps us posted on new versions.
@item

View File

@ -424,6 +424,8 @@ def metafieldtype(name):
return 'flag'
if name == 'Build Version':
return 'build'
if name == 'Build':
return 'buildv2'
if name == 'Use Built':
return 'obsolete'
return 'string'
@ -454,7 +456,7 @@ def metafieldtype(name):
# 'descriptionlines' - original lines of description as formatted in the
# metadata file.
#
def parse_metadata(metafile, **kw):
def parse_metadata(metafile, verbose=False):
def parse_buildline(lines):
value = "".join(lines)
@ -477,6 +479,8 @@ def parse_metadata(metafile, **kw):
return thisbuild
def add_comments(key):
if len(curcomments) == 0:
return
for comment in curcomments:
thisinfo['comments'].append((key, comment))
del curcomments[:]
@ -525,9 +529,35 @@ def parse_metadata(metafile, **kw):
mode = 0
buildlines = []
curcomments = []
curbuild = None
for line in metafile:
line = line.rstrip('\r\n')
if mode == 3:
if not line.startswith(' '):
if 'commit' not in curbuild:
raise MetaDataException("No commit specified for {0} in {1}".format(
curbuild['version'], metafile.name))
thisinfo['builds'].append(curbuild)
add_comments('build:' + curbuild['version'])
mode = 0
else:
if line.endswith('\\'):
buildlines.append(line[:-1].lstrip())
else:
buildlines.append(line.lstrip())
bl = ''.join(buildlines)
bv = bl.split('=', 1)
if len(bv) != 2:
raise MetaDataException("Invalid build flag at {0} in {1}".
format(buildlines[0], metafile.name))
name, val = bv
if name in curbuild:
raise MetaDataException("Duplicate definition on {0} in version {1} of {2}".
format(name, curbuild['version'], metafile.name))
curbuild[name] = val.lstrip()
buildlines = []
if mode == 0:
if len(line) == 0:
continue
@ -547,7 +577,7 @@ def parse_metadata(metafile, **kw):
field = 'Current Version Code'
fieldtype = metafieldtype(field)
if fieldtype != 'build':
if fieldtype not in ['build', 'buildv2']:
add_comments(field)
if fieldtype == 'multiline':
mode = 1
@ -570,6 +600,20 @@ def parse_metadata(metafile, **kw):
else:
thisinfo['builds'].append(parse_buildline([value]))
add_comments('build:' + thisinfo['builds'][-1]['version'])
elif fieldtype == 'buildv2':
curbuild = {}
vv = value.split(',')
if len(vv) != 2:
raise MetaDataException('Build should have comma-separated version and vercode, not "{0}", in {1}'.
format(value, metafile.name))
curbuild['version'] = vv[0]
curbuild['vercode'] = vv[1]
try:
testvercode = int(curbuild['vercode'])
except:
raise MetaDataException("Invalid version code for build in " + metafile.name)
buildlines = []
mode = 3
elif fieldtype == 'obsolete':
pass # Just throw it away!
else:
@ -595,6 +639,8 @@ def parse_metadata(metafile, **kw):
raise MetaDataException(field + " not terminated in " + metafile.name)
elif mode == 2:
raise MetaDataException("Unterminated continuation in " + metafile.name)
elif mode == 3:
raise MetaDataException("Unterminated build in " + metafile.name)
if len(thisinfo['Description']) == 0:
thisinfo['Description'].append('No description available')
@ -637,12 +683,16 @@ def getsrcname(app, build):
#
# 'dest' - The path to the output file
# 'app' - The app data
def write_metadata(dest, app):
def write_metadata(dest, app, verbose=False):
def writecomments(key):
written = 0
for pf, comment in app['comments']:
if pf == key:
mf.write(comment + '\n')
written += 1
if verbose and written > 0:
print "...writing comments for " + (key if key else 'EOF')
def writefield(field, value=None):
writecomments(field)
@ -671,7 +721,8 @@ def write_metadata(dest, app):
mf.write('\n')
if app['Name']:
writefield('Name')
writefield('Auto Name')
if len(app['Auto Name']) > 0:
writefield('Auto Name')
writefield('Summary')
writefield('Description', '')
for line in app['Description']:
@ -685,24 +736,40 @@ def write_metadata(dest, app):
writefield('Repo Type')
writefield('Repo')
mf.write('\n')
keystoignore = ['version', 'vercode', 'subvercode', 'commit']
for build in app['builds']:
writecomments('build:' + build['version'])
mf.write('Build Version:')
if 'origlines' in build:
# Keeping the original formatting if we loaded it from a file...
mf.write('\\\n'.join(build['origlines']) + '\n')
else:
mf.write("%s,%s,%s" % (
build['version'],
getvercode(build),
build['commit']))
for key,value in build.iteritems():
if key not in keystoignore:
mf.write(',' + key + '=' + value)
mf.write('\n')
if len(app['builds']) > 0:
mf.write('Build:')
mf.write("%s,%s\n" % (
build['version'],
getvercode(build)))
# This defines the preferred order for the build items - as in the
# manual, they're roughly in order of application.
keyorder = ['disable', 'commit', 'subdir', 'submodules', 'init',
'oldsdkloc', 'target', 'compilesdk', 'update',
'encoding', 'forceversion', 'forcevercode', 'rm',
'fixtrans', 'fixapos', 'extlibs', 'srclibs',
'patch', 'prebuild', 'initfun', 'scanignore', 'build',
'buildjni', 'gradle', 'maven', 'preassemble',
'bindir', 'antcommand', 'novcheck']
def write_builditem(key, value):
if key not in ['version', 'vercode', 'origlines']:
if verbose:
print "...writing {0} : {1}".format(key, value)
outline = ' ' + key + '='
bits = value.split('&& ')
outline += '&& \\\n '.join([s.lstrip() for s in bits])
outline += '\n'
mf.write(outline)
for key in keyorder:
if key in build:
write_builditem(key, build[key])
for key, value in build.iteritems():
if not key in keyorder:
write_builditem(key, value)
mf.write('\n')
if app['Archive Policy']:
writefield('Archive Policy')
writefield('Auto Update Mode')
@ -722,14 +789,15 @@ def write_metadata(dest, app):
# Read all metadata. Returns a list of 'app' objects (which are dictionaries as
# returned by the parse_metadata function.
def read_metadata(verbose=False, xref=True):
def read_metadata(verbose=False, xref=True, package=None):
apps = []
for metafile in sorted(glob.glob(os.path.join('metadata', '*.txt'))):
try:
appinfo = parse_metadata(metafile, verbose=verbose)
except Exception, e:
raise MetaDataException("Problem reading metadata file %s: - %s" % (metafile, str(e)))
apps.append(appinfo)
if package is None or metafile == os.path.join('metadata', package + '.txt'):
try:
appinfo = parse_metadata(metafile, verbose=verbose)
except Exception, e:
raise MetaDataException("Problem reading metadata file %s: - %s" % (metafile, str(e)))
apps.append(appinfo)
if xref:
# Parse all descriptions at load time, just to ensure cross-referencing

View File

@ -32,22 +32,19 @@ def main():
parser.add_option("-v", "--verbose", action="store_true", default=False,
help="Spew out even more information than normal")
parser.add_option("-p", "--package", default=None,
help="Build only the specified package")
help="Process only the specified package")
(options, args) = parser.parse_args()
# Get all apps...
apps = common.read_metadata(options.verbose)
apps = common.read_metadata(options.verbose, package=options.package)
# Filter apps according to command-line options
if options.package:
apps = [app for app in apps if app['id'] == options.package]
if len(apps) == 0:
print "No such package"
sys.exit(1)
if len(apps) == 0 and options.package:
print "No such package"
sys.exit(1)
for app in apps:
print "Writing " + app['id']
common.write_metadata(os.path.join('metadata', app['id']) + '.txt', app)
common.write_metadata(os.path.join('metadata', app['id']) + '.txt', app, verbose=options.verbose)
print "Finished."