mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-09-13 14:32:28 +03: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:
parent
67021f8760
commit
327e472169
3 changed files with 100 additions and 35 deletions
|
@ -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 done—either 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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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."
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue