1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-09-17 18:50:11 +02:00
This commit is contained in:
Dominik 2012-02-14 23:46:56 +01:00
commit 66f6cb881f
288 changed files with 3326 additions and 1115 deletions

4
.gitignore vendored
View File

@ -2,7 +2,9 @@ config.py
repo/
logs/
built/
build/
tmp/
build_*/
*~
*.pyc
buildserver.box
unsigned/

12
README
View File

@ -186,6 +186,8 @@ configuration to the build. These are:
last character on a line to join that line with the next.
It has no special meaning in other contexts; in particular,
literal backslashes should not be escaped.
init=xxxx As for 'prebuild', but runs on the source code BEFORE any
other processing takes place.
novcheck=yes Don't check that the version name and code in the resulting
apk are correct by looking at the build output - assume the
metadata is correct. This takes away a useful level of
@ -204,6 +206,16 @@ configuration to the build. These are:
files within a directory below the metadata, with the same
name as the metadata file but without the extension. Each of
these patches is applied to the code in turn.
extlibs=a;b;c Specifies a list of external libraries (jar files) from the
build/extlib library, which will be placed in the libs
directory of the project. Separate items with semicolons.
srclibs=a@r;b@r1 Specifies a list of source libraries (kept up to date using
version control) from a predefined set. Separate items with
semicolons, and each item is of the form name@rev where name
is the predefined source library name and rev is the
revision in source control to use. You can then also use
$$name$$ in the prebuild command to substitute the relative
path to the library directory.
Another example, using extra parameters:

17
README.buildserver Normal file
View File

@ -0,0 +1,17 @@
Setting up a build server:
1. Install VirtualBox, vagrant and vagrant-snap
2. In the buildserver directory, run 'vagrant up'. Will take a long time.
3. Log in with 'vagrant ssh'
4. Check it all looks ok, then 'sudo shutdown -h now'
5. Back in the main directory, run 'VBoxManage listvms' look for
buildserver_xxxx
6. Run 'vagrant package --base buildserver_xxxx --output buildserver.box'.
Will take a while.
7. You should now have a new 'buildserver.box'
You should now be able to use the --server option on build.py and builds will
take place in the clean, secure, isolated environment of a fresh virtual
machine for each app built.

394
build.py
View File

