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 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. changed the package name or version code logic.
@item @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 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. available and the upstream developer keeps us posted on new versions.
@item @item

View file

@ -424,6 +424,8 @@ def metafieldtype(name):
return 'flag' return 'flag'
if name == 'Build Version': if name == 'Build Version':
return 'build' return 'build'
if name == 'Build':
return 'buildv2'
if name == 'Use Built': if name == 'Use Built':
return 'obsolete' return 'obsolete'
return 'string' return 'string'
@ -454,7 +456,7 @@ def metafieldtype(name):
# 'descriptionlines' - original lines of description as formatted in the # 'descriptionlines' - original lines of description as formatted in the
# metadata file. # metadata file.
# #
def parse_metadata(metafile, **kw): def parse_metadata(metafile, verbose=False):
def parse_buildline(lines): def parse_buildline(lines):
value = "".join(lines) value = "".join(lines)
@ -477,6 +479,8 @@ def parse_metadata(metafile, **kw):
return thisbuild return thisbuild
def add_comments(key): def add_comments(key):
if len(curcomments) == 0:
return
for comment in curcomments: for comment in curcomments:
thisinfo['comments'].append((key, comment)) thisinfo['comments'].append((key, comment))
del curcomments[:] del curcomments[:]
@ -525,9 +529,35 @@ def parse_metadata(metafile, **kw):
mode = 0 mode = 0
buildlines = [] buildlines = []
curcomments = [] curcomments = []
curbuild = None
for line in metafile: for line in metafile:
line = line.rstrip('\r\n') 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 mode == 0:
if len(line) == 0: if len(line) == 0:
continue continue
@ -547,7 +577,7 @@ def parse_metadata(metafile, **kw):
field = 'Current Version Code' field = 'Current Version Code'
fieldtype = metafieldtype(field) fieldtype = metafieldtype(field)
if fieldtype != 'build': if fieldtype not in ['build', 'buildv2']:
add_comments(field) add_comments(field)
if fieldtype == 'multiline': if fieldtype == 'multiline':
mode = 1 mode = 1
@ -570,6 +600,20 @@ def parse_metadata(metafile, **kw):
else: else:
thisinfo['builds'].append(parse_buildline([value])) thisinfo['builds'].append(parse_buildline([value]))
add_comments('build:' + thisinfo['builds'][-1]['version']) 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': elif fieldtype == 'obsolete':
pass # Just throw it away! pass # Just throw it away!
else: else:
@ -595,6 +639,8 @@ def parse_metadata(metafile, **kw):
raise MetaDataException(field + " not terminated in " + metafile.name) raise MetaDataException(field + " not terminated in " + metafile.name)
elif mode == 2: elif mode == 2:
raise MetaDataException("Unterminated continuation in " + metafile.name) raise MetaDataException("Unterminated continuation in " + metafile.name)
elif mode == 3:
raise MetaDataException("Unterminated build in " + metafile.name)
if len(thisinfo['Description']) == 0: if len(thisinfo['Description']) == 0:
thisinfo['Description'].append('No description available') thisinfo['Description'].append('No description available')
@ -637,12 +683,16 @@ def getsrcname(app, build):
# #
# 'dest' - The path to the output file # 'dest' - The path to the output file
# 'app' - The app data # 'app' - The app data
def write_metadata(dest, app): def write_metadata(dest, app, verbose=False):
def writecomments(key): def writecomments(key):
written = 0
for pf, comment in app['comments']: for pf, comment in app['comments']:
if pf == key: if pf == key:
mf.write(comment + '\n') 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): def writefield(field, value=None):
writecomments(field) writecomments(field)
@ -671,7 +721,8 @@ def write_metadata(dest, app):
mf.write('\n') mf.write('\n')
if app['Name']: if app['Name']:
writefield('Name') writefield('Name')
writefield('Auto Name') if len(app['Auto Name']) > 0:
writefield('Auto Name')
writefield('Summary') writefield('Summary')
writefield('Description', '') writefield('Description', '')
for line in app['Description']: for line in app['Description']:
@ -685,24 +736,40 @@ def write_metadata(dest, app):
writefield('Repo Type') writefield('Repo Type')
writefield('Repo') writefield('Repo')
mf.write('\n') mf.write('\n')
keystoignore = ['version', 'vercode', 'subvercode', 'commit']
for build in app['builds']: for build in app['builds']:
writecomments('build:' + build['version']) writecomments('build:' + build['version'])
mf.write('Build Version:') mf.write('Build:')
if 'origlines' in build: mf.write("%s,%s\n" % (
# Keeping the original formatting if we loaded it from a file... build['version'],
mf.write('\\\n'.join(build['origlines']) + '\n') getvercode(build)))
else:
mf.write("%s,%s,%s" % ( # This defines the preferred order for the build items - as in the
build['version'], # manual, they're roughly in order of application.
getvercode(build), keyorder = ['disable', 'commit', 'subdir', 'submodules', 'init',
build['commit'])) 'oldsdkloc', 'target', 'compilesdk', 'update',
for key,value in build.iteritems(): 'encoding', 'forceversion', 'forcevercode', 'rm',
if key not in keystoignore: 'fixtrans', 'fixapos', 'extlibs', 'srclibs',
mf.write(',' + key + '=' + value) 'patch', 'prebuild', 'initfun', 'scanignore', 'build',
mf.write('\n') 'buildjni', 'gradle', 'maven', 'preassemble',
if len(app['builds']) > 0: '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') mf.write('\n')
if app['Archive Policy']: if app['Archive Policy']:
writefield('Archive Policy') writefield('Archive Policy')
writefield('Auto Update Mode') 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 # Read all metadata. Returns a list of 'app' objects (which are dictionaries as
# returned by the parse_metadata function. # returned by the parse_metadata function.
def read_metadata(verbose=False, xref=True): def read_metadata(verbose=False, xref=True, package=None):
apps = [] apps = []
for metafile in sorted(glob.glob(os.path.join('metadata', '*.txt'))): for metafile in sorted(glob.glob(os.path.join('metadata', '*.txt'))):
try: if package is None or metafile == os.path.join('metadata', package + '.txt'):
appinfo = parse_metadata(metafile, verbose=verbose) try:
except Exception, e: appinfo = parse_metadata(metafile, verbose=verbose)
raise MetaDataException("Problem reading metadata file %s: - %s" % (metafile, str(e))) except Exception, e:
apps.append(appinfo) raise MetaDataException("Problem reading metadata file %s: - %s" % (metafile, str(e)))
apps.append(appinfo)
if xref: if xref:
# Parse all descriptions at load time, just to ensure cross-referencing # 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, parser.add_option("-v", "--verbose", action="store_true", default=False,
help="Spew out even more information than normal") help="Spew out even more information than normal")
parser.add_option("-p", "--package", default=None, parser.add_option("-p", "--package", default=None,
help="Build only the specified package") help="Process only the specified package")
(options, args) = parser.parse_args() (options, args) = parser.parse_args()
# Get all apps... # 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 len(apps) == 0 and options.package:
if options.package: print "No such package"
apps = [app for app in apps if app['id'] == options.package] sys.exit(1)
if len(apps) == 0:
print "No such package"
sys.exit(1)
for app in apps: for app in apps:
print "Writing " + app['id'] 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." print "Finished."