@ -24,8 +24,7 @@ import subprocess
import re
import zipfile
import tarfile
import md5
import shlex
import traceback
from xml.dom.minidom import Document
from optparse import OptionParser
@ -44,8 +43,20 @@ parser.add_option("-p", "--package", default=None,
help="Build only the specified package")
parser.add_option("-s", "--stop", action="store_true", default=False,
help="Make the build stop on exceptions")
parser.add_option("-t", "--test", action="store_true", default=False,
help="Test mode - put output in the tmp directory only.")
parser.add_option("--server", action="store_true", default=False,
help="Use build server")
parser.add_option("--on-server", action="store_true", default=False,
help="Specify that we're running on the build server")
parser.add_option("-f", "--force", action="store_true", default=False,
help="Force build of disabled app. Only allowed in test mode.")
(options, args) = parser.parse_args()
if options.force and not options.test:
print "Force is only allowed in test mode"
sys.exit(1)
# Get all apps...
apps = common.read_metadata(options.verbose)
@ -57,32 +68,40 @@ if not os.path.isdir(log_dir):
print "Creating log directory"
os.makedirs(log_dir)
output_dir = 'repo'
if not os.path.isdir(output_dir):
print "Creating output directory"
os.makedirs(output_dir)
tmp_dir = 'tmp'
if not os.path.isdir(tmp_dir):
print "Creating temporary directory"
os.makedirs(tmp_dir)
if options.test:
output_dir = tmp_dir
else:
output_dir = 'unsigned'
if not os.path.isdir(output_dir):
print "Creating output directory"
os.makedirs(output_dir)
repo_dir = 'repo'
build_dir = 'build'
if not os.path.isdir(build_dir):
print "Creating build directory"
os.makedirs(build_dir)
extlib_dir = os.path.join(build_dir, 'extlib')
# Build applications...
for app in apps:
if options.package and options.package != app['id']:
# Silent skip...
pass
elif app['Disabled']:
print "Skipping %s: disabled" % app['id']
elif app['Disabled'] and not options.force:
if options.verbose:
print "Skipping %s: disabled" % app['id']
elif (not app['builds']) or app['Repo Type'] =='' or len(app['builds']) == 0:
print "Skipping %s: no builds specified" % app['id']
if options.verbose:
print "Skipping %s: no builds specified" % app['id']
else:
print "Processing " + app['id']
build_dir = 'build/' + app['id']
@ -96,180 +115,217 @@ for app in apps:
try:
dest = os.path.join(output_dir, app['id'] + '_' +
thisbuild['vercode'] + '.apk')
dest_unsigned = os.path.join(tmp_dir, app['id'] + '_' +
thisbuild['vercode'] + '_unsigned.apk')
dest_repo = os.path.join(repo_dir, app['id'] + '_' +
thisbuild['vercode'] + '.apk')
if os.path.exists(dest):
print "..version " + thisbuild['version'] + " already exists"
if os.path.exists(dest) or (not options.test and os.path.exists(dest_repo)):
if options.verbose:
print "..version " + thisbuild['version'] + " already exists"
elif thisbuild['commit'].startswith('!'):
print ("..skipping version " + thisbuild['version'] + " - " +
if options.verbose:
print ("..skipping version " + thisbuild['version'] + " - " +
thisbuild['commit'][1:])
else:
print "..building version " + thisbuild['version']
if options.verbose:
mstart = '.. building version '
else:
mstart = 'Building version '
print mstart + thisbuild['version'] + ' of ' + app['id']
# Prepare the source code...
root_dir = common.prepare_source(vcs, app, thisbuild,
build_dir, sdk_path, ndk_path, javacc_path,
not refreshed_source)
refreshed_source = True
if options.server:
# Build the source tarball right before we build the release...
tarname = app['id'] + '_' + thisbuild['vercode'] + '_src'
tarball = tarfile.open(os.path.join(output_dir,
tarname + '.tar.gz'), "w:gz")
def tarexc(f):
if f in ['.svn', '.git', '.hg', '.bzr']:
return True
return False
tarball.add(build_dir, tarname, exclude=tarexc)
tarball.close()
import paramiko
# Build native stuff if required...
if thisbuild.get('buildjni', 'no') == 'yes':
ndkbuild = os.path.join(ndk_path, "ndk-build")
p = subprocess.Popen([ndkbuild], cwd=root_dir,
stdout=subprocess.PIPE)
output = p.communicate()[0]
# Start up the virtual maachine...
if subprocess.call(['vagrant', 'up'], cwd='builder') != 0:
# Not a very helpful message yet!
raise BuildException("Failed to set up build server")
# Get SSH configuration settings for us to connect...
subprocess.call('vagrant ssh-config >sshconfig',
cwd='builder', shell=True)
vagranthost = 'default' # Host in ssh config file
# Load and parse the SSH config...
sshconfig = paramiko.SSHConfig()
sshconfig.parse('builder/sshconfig')
sshconfig = sshconfig.lookup(vagranthost)
# Open SSH connection...
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AcceptPolicy)
ssh.connect(sshconfig['HostName'], username=sshconfig['Username'],
port=sshconfig['Port'], timeout=10, look_for_keys=False,
key_filename=sshconfig['IdentityFile'])
# Get an SFTP connection...
ftp = ssh.open_sftp()
ftp.get_channel().settimeout(15)
# Put all the necessary files in place...
ftp.chdir('/home/vagrant')
ftp.put('build.py', 'build.py')
ftp.put('common.py', 'common.py')
ftp.put('config.buildserver.py', 'config.py')
ftp.mkdir('build')
ftp.chdir('build')
ftp.mkdir('extlib')
def send_dir(path):
lastdir = path
for r, d, f in os.walk(base):
while lastdir != os.path.commonprefix([lastdir, root]):
ftp.chdir('..')
lastdir = os.path.split(lastdir)[0]
lastdir = r
for ff in f:
ftp.put(os.path.join(r, ff), ff)
ftp.send_dir(app['id'])
# TODO: send relevant extlib directories too
ftp.chdir('/home/vagrant')
# Execute the build script...
ssh.exec_command('python build.py --on-server -p ' +
app['id'])
# Retrieve the built files...
apkfile = app['id'] + '_' + thisbuild['vercode'] + '.apk'
tarball = app['id'] + '_' + thisbuild['vercode'] + '_src' + '.tar.gz'
ftp.chdir('unsigned')
ftp.get(apkfile, os.path.join(output_dir, apkfile))
ftp.get(tarball, os.path.join(output_dir, tarball))
# Get rid of the virtual machine...
if subprocess.call(['vagrant', 'destroy'], cwd='builder') != 0:
# Not a very helpful message yet!
raise BuildException("Failed to destroy")
else:
# Prepare the source code...
root_dir = common.prepare_source(vcs, app, thisbuild,
build_dir, extlib_dir, sdk_path, ndk_path,
javacc_path, not refreshed_source)
refreshed_source = True
# Scan before building...
buildprobs = common.scan_source(build_dir, root_dir, thisbuild)
if len(buildprobs) > 0:
print 'Scanner found ' + str(len(buildprobs)) + ' problems:'
for problem in buildprobs:
print '...' + problem
raise BuildException("Can't build due to " +
str(len(buildprobs)) + " scanned problems")
# Build the source tarball right before we build the release...
tarname = app['id'] + '_' + thisbuild['vercode'] + '_src'
tarball = tarfile.open(os.path.join(tmp_dir,
tarname + '.tar.gz'), "w:gz")
def tarexc(f):
if f in ['.svn', '.git', '.hg', '.bzr']:
return True
return False
tarball.add(build_dir, tarname, exclude=tarexc)
tarball.close()
# Build native stuff if required...
if thisbuild.get('buildjni', 'no') == 'yes':
ndkbuild = os.path.join(ndk_path, "ndk-build")
p = subprocess.Popen([ndkbuild], cwd=root_dir,
stdout=subprocess.PIPE)
output = p.communicate()[0]
if p.returncode != 0:
print output
raise BuildException("NDK build failed for %s:%s" % (app['id'], thisbuild['version']))
elif options.verbose:
print output
# Build the release...
if thisbuild.has_key('maven'):
p = subprocess.Popen(['mvn', 'clean', 'install',
'-Dandroid.sdk.path=' + sdk_path],
cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
if thisbuild.has_key('antcommand'):
antcommand = thisbuild['antcommand']
else:
antcommand = 'release'
p = subprocess.Popen(['ant', antcommand], cwd=root_dir,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
if p.returncode != 0:
print output
raise BuildException("NDK build failed for %s:%s" % (app['id'], thisbuild['version']))
raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), output.strip(), error.strip())
elif options.verbose:
print output
print "Build successful"
# Build the release...
if thisbuild.has_key('maven'):
p = subprocess.Popen(['mvn', 'clean', 'install',
'-Dandroid.sdk.path=' + sdk_path],
cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
else:
if thisbuild.has_key('antcommand'):
antcommand = thisbuild['antcommand']
# Find the apk name in the output...
if thisbuild.has_key('bindir'):
bindir = os.path.join(build_dir, thisbuild['bindir'])
else:
antcommand = 'release'
p = subprocess.Popen(['ant', antcommand], cwd=root_dir,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output, error = p.communicate()
if p.returncode != 0:
raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), output.strip(), error.strip())
elif options.verbose:
print output
print "Build successful"
# Find the apk name in the output...
if thisbuild.has_key('bindir'):
bindir = os.path.join(build_dir, thisbuild['bindir'])
else:
bindir = os.path.join(root_dir, 'bin')
if thisbuild.get('initfun', 'no') == "yes":
# Special case (again!) for funambol...
src = ("funambol-android-sync-client-" +
thisbuild['version'] + "-unsigned.apk")
src = os.path.join(bindir, src)
elif thisbuild.has_key('maven'):
src = re.match(r".*^\[INFO\] Installing /.*/([^/]*)\.apk",
output, re.S|re.M).group(1)
src = os.path.join(bindir, src) + '.apk'
bindir = os.path.join(root_dir, 'bin')
if thisbuild.get('initfun', 'no') == "yes":
# Special case (again!) for funambol...
src = ("funambol-android-sync-client-" +
thisbuild['version'] + "-unsigned.apk")
src = os.path.join(bindir, src)
elif thisbuild.has_key('maven'):
src = re.match(r".*^\[INFO\] Installing /.*/([^/]*)\.apk",
output, re.S|re.M).group(1)
src = os.path.join(bindir, src) + '.apk'
#[INFO] Installing /home/ciaran/fdroidserver/tmp/mainline/application/target/callerid-1.0-SNAPSHOT.apk
else:
src = re.match(r".*^.*Creating (\S+) for release.*$.*", output,
re.S|re.M).group(1)
src = os.path.join(bindir, src)
else:
src = re.match(r".*^.*Creating (\S+) for release.*$.*", output,
re.S|re.M).group(1)
src = os.path.join(bindir, src)
# By way of a sanity check, make sure the version and version
# code in our new apk match what we expect...
print "Checking " + src
p = subprocess.Popen([os.path.join(sdk_path, 'platform-tools',
'aapt'),
'dump', 'badging', src],
stdout=subprocess.PIPE)
output = p.communicate()[0]
if thisbuild.get('novcheck', 'no') == "yes":
vercode = thisbuild['vercode']
version = thisbuild['version']
else:
vercode = None
version = None
for line in output.splitlines():
if line.startswith("package:"):
pat = re.compile(".*versionCode='([0-9]*)'.*")
vercode = re.match(pat, line).group(1)
pat = re.compile(".*versionName='([^']*)'.*")
version = re.match(pat, line).group(1)
if version == None or vercode == None:
raise BuildException("Could not find version information in build in output")
# Some apps (e.g. Timeriffic) have had the bonkers idea of
# including the entire changelog in the version number. Remove
# it so we can compare. (TODO: might be better to remove it
# before we compile, in fact)
index = version.find(" //")
if index != -1:
version = version[:index]
if (version != thisbuild['version'] or
vercode != thisbuild['vercode']):
raise BuildException(("Unexpected version/version code in output"
"APK: %s / %s"
"Expected: %s / %s")
% (version, str(vercode), thisbuild['version'], str(thisbuild['vercode']))
)
# Copy the unsigned apk to our temp directory for further
# processing...
shutil.copyfile(src, dest_unsigned)
# Figure out the key alias name we'll use. Only the first 8
# characters are significant, so we'll use the first 8 from
# the MD5 of the app's ID and hope there are no collisions.
# If a collision does occur later, we're going to have to
# come up with a new alogrithm, AND rename all existing keys
# in the keystore!
if keyaliases.has_key(app['id']):
# For this particular app, the key alias is overridden...
keyalias = keyaliases[app['id']]
else:
m = md5.new()
m.update(app['id'])
keyalias = m.hexdigest()[:8]
print "Key alias: " + keyalias
# See if we already have a key for this application, and
# if not generate one...
p = subprocess.Popen(['keytool', '-list',
'-alias', keyalias, '-keystore', keystore,
'-storepass', keystorepass], stdout=subprocess.PIPE)
output = p.communicate()[0]
if p.returncode !=0:
print "Key does not exist - generating..."
p = subprocess.Popen(['keytool', '-genkey',
'-keystore', keystore, '-alias', keyalias,
'-keyalg', 'RSA', '-keysize', '2048',
'-validity', '10000',
'-storepass', keystorepass, '-keypass', keypass,
'-dname', keydname], stdout=subprocess.PIPE)
# By way of a sanity check, make sure the version and version
# code in our new apk match what we expect...
print "Checking " + src
p = subprocess.Popen([os.path.join(sdk_path, 'platform-tools',
'aapt'),
'dump', 'badging', src],
stdout=subprocess.PIPE)
output = p.communicate()[0]
print output
if p.returncode != 0:
raise BuildException("Failed to generate key")
if thisbuild.get('novcheck', 'no') == "yes":
vercode = thisbuild['vercode']
version = thisbuild['version']
else:
vercode = None
version = None
for line in output.splitlines():
if line.startswith("package:"):
pat = re.compile(".*versionCode='([0-9]*)'.*")
vercode = re.match(pat, line).group(1)
pat = re.compile(".*versionName='([^']*)'.*")
version = re.match(pat, line).group(1)
if version == None or vercode == None:
raise BuildException("Could not find version information in build in output")
# Sign the application...
p = subprocess.Popen(['jarsigner', '-keystore', keystore,
'-storepass', keystorepass, '-keypass', keypass,
dest_unsigned, keyalias], stdout=subprocess.PIPE)
output = p.communicate()[0]
print output
if p.returncode != 0:
raise BuildException("Failed to sign application")
# Some apps (e.g. Timeriffic) have had the bonkers idea of
# including the entire changelog in the version number. Remove
# it so we can compare. (TODO: might be better to remove it
# before we compile, in fact)
index = version.find(" //")
if index != -1:
version = version[:index]
if (version != thisbuild['version'] or
vercode != thisbuild['vercode']):
raise BuildException(("Unexpected version/version code in output"
"APK: %s / %s"
"Expected: %s / %s")
% (version, str(vercode), thisbuild['version'], str(thisbuild['vercode']))
)
# Copy the unsigned apk to our destination directory for further
# processing (by publish.py)...
shutil.copyfile(src, dest)
# Move the source tarball into the output directory...
if output_dir != tmp_dir:
tarfilename = tarname + '.tar.gz'
shutil.move(os.path.join(tmp_dir, tarfilename),
os.path.join(output_dir, tarfilename))
# Zipalign it...
p = subprocess.Popen([os.path.join(sdk_path,'tools','zipalign'),
'-v', '4', dest_unsigned, dest],
stdout=subprocess.PIPE)
output = p.communicate()[0]
print output
if p.returncode != 0:
raise BuildException("Failed to align application")
os.remove(dest_unsigned)
build_succeeded.append(app)
except BuildException as be:
if options.stop:
@ -287,7 +343,7 @@ for app in apps:
except Exception as e:
if options.stop:
raise
print "Could not build app %s due to unknown error: %s" % (app['id'], e)
print "Could not build app %s due to unknown error: %s" % (app['id'], traceback.format_exc())
failed_apps[app['id']] = e
for app in build_succeeded:

2
build/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*/
!extlib/

6
build/extlib/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
!*/
GreenDroid/
ActionBarSherlock/
FacebookSDK/
OI/
JOpenDocument/

Binary file not shown.

View File

@ -0,0 +1 @@
https://github.com/NightWhistler/HtmlSpanner.git

Binary file not shown.

View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

View File

@ -0,0 +1 @@
http://archive.apache.org/dist/commons/io/binaries/commons-io-2.0.1-bin.zip

Binary file not shown.

View File

@ -0,0 +1 @@
https://github.com/psiegman/epublib

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Binary file not shown.

View File

@ -0,0 +1 @@
http://guava-libraries.googlecode.com/files/guava-r08.zip

Binary file not shown.

View File

@ -0,0 +1 @@
http://code.google.com/p/google-guice/

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
builder/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
sshconfig

8
builder/Vagrantfile vendored Normal file
View File

@ -0,0 +1,8 @@
Vagrant::Config.run do |config|
config.vm.box = "buildserver"
config.vm.box_url = "../buildserver.box"
config.vm.customize ["modifyvm", :id, "--memory", "768"]
end

1
buildserver/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vagrant

26
buildserver/Vagrantfile vendored Normal file
View File

@ -0,0 +1,26 @@
Vagrant::Config.run do |config|
config.vm.box = "debian6-32"
config.vm.box_url = "/shares/software/OS and Boot/debian6-32.box"
config.vm.customize ["modifyvm", :id, "--memory", "1024"]
config.vm.provision :shell, :path => "fixpaths.sh"
# Set apt proxy - remove, or adjust this, accordingly!
config.vm.provision :shell, :inline => 'sudo echo "Acquire::http { Proxy \"http://thurlow:3142\"; };" > /etc/apt/apt.conf.d/02proxy && sudo apt-get update'
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "cookbooks"
chef.log_level = :debug
chef.json = {
:settings => {
:sdk_loc => "/home/vagrant/android-sdk",
:ndk_loc => "/home/vagrant/android-ndk",
:user => "vagrant"
}
}
chef.add_recipe "android-sdk"
chef.add_recipe "android-ndk"
chef.add_recipe "fdroidbuild-general"
end
end

View File

@ -0,0 +1,17 @@
ndk_loc = node[:settings][:ndk_loc]
script "setup-android-ndk" do
interpreter "bash"
user node[:settings][:user]
cwd "/tmp"
code "
wget http://dl.google.com/android/ndk/android-ndk-r7-linux-x86.tar.bz2
tar jxvf android-ndk-r7-linux-x86.tar.bz2
mv android-ndk-r7 #{ndk_loc}
"
not_if do
File.exists?("#{ndk_loc}")
end
end

View File

@ -0,0 +1,34 @@
%w{openjdk-6-jdk}.each do |pkg|
package pkg do
action :install
end
end
sdk_loc = node[:settings][:sdk_loc]
user = node[:settings][:user]
script "setup-android-sdk" do
interpreter "bash"
user user
cwd "/tmp"
code "
wget http://dl.google.com/android/android-sdk_r16-linux.tgz
tar zxvf android-sdk_r16-linux.tgz
mv android-sdk-linux #{sdk_loc}
rm android-sdk_r16-linux.tgz
#{sdk_loc}/tools/android update sdk --no-ui -t platform-tool
#{sdk_loc}/tools/android update sdk --no-ui -t platform
#{sdk_loc}/tools/android update sdk --no-ui -t tool,platform-tool
"
not_if do
File.exists?("#{sdk_loc}")
end
end
execute "add-android-sdk-path" do
user user
path = "#{sdk_loc}/tools:#{sdk_loc}/platform-tools"
command "echo \"export PATH=\\$PATH:#{path}\" >> /home/#{user}/.bashrc"
not_if "grep #{sdk_loc} /home/#{user}/.bashrc"
end

View File

@ -0,0 +1,7 @@
%w{ant ant-contrib maven2 javacc python}.each do |pkg|
package pkg do
action :install
end
end

23
buildserver/fixpaths.sh Normal file
View File

@ -0,0 +1,23 @@
#!/bin/sh
fixit()
{
#Fix sudoers so the PATH gets passed through, otherwise chef
#provisioning doesn't work.
if [ -z "$1" ]; then
export EDITOR=$0 && sudo -E visudo
else
echo "Fix sudoers"
echo "Defaults exempt_group=admin" >> $1
fi
#Stick the gems bin onto root's path as well.
sudo echo "PATH=$PATH:/var/lib/gems/1.8/bin" >>/root/.bashrc
# Restart sudo so it gets the changes straight away
sudo /etc/init.d/sudo restart
}
sudo grep "exempt_group" /etc/sudoers -q
if [ "$?" -eq "1" ]; then
fixit
fi

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# checkmarket2.py - part of the FDroid server tools
# checkupdates.py - part of the FDroid server tools
# Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com
#
# This program is free software: you can redistribute it and/or modify
@ -35,9 +35,14 @@ execfile('config.py')
# Returns (None, "a message") if this didn't work, or (version, vercode) for
# the details of the current version.
def check_market(app):
time.sleep(5)
time.sleep(10)
url = 'http://market.android.com/details?id=' + app['id']
page = urllib.urlopen(url).read()
req = urllib.urlopen(url)
if req.getcode() == 404:
return (None, 'Not in market')
elif req.getcode() != 200:
return (None, 'Return code ' + str(req.getcode()))
page = req.read()
version = None
vercode = None
@ -46,6 +51,9 @@ def check_market(app):
if m:
version = html_parser.unescape(m.group(1))
if version == 'Varies with device':
return (None, 'Device-variable version, cannot use this method')
m = re.search('data-paramValue="(\d+)"><div class="goog-menuitem-content">Latest Version<', page)
if m:
vercode = m.group(1)
@ -63,6 +71,8 @@ def check_market(app):
parser = OptionParser()
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")
(options, args) = parser.parse_args()
# Get all apps...
@ -72,28 +82,32 @@ html_parser = HTMLParser.HTMLParser()
for app in apps:
print "Processing " + app['id'] + '...'
mode = app['Update Check Mode']
if mode == 'Market':
(version, vercode) = check_market(app)
elif mode == 'None':
version = None
vercode = 'Checking disabled'
if options.package and options.package != app['id']:
# Silent skip...
pass
else:
version = None
vercode = 'Invalid update check method'
print "Processing " + app['id'] + '...'
if not version:
print "..." + vercode
elif vercode == app['Market Version Code'] and version == app['Market Version']:
print "...up to date"
else:
print '...updating to version:' + version + ' vercode:' + vercode
app['Market Version'] = version
app['Market Version Code'] = vercode
metafile = os.path.join('metadata', app['id'] + '.txt')
common.write_metadata(metafile, app)
mode = app['Update Check Mode']
if mode == 'Market':
(version, vercode) = check_market(app)
elif mode == 'None':
version = None
vercode = 'Checking disabled'
else:
version = None
vercode = 'Invalid update check method'
if not version:
print "..." + vercode
elif vercode == app['Current Version Code'] and version == app['Current Version']:
print "...up to date"
else:
print '...updating to version:' + version + ' vercode:' + vercode
app['Current Version'] = version
app['Current Version Code'] = vercode
metafile = os.path.join('metadata', app['id'] + '.txt')
common.write_metadata(metafile, app)
print "Finished."

279
common.py
View File

@ -30,9 +30,11 @@ def getvcs(vcstype, remote, local):
elif vcstype == 'git-svn':
return vcs_gitsvn(remote, local)
elif vcstype == 'hg':
return vcs_hg(remote,local)
return vcs_hg(remote, local)
elif vcstype == 'bzr':
return vcs_bzr(remote,local)
return vcs_bzr(remote, local)
elif vcstype == 'srclib':
return vcs_srclib(remote, local)
raise VCSException("Invalid vcs type " + vcstype)
class vcs:
@ -56,12 +58,15 @@ class vcs:
self.remote = remote
self.local = local
self.refreshed = False
self.srclib = None
# Take the local repository to a clean version of the given revision, which
# is specificed in the VCS's native format. Beforehand, the repository can
# be dirty, or even non-existent. If the repository does already exist
# locally, it will be updated from the origin, but only once in the
# lifetime of the vcs object.
# None is acceptable for 'rev' if you know you are cloning a clean copy of
# the repo - otherwise it must specify a valid revision.
def gotorevision(self, rev):
raise VCSException("This VCS type doesn't define gotorevision")
@ -69,6 +74,11 @@ class vcs:
def initsubmodules(self):
raise VCSException('Submodules not supported for this vcs type')
# Returns the srclib (name, path) used in setting up the current
# revision, or None.
def getsrclib(self):
return self.srclib
class vcs_git(vcs):
# If the local directory exists, but is somehow not a git repository, git
@ -95,19 +105,23 @@ class vcs_git(vcs):
raise VCSException("Git reset failed")
# Remove untracked files now, in case they're tracked in the target
# revision (it happens!)...
if subprocess.call(['git', 'clean', '-dfx'], cwd=self.local) != 0:
if subprocess.call(['git', 'clean', '-dffx'], cwd=self.local) != 0:
raise VCSException("Git clean failed")
if not self.refreshed:
# Get latest commits and tags from remote...
if subprocess.call(['git', 'fetch', 'origin'],
cwd=self.local) != 0:
raise VCSException("Git fetch failed")
if subprocess.call(['git', 'fetch', '--tags', 'origin'],
cwd=self.local) != 0:
raise VCSException("Git fetch failed")
self.refreshed = True
# Check out the appropriate revision...
if subprocess.call(['git', 'checkout', rev], cwd=self.local) != 0:
raise VCSException("Git checkout failed")
if rev:
if subprocess.call(['git', 'checkout', rev], cwd=self.local) != 0:
raise VCSException("Git checkout failed")
# Get rid of any uncontrolled files left behind...
if subprocess.call(['git', 'clean', '-dfx'], cwd=self.local) != 0:
if subprocess.call(['git', 'clean', '-dffx'], cwd=self.local) != 0:
raise VCSException("Git clean failed")
def initsubmodules(self):
@ -146,7 +160,7 @@ class vcs_gitsvn(vcs):
raise VCSException("Git reset failed")
# Remove untracked files now, in case they're tracked in the target
# revision (it happens!)...
if subprocess.call(['git', 'clean', '-dfx'], cwd=self.local) != 0:
if subprocess.call(['git', 'clean', '-dffx'], cwd=self.local) != 0:
raise VCSException("Git clean failed")
if not self.refreshed:
# Get new commits and tags from repo...
@ -154,17 +168,18 @@ class vcs_gitsvn(vcs):
cwd=self.local) != 0:
raise VCSException("Git svn rebase failed")
self.refreshed = True
# Figure out the git commit id corresponding to the svn revision...
p = subprocess.Popen(['git', 'svn', 'find-rev', 'r' + rev],
cwd=self.local, stdout=subprocess.PIPE)
rev = p.communicate()[0].rstrip()
if p.returncode != 0:
raise VCSException("Failed to get git treeish from svn rev")
# Check out the appropriate revision...
if subprocess.call(['git', 'checkout', rev], cwd=self.local) != 0:
raise VCSException("Git checkout failed")
if rev:
# Figure out the git commit id corresponding to the svn revision...
p = subprocess.Popen(['git', 'svn', 'find-rev', 'r' + rev],
cwd=self.local, stdout=subprocess.PIPE)
rev = p.communicate()[0].rstrip()
if p.returncode != 0:
raise VCSException("Failed to get git treeish from svn rev")
# Check out the appropriate revision...
if subprocess.call(['git', 'checkout', rev], cwd=self.local) != 0:
raise VCSException("Git checkout failed")
# Get rid of any uncontrolled files left behind...
if subprocess.call(['git', 'clean', '-dfx'], cwd=self.local) != 0:
if subprocess.call(['git', 'clean', '-dffx'], cwd=self.local) != 0:
raise VCSException("Git clean failed")
class vcs_svn(vcs):
@ -193,10 +208,11 @@ class vcs_svn(vcs):
self.userargs(), cwd=self.local) != 0:
raise VCSException("Svn update failed")
self.refreshed = True
revargs = ['-r', rev]
if subprocess.call(['svn', 'update', '--force'] + revargs +
self.userargs(), cwd=self.local) != 0:
raise VCSException("Svn update failed")
if rev:
revargs = ['-r', rev]
if subprocess.call(['svn', 'update', '--force'] + revargs +
self.userargs(), cwd=self.local) != 0:
raise VCSException("Svn update failed")
class vcs_hg(vcs):
@ -214,10 +230,11 @@ class vcs_hg(vcs):
cwd=self.local) != 0:
raise VCSException("Hg pull failed")
self.refreshed = True
revargs = [rev]
if subprocess.call(['hg', 'checkout', '-C'] + revargs,
cwd=self.local) != 0:
raise VCSException("Hg checkout failed")
if rev:
revargs = [rev]
if subprocess.call(['hg', 'checkout', '-C'] + revargs,
cwd=self.local) != 0:
raise VCSException("Hg checkout failed")
class vcs_bzr(vcs):
@ -235,10 +252,33 @@ class vcs_bzr(vcs):
cwd=self.local) != 0:
raise VCSException("Bzr update failed")
self.refreshed = True
revargs = ['-r', rev]
if subprocess.call(['bzr', 'revert'] + revargs,
cwd=self.local) != 0:
raise VCSException("Bzr revert failed")
if rev:
revargs = ['-r', rev]
if subprocess.call(['bzr', 'revert'] + revargs,
cwd=self.local) != 0:
raise VCSException("Bzr revert failed")
class vcs_srclib(vcs):
def gotorevision(self, rev):
# Yuk...
extlib_dir = 'build/extlib'
if os.path.exists(self.local):
shutil.rmtree(self.local)
if self.remote.find(':') != -1:
srclib, path = self.remote.split(':')
else:
srclib = self.remote
path = None
libdir = getsrclib(srclib + '@' + rev, extlib_dir)
self.srclib = (srclib, libdir)
if path:
libdir = os.path.join(libdir, path)
shutil.copytree(libdir, self.local)
return self.local
# Get the type expected for a given metadata field.
@ -257,7 +297,7 @@ def metafieldtype(name):
# Parse metadata for a single application.
#
# 'metafile' - the filename to read. The package id for the application comes
# from this filename.
# from this filename. Pass None to get a blank entry.
#
# Returns a dictionary containing all the details of the application. There are
# two major kinds of information in the dictionary. Keys beginning with capital
@ -302,12 +342,15 @@ def parse_metadata(metafile, **kw):
thisinfo['comments'].append((key, comment))
del curcomments[:]
if not isinstance(metafile, file):
metafile = open(metafile, "r")
thisinfo = {}
thisinfo['id'] = metafile.name[9:-4]
if kw.get("verbose", False):
print "Reading metadata for " + thisinfo['id']
if metafile:
if not isinstance(metafile, file):
metafile = open(metafile, "r")
thisinfo['id'] = metafile.name[9:-4]
if kw.get("verbose", False):
print "Reading metadata for " + thisinfo['id']
else:
thisinfo['id'] = None
# Defaults for fields that come from metadata...
thisinfo['Name'] = None
@ -322,8 +365,8 @@ def parse_metadata(metafile, **kw):
thisinfo['Disabled'] = None
thisinfo['AntiFeatures'] = None
thisinfo['Update Check Mode'] = 'Market'
thisinfo['Market Version'] = ''
thisinfo['Market Version Code'] = '0'
thisinfo['Current Version'] = ''
thisinfo['Current Version Code'] = '0'
thisinfo['Repo Type'] = ''
thisinfo['Repo'] = ''
thisinfo['Requires Root'] = False
@ -332,6 +375,9 @@ def parse_metadata(metafile, **kw):
thisinfo['builds'] = []
thisinfo['comments'] = []
if metafile is None:
return thisinfo
mode = 0
buildlines = []
curcomments = []
@ -350,6 +396,11 @@ def parse_metadata(metafile, **kw):
field = line[:index]
value = line[index+1:]
# Translate obsolete fields...
if field == 'Market Version':
field = 'Current Version'
if field == 'Market Version Code':
field = 'Current Version Code'
fieldtype = metafieldtype(field)
if fieldtype != 'build':
@ -466,13 +517,22 @@ def write_metadata(dest, app):
for build in app['builds']:
writecomments('build:' + build['version'])
mf.write('Build Version:')
mf.write('\\\n'.join(build['origlines']) + '\n')
if build.has_key('origlines'):
# Keeping the original formatting if we loaded it from a file...
mf.write('\\\n'.join(build['origlines']) + '\n')
else:
mf.write(build['version'] + ',' + build['vercode'] + ',' +
build['commit'])
for key,value in build.iteritems():
if key not in ['version', 'vercode', 'commit']:
mf.write(',' + key + '=' + value)
mf.write('\n')
if len(app['builds']) > 0:
mf.write('\n')
writefield('Update Check Mode')
if len(app['Market Version']) > 0:
writefield('Market Version')
writefield('Market Version Code')
if len(app['Current Version']) > 0:
writefield('Current Version')
writefield('Current Version Code')
mf.write('\n')
writecomments(None)
mf.close()
@ -532,18 +592,75 @@ class MetaDataException(Exception):
return repr(self.value)
# Get the specified source library.
# Returns the path to it.
# TODO: These are currently just hard-coded in this method. It will be a
# metadata-driven system eventually, but not yet.
def getsrclib(spec, extlib_dir):
name, ref = spec.split('@')
if name == 'GreenDroid':
sdir = os.path.join(extlib_dir, 'GreenDroid')
vcs = getvcs('git',
'https://github.com/cyrilmottier/GreenDroid.git', sdir)
vcs.gotorevision(ref)
return os.path.join(sdir, 'GreenDroid')
if name == 'ActionBarSherlock':
sdir = os.path.join(extlib_dir, 'ActionBarSherlock')
vcs = getvcs('git',
'https://github.com/JakeWharton/ActionBarSherlock.git', sdir)
vcs.gotorevision(ref)
libdir = os.path.join(sdir, 'library')
if subprocess.call(['android', 'update', 'project', '-p',
libdir]) != 0:
raise BuildException('Error updating ActionBarSherlock project')
return libdir
if name == 'FacebookSDK':
sdir = os.path.join(extlib_dir, 'FacebookSDK')
vcs = getvcs('git',
'git://github.com/facebook/facebook-android-sdk.git', sdir)
vcs.gotorevision(ref)
libdir = os.path.join(sdir, 'facebook')
if subprocess.call(['android', 'update', 'project', '-p',
libdir]) != 0:
raise BuildException('Error updating FacebookSDK project')
return libdir
if name == 'OI':
sdir = os.path.join(extlib_dir, 'OI')
vcs = getvcs('git-svn',
'http://openintents.googlecode.com/svn/trunk/', sdir)
vcs.gotorevision(ref)
return sdir
if name == 'JOpenDocument':
sdir = os.path.join(extlib_dir, 'JOpenDocument')
vcs = getvcs('git',
'https://github.com/andiwand/JOpenDocument.git', sdir)
vcs.gotorevision(ref)
shutil.rmtree(os.path.join(sdir, 'bin'))
return sdir
raise BuildException('Unknown srclib ' + name)
# Prepare the source code for a particular build
# 'vcs' - the appropriate vcs object for the application
# 'app' - the application details from the metadata
# 'build' - the build details from the metadata
# 'build_dir' - the path to the build directory
# 'build_dir' - the path to the build directory, usually
# 'build/app.id'
# 'extlib_dir' - the path to the external libraries directory, usually
# 'build/extlib'
# 'sdk_path' - the path to the Android SDK
# 'ndk_path' - the path to the Android NDK
# 'javacc_path' - the path to javacc
# 'refresh' - True to refresh from the remote repo
# Returns the root directory, which may be the same as 'build_dir' or may
# be a subdirectory of it.
def prepare_source(vcs, app, build, build_dir, sdk_path, ndk_path, javacc_path, refresh):
def prepare_source(vcs, app, build, build_dir, extlib_dir, sdk_path, ndk_path, javacc_path, refresh):
# Optionally, the actual app source can be in a subdirectory...
if build.has_key('subdir'):
@ -564,6 +681,12 @@ def prepare_source(vcs, app, build, build_dir, sdk_path, ndk_path, javacc_path,
if build.get('submodules', 'no') == 'yes':
vcs.initsubmodules()
# Run an init command if one is required...
if build.has_key('init'):
init = build['init']
if subprocess.call(init, cwd=root_dir, shell=True) != 0:
raise BuildException("Error running init command")
# Generate (or update) the ant build file, build.xml...
if (build.get('update', 'yes') == 'yes' and
not build.has_key('maven')):
@ -579,6 +702,7 @@ def prepare_source(vcs, app, build, build_dir, sdk_path, ndk_path, javacc_path,
# the original behaviour...
buildxml = os.path.join(root_dir, 'build.xml')
if os.path.exists(buildxml):
print 'Force-removing old build.xml'
os.remove(buildxml)
if subprocess.call(parms, cwd=root_dir) != 0:
raise BuildException("Failed to update project")
@ -680,10 +804,35 @@ def prepare_source(vcs, app, build, build_dir, sdk_path, ndk_path, javacc_path,
f.writelines(outlines)
f.close()
# Add required external libraries...
if build.has_key('extlibs'):
libsdir = os.path.join(root_dir, 'libs')
if not os.path.exists(libsdir):
os.mkdir(libsdir)
for lib in build['extlibs'].split(';'):
libf = os.path.basename(lib)
shutil.copyfile(os.path.join(extlib_dir, lib),
os.path.join(libsdir, libf))
# Get required source libraries...
srclibpaths = []
if build.has_key('srclibs'):
for lib in build['srclibs'].split(';'):
name, _ = lib.split('@')
srclibpaths.append((name, getsrclib(lib, extlib_dir)))
basesrclib = vcs.getsrclib()
# If one was used for the main source, add that too.
if basesrclib:
srclibpaths.append(basesrclib)
# Run a pre-build command if one is required...
if build.has_key('prebuild'):
if subprocess.call(build['prebuild'],
cwd=root_dir, shell=True) != 0:
prebuild = build['prebuild']
# Substitute source library paths into prebuild commands...
for name, libpath in srclibpaths:
libpath = os.path.relpath(libpath, root_dir)
prebuild = prebuild.replace('$$' + name + '$$', libpath)
if subprocess.call(prebuild, cwd=root_dir, shell=True) != 0:
raise BuildException("Error running pre-build command")
# Apply patches if any
@ -778,6 +927,45 @@ def prepare_source(vcs, app, build, build_dir, sdk_path, ndk_path, javacc_path,
return root_dir
# Scan the source code in the given directory (and all subdirectories)
# and return a list of potential problems.
def scan_source(build_dir, root_dir, thisbuild):
problems = []
# Scan for common known non-free blobs:
usual_suspects = ['flurryagent',
'paypal_mpl',
'libgoogleanalytics',
'admob-sdk-android',
'googleadview',
'googleadmobadssdk']
for r,d,f in os.walk(build_dir):
for curfile in f:
for suspect in usual_suspects:
if curfile.lower().find(suspect) != -1:
msg = 'Found probable non-free blob ' + os.path.join(r, curfile)
problems.append(msg)
# Presence of a jni directory without buildjni=yes might
# indicate a problem...
if (os.path.exists(os.path.join(root_dir, 'jni')) and
thisbuild.get('buildjni', 'no') != 'yes'):
msg = 'Found jni directory, but buildjni is not enabled'
problems.append(msg)
# Presence of these is not a problem as such, but they
# shouldn't be there and mess up our source tarballs...
if os.path.exists(os.path.join(root_dir, 'bin')):
msg = "There shouldn't be a bin directory"
problems.append(msg)
if os.path.exists(os.path.join(root_dir, 'gen')):
msg = "There shouldn't be a gen directory"
problems.append(msg)
return problems
class KnownApks:
def __init__(self):
@ -832,5 +1020,6 @@ class KnownApks:
lst = []
for app, added in sortedapps:
lst.append(app)
lst.reverse()
return lst

4
config.buildserver.py Normal file
View File

@ -0,0 +1,4 @@
aapt_path = "/home/vagrant/android-sdk/platform-tools/aapt"
sdk_path = "/home/vagrant/android-sdk"
ndk_path = "/home/vagrant/android-ndk"
javacc_path = "/usr/share/java"

View File

@ -39,9 +39,4 @@ keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"
keyaliases = {}
keyaliases['com.example.app'] = 'example'
#For the market checker, which is used only to determine a 'current' version
#that the developer recommends, for those apps that are there.
market_user = ""
market_password = ""
market_deviceid = ""

243
import.py Executable file
View File

@ -0,0 +1,243 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# import.py - part of the FDroid server tools
# Copyright (C) 2010-12, Ciaran Gultnieks, ciaran@ciarang.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import os
import shutil
import subprocess
import re
import urllib
from optparse import OptionParser
#Read configuration...
repo_name = None
repo_description = None
repo_icon = None
repo_url = None
execfile('config.py')
import common
# Parse command line...
parser = OptionParser()
parser.add_option("-u", "--url", default=None,
help="Project URL to import from.")
parser.add_option("-s", "--subdir", default=None,
help="Path to main android project subdirectory, if not in root.")
(options, args) = parser.parse_args()
if not options.url:
print "Specify project url."
sys.exit(1)
url = options.url
tmp_dir = 'tmp'
if not os.path.isdir(tmp_dir):
print "Creating temporary directory"
os.makedirs(tmp_dir)
# Get all apps...
apps = common.read_metadata()
# Figure out what kind of project it is...
projecttype = None
issuetracker = None
license = None
if url.startswith('https://github.com'):
projecttype = 'github'
repo = url + '.git'
repotype = 'git'
sourcecode = url
elif url.startswith('http://code.google.com/p/'):
if not url.endswith('/'):
print "Expected format for googlecode url is http://code.google.com/p/PROJECT/"
sys.exit(1)
projecttype = 'googlecode'
sourcecode = url + 'source/checkout'
issuetracker = url + 'issues/list'
# Figure out the repo type and adddress...
req = urllib.urlopen(sourcecode)
if req.getcode() != 200:
print 'Unable to find source at ' + sourcecode + ' - return code ' + str(req.getcode())
sys.exit(1)
page = req.read()
repotype = None
index = page.find('hg clone')
if index != -1:
repotype = 'hg'
repo = page[index + 9:]
index = repo.find('<')
if index == -1:
print "Error while getting repo address"
sys.exit(1)
repo = repo[:index]
if not repotype:
index=page.find('git clone')
if index != -1:
repotype = 'git'
repo = page[index + 10:]
index = repo.find('<')
if index == -1:
print "Error while getting repo address"
sys.exit(1)
repo = repo[:index]
if not repotype:
index=page.find('svn checkout')
if index != -1:
repotype = 'git-svn'
repo = page[index + 13:]
prefix = '<strong><em>http</em></strong>'
if not repo.startswith(prefix):
print "Unexpected checkout instructions format"
sys.exit(1)
repo = 'http' + repo[len(prefix):]
index = repo.find('<')
if index == -1:
print "Error while getting repo address - no end tag? '" + repo + "'"
sys.exit(1)
repo = repo[:index]
index = repo.find(' ')
if index == -1:
print "Error while getting repo address - no space? '" + repo + "'"
sys.exit(1)
repo = repo[:index]
if not repotype:
print "Unable to determine vcs type"
sys.exit(1)
# Figure out the license...
req = urllib.urlopen(url)
if req.getcode() != 200:
print 'Unable to find project page at ' + sourcecode + ' - return code ' + str(req.getcode())
sys.exit(1)
page = req.read()
index = page.find('Code license')
if index == -1:
print "Couldn't find license data"
sys.exit(1)
ltext = page[index:]
lprefix = 'rel="nofollow">'
index = ltext.find(lprefix)
if index == -1:
print "Couldn't find license text"
sys.exit(1)
ltext = ltext[index + len(lprefix):]
index = ltext.find('<')
if index == -1:
print "License text not formatted as expected"
sys.exit(1)
ltext = ltext[:index]
if ltext == 'GNU GPL v3':
license = 'GPLv3'
elif ltext == 'GNU GPL v2':
license = 'GPLv2'
elif ltext == 'Apache License 2.0':
license = 'Apache2'
else:
print "License " + ltext + " is not recognised"
sys.exit(1)
if not projecttype:
print "Unable to determine the project type."
sys.exit(1)
# Get a copy of the source so we can extract some info...
print 'Getting source from ' + repotype + ' repo at ' + repo
src_dir = os.path.join(tmp_dir, 'importer')
if os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
vcs = common.getvcs(repotype, repo, src_dir)
vcs.gotorevision(None)
if options.subdir:
root_dir = os.path.join(src_dir, options.subdir)
else:
root_dir = src_dir
# Check AndroidManiifest.xml exists...
manifest = os.path.join(root_dir, 'AndroidManifest.xml')
if not os.path.exists(manifest):
print "AndroidManifest.xml did not exist in the expected location. Specify --subdir?"
sys.exit(1)
# Extract some information...
vcsearch = re.compile(r'.*android:versionCode="([^"]+)".*').search
vnsearch = re.compile(r'.*android:versionName="([^"]+)".*').search
psearch = re.compile(r'.*package="([^"]+)".*').search
version = None
vercode = None
package = None
for line in file(manifest):
if not package:
matches = psearch(line)
if matches:
package = matches.group(1)
if not version:
matches = vnsearch(line)
if matches:
version = matches.group(1)
if not vercode:
matches = vcsearch(line)
if matches:
vercode = matches.group(1)
if not package:
print "Couldn't find package ID"
sys.exit(1)
if not version:
print "Couldn't find latest version name"
sys.exit(1)
if not vercode:
print "Couldn't find latest version code"
sys.exit(1)
# Make sure it's actually new...
for app in apps:
if app['id'] == package:
print "Package " + package + " already exists"
sys.exit(1)
# Construct the metadata...
app = common.parse_metadata(None)
app['id'] = package
app['Web Site'] = url
app['Source Code'] = sourcecode
if issuetracker:
app['Issue Tracker'] = issuetracker
if license:
app['License'] = license
app['Repo Type'] = repotype
app['Repo'] = repo
# Create a build line...
build = {}
build['version'] = version
build['vercode'] = vercode
build['commit'] = '?'
if options.subdir:
build['subdir'] = options.subdir
if os.path.exists(os.path.join(root_dir, 'jni')):
build['buildjni'] = 'yes'
app['builds'].append(build)
app['comments'].append(('build:' + version,
"#Generated by import.py - check this is the right version, and find the right commit!"))
metafile = os.path.join('metadata', package + '.txt')
common.write_metadata(metafile, app)
print "Wrote " + metafile

View File

@ -15,3 +15,5 @@ Repo:http://anstop.googlecode.com/svn/trunk
Build Version:1.4,9,34
Update Check Mode:None

View File

@ -14,8 +14,9 @@ Repo Type:git
Repo:git://github.com/aarddict/android.git
Build Version:1.3.1,10,1.3.1,prebuild=mv lib libs
Build Version:1.4.0,12,7df930161256324e31b2c720281629f58446b6d6,prebuild=mv lib libs
Update Check Mode:Market
Market Version:1.3.1
Market Version Code:10
Current Version:1.4.0
Current Version Code:12

View File

@ -14,6 +14,7 @@ Repo:http://android-vnc-viewer.googlecode.com/svn/branches/antlersoft
Build Version:0.5.0,13,197,subdir=androidVNC
Market Version:0.5.0
Market Version Code:13
Update Check Mode:Market
Current Version:0.5.0
Current Version Code:13

View File

@ -14,13 +14,12 @@ It is extremely customizable with many options to suit your needs and style.
Repo Type:svn
Repo:http://droid-notify.googlecode.com/svn/trunk
Build Version:2.20,27,707,patch=facebook.patch,prebuild=mv lib/ libs/ \
&& git clone git://github.com/facebook/facebook-android-sdk.git \
&& cp facebook-android-sdk/facebook/default.properties facebook-android-sdk/facebook/project.properties \
&& cp build.xml facebook-android-sdk/facebook/ \
&& cp local.properties facebook-android-sdk/facebook/
Build Version:2.20,27,707,srclibs=FacebookSDK@c58af0b,prebuild=sed -i 's@\(android.library.reference.1=\).*@\1$$FacebookSDK$$@' project.properties && mv lib/ libs/
Build Version:2.22,29,759,srclibs=FacebookSDK@c58af0b,prebuild=sed -i 's@\(android.library.reference.1=\).*@\1$$FacebookSDK$$@' project.properties && mv lib/ libs/
Build Version:2.23,30,760,encoding=utf-8,srclibs=FacebookSDK@c58af0b,prebuild=sed -i 's@\(android.library.reference.1=\).*@\1$$FacebookSDK$$@' project.properties && mv lib/ libs/
Build Version:2.24,31,781,encoding=utf-8,srclibs=FacebookSDK@c58af0b,prebuild=sed -i 's@\(android.library.reference.1=\).*@\1$$FacebookSDK$$@' project.properties && mv lib/ libs/ && rm -rf gen/ && rm -rf bin/
Update Check Mode:Market
Market Version:2.21
Market Version Code:28
Current Version:2.24
Current Version Code:31

View File

@ -1,10 +0,0 @@
Index: project.properties
===================================================================
--- a/project.properties (revision 707)
+++ b/project.properties (working copy)
@@ -9,4 +9,4 @@
# Project target.
target=android-8
-android.library.reference.1=../com_facebook_android
+android.library.reference.1=facebook-android-sdk/facebook

View File

@ -0,0 +1,20 @@
Category:Office
License:Apache2
Web Site:http://code.google.com/p/arity-calculator/
Source Code:http://code.google.com/p/arity-calculator/source/checkout
Issue Tracker:http://code.google.com/p/arity-calculator/issues/list
Summary:Scientific Calculator
Description:
Scientific calculator with complex numbers and graphing of user-defined functions.
.
Repo Type:hg
Repo:https://code.google.com/p/arity-calculator/
Build Version:1.27,27,ad8847de5df0,target=android-8
Update Check Mode:Market
Current Version:1.27
Current Version Code:27

View File

@ -10,6 +10,7 @@ Description:
Generative art (pretty pictures of mathematical origin).
.
Market Version:3.15
Market Version Code:25
Update Check Mode:Market
Current Version:3.15
Current Version Code:25

View File

@ -15,6 +15,7 @@ Repo:http://ical-import-export.googlecode.com/svn/trunk/
Build Version:1.5,51,!11 but needs AndroidTools compiling too,subdir=iCalImportExport,target=android-10
Market Version:1.5
Market Version Code:51
Update Check Mode:Market
Current Version:1.5
Current Version Code:51

View File

@ -1,9 +1,10 @@
Disabled:Sends device info and other data to a web server without permission
Category:None
AntiFeatures:Tracking
Category:Office
License:GPLv3+
Web Site:http://tomtasche.at/p/OpenOffice%20Document%20Reader
Source Code:https://github.com/TomTasche/OpenOffice-Document-Reader
Issue Tracker:https://github.com/TomTasche/OpenOffice-Document-Reader/issues
Source Code:https://github.com/TomTasche/OpenDocument.droid
Issue Tracker:https://github.com/TomTasche/OpenDocument.droid/issues
Donate:https://flattr.com/thing/117140/OpenOffice-Document-Reader
Summary:Open Office document reader.
Description:
@ -11,12 +12,15 @@ Open Office document reader.
.
Repo Type:git
Repo:https://github.com/TomTasche/OpenOffice-Document-Reader.git
Repo:https://github.com/TomTasche/OpenDocument.droid.git
Build Version:1.1.9,11,243eba4f441b3601de96
Build Version:1.2,12,d174bed05a6026ddb5db
Build Version:1.2.3,15,8fe022fd67e5bb62c6d8
Build Version:1.3.0,22,4b8ea7438125e90d43bdadfc042723a7a485a217,srclibs=JOpenDocument@35ec3d3ddfc11592cefe8cae9eea3608ad2b30c2,prebuild=rm *.apk && rm -rf bin/ && rm -rf gen/ && cp -r $$JOpenDocument$$/src/* src/ && rm -rf src/test/
Build Version:1.3.2,24,4bcf9024ac9fb96bc5c03c3129f9d401272caaf0,srclibs=JOpenDocument@35ec3d3ddfc11592cefe8cae9eea3608ad2b30c2,prebuild=rm *.apk && rm -rf bin/ && rm -rf gen/ && rm libs/jopendocument.jar && cp -r $$JOpenDocument$$/src/* src/ && rm -rf src/test/
Market Version:1.3.0
Market Version Code:22
Update Check Mode:Market
Current Version:1.3.0
Current Version Code:22

View File

@ -17,6 +17,7 @@ Repo:http://trolly.googlecode.com/svn/trunk
# It needs a file from OpenIntents, so let's get it from Subversion...
Build Version:1.4,6,40,target=android-4,prebuild=mkdir -p src/org/openintents/intents && svn cat -r 3070 http://openintents.googlecode.com/svn/trunk/shoppinglist/ShoppingList/src/org/openintents/intents/ShoppingListIntents.java >src/org/openintents/intents/ShoppingListIntents.java
Market Version:1.4
Market Version Code:6
Update Check Mode:Market
Current Version:1.4
Current Version Code:6

View File

@ -14,7 +14,8 @@ based on Aptoide!
Repo Type:svn
Repo:http://aptoide.org/repo
Market Version:2.0.1
Market Version Code:145
Update Check Mode:Market
Current Version:2.0.1
Current Version Code:145
#Build Version:2.0,126,45,subdir=aptoide-client/v2.0

View File

@ -17,6 +17,7 @@ Repo:http://cyanogen-updater.googlecode.com/svn/trunk/
Build Version:5.0.1,501,626
Market Version:5.0.1
Market Version Code:501
Update Check Mode:None
Current Version:5.0.1
Current Version Code:501

View File

@ -17,6 +17,7 @@ Repo:http://androidpermissions.googlecode.com/svn/trunk
Build Version:1.1,2,16
Market Version:1.1
Market Version Code:2
Update Check Mode:Market
Current Version:1.1
Current Version Code:2

View File

@ -2,6 +2,8 @@ Category:Office
License:Apache2
Web Site:
Source Code:https://github.com/pakerfeldt/aGiro
# The closest thing to a web site or issue tracker is this thread:
# http://www.swedroid.se/forum/showthread.php?t=16305
Issue Tracker:
Summary:OCR scanner for Swedish bills
@ -16,8 +18,5 @@ Repo:https://github.com/pakerfeldt/aGiro.git
Build Version:alpha 2,2,!repo moved and renamed 20bd0f021dd852afcc9aa9008ee713419ae8e05c
#Use Built:Yes
# The closest thing to a web site or issue tracker is this thread:
# http://www.swedroid.se/forum/showthread.php?t=16305
#Web Site:
#Issue Tracker:
Update Check Mode:None

View File

@ -10,6 +10,7 @@ Mandelbrot set viewer that works in the style of a map viewer - i.e. scroll arou
and zoom in/out.
.
Market Version:0.13
Market Version Code:13
Update Check Mode:Market
Current Version:0.13
Current Version Code:13

View File

@ -22,6 +22,7 @@ Build Version:1.09.05,10905,fc40dccbb9,subdir=Timeriffic,oldsdkloc=yes,novcheck=
Build Version:1.09.11,10911,!Can't find correct commit. See metadata notes too.
Build Version:1.09.12,10912,!No source for this in the repo
Market Version:1.09.12
Market Version Code:10912
Update Check Mode:Market
Current Version:1.09.12
Current Version Code:10912

View File

@ -24,6 +24,6 @@ Build Version:1.2.1.5,78,!more dependency shuffling required and watch out for t
Build Version:1.3.0,83,v1.3.0,target=android-11,prebuild=mkdir lib && mv libs-dependencies/* lib && rm -r libs-dependencies && mv libs/* lib && rm -r libs && git checkout proguard.cfg
Update Check Mode:Market
Market Version:1.3.0
Market Version Code:83
Current Version:1.3.0
Current Version Code:83

View File

@ -17,6 +17,7 @@ Repo:http://scandinavian-keyboard.googlecode.com/svn/trunk
Build Version:1.4.4,13,15,target=android-4
Build Version:1.4.6,15,17,target=android-4
Market Version:1.4.6
Market Version Code:15
Update Check Mode:Market
Current Version:1.4.6
Current Version Code:15

View File

@ -21,8 +21,9 @@ Build Version:1.9.3.1,80,v1.9.3.1
Build Version:1.9.5,82,v1.9.5
Build Version:1.9.6,83,v1.9.6
Build Version:1.9.7,84,v1.9.7,target=android-8
Build Version:1.9.8,85,v1.9.8,target=android-8
Update Check Mode:Market
Market Version:1.9.7
Market Version Code:84
Current Version:1.9.8
Current Version Code:85

View File

@ -14,6 +14,7 @@ Repo:http://kraigsandroid.googlecode.com/svn/tags/
Build Version:1.7,8,378
Market Version:1.7
Market Version Code:8
Update Check Mode:Market
Current Version:1.7
Current Version Code:8

View File

@ -0,0 +1,24 @@
Category:Games
License:GPLv3
Web Site:http://code.google.com/p/mahjonggbuilder/
Source Code:http://code.google.com/p/mahjonggbuilder/source/checkout
Issue Tracker:http://code.google.com/p/mahjonggbuilder/issues/list
Summary:Solitaire games
Description:
A collection of 19 solitaire games where the object is to remove all pieces
from the game board by finding matching pairs of images from the both ends of
lines of pieces.
The built-in layout editor allows creation of new game layouts.
.
Repo Type:git-svn
Repo:http://mahjonggbuilder.googlecode.com/svn/trunk/
Build Version:1.4.4,14,15,subdir=Android
Update Check Mode:Market
Current Version:1.4.4
Current Version Code:14

View File

@ -20,6 +20,7 @@ Repo:http://contactowner.googlecode.com/svn/branches/v2next/
Build Version:2.2,12,44,target=android-4
Market Version:2.2
Market Version Code:22
Update Check Mode:Market
Current Version:2.2
Current Version Code:22

20
metadata/com.ath0.rpn.txt Normal file
View File

@ -0,0 +1,20 @@
Category:Office
License:GPLv3+
Web Site:http://meta.ath0.com/software/rpn/
Source Code:https://github.com/lpar/RPN
Issue Tracker:https://github.com/lpar/RPN/issues
Summary:RPN Calculator
Description:
Simple fixed-point decimal arithmetic, Reverse Polish Notation calculator.
.
Repo Type:git
Repo:https://github.com/lpar/RPN.git
Build Version:1.8.1,10,199a87f7319b685e59d6847f1ff2417613f69c6e
Update Check Mode:Market
Current Version:1.8
Current Version Code:9

View File

@ -25,6 +25,6 @@ Repo:git://github.com/thasmin/Podax.git
Build Version:2.11,12,13d0e30198d96b4cd7b1a87065a1b8cf3ed578f4,target=android-7
Update Check Mode:Market
Market Version:2.11
Market Version Code:12
Current Version:2.11
Current Version Code:12

View File

@ -15,8 +15,9 @@ Repo:http://www.beem-project.com/hg/trunk/
Build Version:0.1.5,7,0.1.5
Build Version:0.1.6,9,0.1.6
Build Version:0.1.7_rc1,10,0.1.7_rc1,target=android-8
Build Version:0.1.7_rc2,11,0.1.7_rc2,target=android-8
Update Check Mode:Market
Market Version:0.1.7_rc1
Market Version Code:10
Current Version:0.1.7_rc2
Current Version Code:11

View File

@ -16,6 +16,7 @@ Repo:http://boardgamegeek.googlecode.com/svn/trunk/
Build Version:3.3,20,r416,subdir=BoardGameGeek,target=android-8
Build Version:3.4,21,r525,subdir=BoardGameGeek,target=android-8
Market Version:3.4
Market Version Code:21
Update Check Mode:Market
Current Version:3.4
Current Version Code:21

View File

@ -18,8 +18,9 @@ Features:
Repo Type:svn
Repo:https://daily-money.googlecode.com/svn/trunk/
Market Version:0.9.7-0702-freshly
Market Version Code:2011070200
Update Check Mode:Market
Current Version:0.9.7-0702-freshly
Current Version Code:2011070200
# Does not build yet
#Build Version:0.9.7-0702-freshly,2011070200,218,subdir=dailymoney-surface/,target=android-7,prebuild=\

View File

@ -18,6 +18,7 @@ Build Version:1.9.8 p2,201012060,184,target=android-8
Build Version:1.9.9.2,201106160,213,target=android-8
Build Version:1.9.9.3,201107260,220,target=android-8
Market Version:1.9.9.5
Market Version Code:201110061
Update Check Mode:Market
Current Version:1.9.9.5
Current Version Code:201110061

View File

@ -14,6 +14,7 @@ Repo:http://quick-settings.googlecode.com/svn/trunk/quick-battery/
Build Version:0.8.2,201010020,153,target=android-8
Market Version:0.8.2
Market Version Code:201010020
Update Check Mode:Market
Current Version:0.8.2
Current Version Code:201010020

View File

@ -15,6 +15,7 @@ Repo:https://code.google.com/p/simplechessclock/
Build Version:1.2.0,8,379155447bff,subdir=simplechessclock,target=android-8
Market Version:1.2.0
Market Version Code:8
Update Check Mode:Market
Current Version:1.2.0
Current Version Code:8

View File

@ -0,0 +1,27 @@
Category:Office
License:GPLv3
Web Site:http://projects.ciarang.com/p/tallyphant/
Source Code:http://projects.ciarang.com/p/tallyphant/source/tree/master/
Issue Tracker:http://projects.ciarang.com/p/tallyphant/issues/
Donate:http://projects.ciarang.com/p/tallyphant/page/Donate/
Summary:Counter
Description:
A simple counting application. Count any number of items simultanously,
either up or down. Can be set to vibrate, beep or speak when the values
change.
Live data can also be send via UDP to a networked computer, and results
can be shared via email, etc.
.
Repo Type:git
Repo:git://git.ciarang.com/tallyphant.git
Build Version:0.1,2,065a77a8d508746c6838b6892f68d7b35ac10608
Build Version:0.2,3,38c8d82a1b19c7313aea5cdaae9f93a95fcaac32
Build Version:0.3,4,cbe9aa47adb5ac24244b4e80484fee3eb356cf8b
Build Version:0.4,5,f207fbd7d2d7a682ba71c4fa7c446cc636401cba
Update Check Mode:None

View File

@ -21,6 +21,7 @@ Build Version:2.0.16,102,!No source in repo,target=android-11
#https://answers.launchpad.net/arxivdroid/+question/173825
Build Version:2.0.20,106,!No source in repo
Market Version:2.0.20
Market Version Code:106
Update Check Mode:Market
Current Version:2.0.20
Current Version Code:106

View File

@ -10,8 +10,9 @@ Description:
A SIP (VOIP) client.
.
Update Check Mode:Market
#Note : build needs a customised ndk, as described at:
# http://code.google.com/p/csipsimple/wiki/HowToBuild
Market Version:0.03-01
Market Version Code:1108
Current Version:0.03-01
Current Version Code:1108

View File

@ -19,6 +19,7 @@ prebuild=sed -r -i \
AndroidManifest.xml,\
oldsdkloc=yes,target=android-4
Market Version:0.5
Market Version Code:5
Update Check Mode:None
Current Version:0.5
Current Version Code:5

View File

@ -13,7 +13,8 @@ An RSS feed reader and podcatcher with audio and video support.
Repo Type:git
Repo:http://git.gitorious.org/feeddroid/feeddroid.git
Update Check Mode:None
#Build Version:1.1.1,37,db5077bf1ef792d8d5f6154198b7200a50d963df,subdir=FeedDroid
Market Version:1.1.1
Market Version Code:37
Current Version:1.1.1
Current Version Code:37

View File

@ -12,9 +12,10 @@ It provides a graphical compass card along with text bearing information.
Repo Type:git
Repo:git://github.com/okey666/NiceCompass.git
Update Check Mode:Market
Market Version:1.3
Market Version Code:6
Build Version:1.3,6,b6f322cf10ec4320ca5b4111f75dccfdd4b6f7f0,target=android-13,srclibs=ActionBarSherlock@3.5.1,prebuild=\
sed -i 's@\(android.library.reference.1=\).*@\1$$ActionBarSherlock$$@' project.properties
Update Check Mode:Market
Current Version:1.3
Current Version Code:6
# uses ActionBarSherlock library which is not included
#Build Version:1.3,6,b6f322cf10ec4320ca5b4111f75dccfdd4b6f7f0

View File

@ -14,7 +14,9 @@ Repo:https://github.com/dozingcat/Vector-Pinball.git
Build Version:1.1,4,45b5218594320ffb4b37
Build Version:1.3,10,1210949b1e373916d096
Build Version:1.3.1,11,!No corresponding source
Market Version:1.3.1
Market Version Code:11
Update Check Mode:Market
Current Version:1.3.1
Current Version Code:11

View File

@ -14,7 +14,8 @@ A Tux Racer clone.
Repo Type:git
Repo:git://github.com/drodin/TuxRider.git
Update Check Mode:Market
#Build Version:1.0.4 beta,6,67bce39cda321c225bc5
Market Version:1.0.9
Market Version Code:11
Current Version:1.0.9
Current Version Code:11

View File

@ -13,8 +13,9 @@ A calendar application.
Repo Type:hg
Repo:https://bitbucket.org/giszmo/offline-calendar
Update Check Mode:Market
#There don't seem to be any developer releases yet
#There is now a 1.1 in the android market, but no source for it in the repository
Market Version:1.1
Market Version Code:2
Current Version:1.1
Current Version Code:2

View File

@ -15,3 +15,5 @@ Repo:https://anetmon.svn.sourceforge.net/svnroot/anetmon/
Build Version:0.2-beta,2,17
Update Check Mode:None

View File

@ -27,6 +27,7 @@ Build Version:3.7,68,514799b45d18cf6dbc42065adf08abbdc9e2f16f,target=android-10
Build Version:3.8,69,bb85065cb6045df773cd681ac8bad55a6818d48a,target=android-10
Build Version:3.8.1,70,890b6affe8a64,target=android-10
Market Version:3.8.1
Market Version Code:70
Update Check Mode:Market
Current Version:3.8.1
Current Version Code:70

View File

@ -15,6 +15,7 @@ Repo:https://github.com/ghackett/AppAlarm
Build Version:1.2.6,30,af9d89993212c67bfc510ed082381afc7abcd95a
Market Version:1.2.6
Market Version Code:30
Update Check Mode:Market
Current Version:1.2.6
Current Version Code:30

View File

@ -19,6 +19,7 @@ Repo:https://code.google.com/p/android-mileage/
#Build Version:3.0.0,3000,0766c4f352a5,subdir=trunk,oldsdkloc=yes
Build Version:3.0.8,3080,16b397029a76,subdir=trunk,oldsdkloc=yes
Market Version:3.0.8
Market Version Code:3080
Update Check Mode:Market
Current Version:3.0.8
Current Version Code:3080

View File

@ -18,3 +18,5 @@ Build Version:1.0.2,35,35,\
prebuild=sed -i -r 's/(android:versionName)/android:versionCode="35" \1/' \
AndroidManifest.xml
Update Check Mode:None

View File

@ -1,4 +1,4 @@
Disabled: Doesn't built at the moment.
Disabled: Doesn't build at the moment.
Category:Office
License:GPLv3
Web Site:https://launchpad.net/weightchart
@ -16,3 +16,5 @@ Repo:lp:weightchart
Build Version:1,1,1,target=8
Update Check Mode:None

View File

@ -16,6 +16,6 @@ Repo:https://github.com/k9mail/k-9.git
#Note - k9 is currently developer's binary only
#Build Version:3.906,14006,3.906,oldsdkloc=yes,patch=target9to10.patch,target=android-10
Update Check Mode:Market
Market Version:4.003
Market Version Code:14021
Current Version:4.005
Current Version Code:14023

View File

@ -25,6 +25,6 @@ Update Check Mode:Market
#Source is now accessible, but the build is failing without an obvious error.
#Need to look at this again.
#Build Version:10.0.7,17,2671,subdir=tags/10.0.7,update=no,initfun=yes
Market Version:10.0.8
Market Version Code:18
Current Version:10.0.8
Current Version Code:18

View File

@ -26,7 +26,12 @@ Build Version:1.35,94,131,\
prebuild=sed -ri 's/(debuggable)="true"/\1="false"/' AndroidManifest.xml
Build Version:1.36.4,110,161,\
prebuild=sed -ri 's/(debuggable)="true"/\1="false"/' AndroidManifest.xml
Build Version:1.40,160,302,\
prebuild=sed -ri 's/(debuggable)="true"/\1="false"/' AndroidManifest.xml
Build Version:1.40.1,163,307
Build Version:1.40.2,164,314,prebuild=rm -rf gen/
Market Version:1.39.3
Market Version Code:154
Update Check Mode:Market
Current Version:1.40.2
Current Version Code:164

View File

@ -10,6 +10,7 @@ Description:
No description available
.
Market Version:0.4
Market Version Code:5
Update Check Mode:Market
Current Version:0.4
Current Version Code:5

View File

@ -21,6 +21,7 @@ Build Version:3.0alpha3,3005,!no source in repo,prebuild=mkdir libs && cp extra/
Build Version:3.1,3010,68,prebuild=mkdir libs && cp extra/system.jar libs/
Build Version:3.2,3020,69,prebuild=mkdir libs && cp extra/system.jar libs/
Market Version:3.2
Market Version Code:3020
Update Check Mode:Market
Current Version:3.2
Current Version Code:3020

View File

@ -17,9 +17,10 @@ Repo:https://mytracks.googlecode.com/hg/
Build Version:1.1.0,23,a86a640f2d,subdir=MyTracks
Build Version:1.1.3,26,!Doesn't build - needs dependencies building now I think
Update Check Mode:Market
#Build Version:1.1.3,26,62821d45032d,subdir=MyTracks,target=android-10,encoding=utf-8
#Still doesn't build...
#Build Version:1.1.9,22,v1.1.9,subdir=MyTracks,encoding=utf-8,target=android-13
Market Version:1.1.13
Market Version Code:36
Current Version:1.1.13
Current Version Code:36

View File

@ -17,6 +17,6 @@ Repo:http://stardroid.googlecode.com/svn/trunk/app
Build Version:1.6.4,1112,3
Update Check Mode:Market
Market Version:1.6.4
Market Version Code:1112
Current Version:1.6.4
Current Version Code:1112

View File

@ -21,6 +21,7 @@ Build Version:1.5.16,164,187,subdir=AppsOrganizer
Build Version:1.5.18,166,190,subdir=AppsOrganizer
Build Version:1.5.19,167,191,subdir=AppsOrganizer,target=android-10
Market Version:1.5.19
Market Version Code:167
Update Check Mode:Market
Current Version:1.5.19
Current Version Code:167

View File

@ -9,6 +9,7 @@ Description:
Barcode scanner from ZXing.
.
Market Version:3.72
Market Version Code:76
Update Check Mode:None
Current Version:4.0
Current Version Code:79

View File

@ -1,3 +1,4 @@
Disabled:Missing current source for library - 1.0 available, 1.4 used - https://sourceforge.net/tracker/?func=detail&aid=3479542&group_id=218065&atid=1043257
Category:Internet
License:GPLv3
Web Site:http://openbmap.org
@ -15,7 +16,9 @@ Repo:git://myposition.git.sourceforge.net/gitroot/myposition/AndroidClient
Build Version:0.4.96,9,bc15ce80024d7f53897fd10e6ea0cc914d0ba226,prebuild=mv lib libs,target=android-10
Build Version:0.4.991,13,!Source is not there - see https://sourceforge.net/tracker/?func=detail&aid=3374951&group_id=218065&atid=1043257
Build Version:0.4.999,14,3ed4e59fff30555325f9affa8c0021ee033fc72f,prebuild=mv lib libs,target=android-10
Market Version:0.4.991
Market Version Code:13
Update Check Mode:Market
Current Version:0.4.999
Current Version Code:14

View File

@ -17,6 +17,7 @@ Repo:http://chartdroid.googlecode.com/svn/trunk/core
Build Version:2.0.0,18,294
Market Version:2.0.0
Market Version Code:18
Update Check Mode:Market
Current Version:2.0.0
Current Version Code:18

View File

@ -22,6 +22,7 @@ Build Version:1.4.8,148,156
Build Version:1.5.3,153,219
Build Version:1.5.6,156,245,target=android-8
Market Version:1.5.6
Market Version Code:156
Update Check Mode:Market
Current Version:1.5.6
Current Version Code:156

View File

@ -11,6 +11,7 @@ You can also receive information, such as incoming calls and SMS, and
battery state.
.
Market Version:2.06-beta
Market Version Code:17
Update Check Mode:Market
Current Version:2.06-beta
Current Version Code:17

View File

@ -25,6 +25,7 @@ Repo:http://andors-trail.googlecode.com/svn/trunk/
Build Version:0.6.9,20,118,subdir=AndorsTrail
Build Version:0.6.10,25,192,subdir=AndorsTrail
Market Version:0.6.10
Market Version Code:25
Update Check Mode:Market
Current Version:0.6.10
Current Version Code:25

View File

@ -0,0 +1,37 @@
Category:Office
License:Apache2
Web Site:http://code.google.com/p/quickdic-dictionary/
Source Code:http://code.google.com/p/quickdic-dictionary/source/checkout
Issue Tracker:http://code.google.com/p/quickdic-dictionary/issues/list
Summary:Offline translation dictionary
Description:
Uses data from Wiktionary and Beolingus to generate dictionary files that can
be used offline.
.
Repo Type:git
Repo:https://code.google.com/p/quickdic-dictionary.dictionary/
Build Version:3.0.1,15,6507667d0e0af60c201ae6c732c15e2fd07886ae,prebuild=mkdir libs && \
mv jars/*.jar libs/ && \
git clone https://code.google.com/p/quickdic-dictionary.util/ Util && \
cd Util && \
git checkout c848279fde9af59fdd167eacbc5deb0258223c8e && \
cd .. && \
cp -r Util/src . && \
rm -rf Util/
Build Version:3.1,16,64d2b5,prebuild=mkdir libs && \
mv jars/*.jar libs/ && \
git clone https://code.google.com/p/quickdic-dictionary.util/ Util && \
cd Util && \
git checkout c8f5ba9eac5f110d574ef8b443a205051026688c && \
cd .. && \
cp -r Util/src . && \
rm -rf Util/
Update Check Mode:Market
Current Version:3.1
Current Version Code:16

View File

@ -21,7 +21,9 @@ Repo:git://github.com/nicolas-raoul/Anki-Android.git
Build Version:0.6,20,f26b7662ae9db9a92d21
Build Version:0.7,21,v0.7
Build Version:1.0,22,v1.0,prebuild=sed -i -e "/key\.alias.*/d" -e "/key\.store.*/d" *.properties
Build Version:1.0,23,!Same version presumably
Market Version:1.0
Market Version Code:23
Update Check Mode:Market
Current Version:1.0
Current Version Code:23

View File

@ -0,0 +1,28 @@
Category:Multimedia
License:GPLv3
Web Site:http://binauralbeatstherapy.wordpress.com/
Source Code:https://github.com/GiorgioRegni/Binaural-Beats
Issue Tracker:https://github.com/GiorgioRegni/Binaural-Beats/issues
Summary:Auditory brainwave mangler
Description:
Stimulate your brain to produce subtle changes though entraiment of brainwaves.
Binaural beats stimulates your brain by sending special auditory artifacts
directly into your headphones to produce subtle changes in behavior though
entraiment of brainwaves frequency.
This app can help induce relaxation, creativity and many other desirable mental
states.
.
Repo Type:git
Repo:https://github.com/GiorgioRegni/Binaural-Beats.git
Build Version:1.2,24,85160b47e80d1cac025d02756f642f3c8f667191
Build Version:1.3,25,!No source in repo
Update Check Mode:Market
Current Version:1.3
Current Version Code:25

View File

@ -13,8 +13,9 @@ their number. The web service is also FOSS.
Repo Type:git
Repo:git://gitorious.org/callerid-for-android/mainline.git
Update Check Mode:Market
#Disabled pending figuring out how to stop it zipaligning....
#Build Version:1.0,1,e6d5a9ac4bb24ae3866a0782f2b23d1f18eb2266,subdir=application,maven=yes,bindir=application/target,prebuild=wget http://osmdroid.googlecode.com/files/osmdroid-android-3.0.3.jar && mvn install:install-file -DgroupId=org.osmdroid -DartifactId=osmdroid -Dversion=3.0.3 -Dpackaging=jar -Dfile=osmdroid-android-3.0.3.jar
Market Version:1.3
Market Version Code:4
Current Version:1.3
Current Version Code:4

View File

@ -20,6 +20,7 @@ Repo:git://github.com/bherrmann7/Car-Cast.git
Build Version:1.0.129,129,7a879c6bfa51b5d80401b84e031bf4ff2981bb8c,subdir=cc,target=android-8,rm=cc/libs/admob-sdk-android.jar,patch=admob.patch
Market Version:1.0.129
Market Version Code:129
Update Check Mode:Market
Current Version:1.0.129
Current Version Code:129

View File

@ -10,6 +10,7 @@ A game in the style of the classic Missile Command. Defend your cities from inco
enemy missiles.
.
Market Version:0.5.1
Market Version Code:6
Update Check Mode:Market
Current Version:0.5.1
Current Version Code:6

Some files were not shown because too many files have changed in this diff Show More