import subprocess
import time
import operator
-import Queue
import logging
import hashlib
import socket
import xml.etree.ElementTree as XMLElementTree
-from distutils.version import LooseVersion
+try:
+ # Python 2
+ from Queue import Queue
+except ImportError:
+ # Python 3
+ from queue import Queue
+
from zipfile import ZipFile
import metadata
'r10e': "$ANDROID_NDK",
},
'build_tools': "23.0.2",
- 'java_paths': {
- '1.7': "/usr/lib/jvm/java-7-openjdk",
- '1.8': None,
- },
+ 'java_paths': None,
'ant': "ant",
'mvn3': "mvn",
'gradle': 'gradle',
thisconfig[k] = exp
thisconfig[k + '_orig'] = v
+ # find all installed JDKs for keytool, jarsigner, and JAVA[6-9]_HOME env vars
+ if thisconfig['java_paths'] is None:
+ thisconfig['java_paths'] = dict()
+ for d in sorted(glob.glob('/usr/lib/jvm/j*[6-9]*')
+ + glob.glob('/usr/java/jdk1.[6-9]*')
+ + glob.glob('/System/Library/Java/JavaVirtualMachines/1.[6-9].0.jdk')
+ + glob.glob('/Library/Java/JavaVirtualMachines/*jdk*[6-9]*')):
+ if os.path.islink(d):
+ continue
+ j = os.path.basename(d)
+ # the last one found will be the canonical one, so order appropriately
+ for regex in (r'1\.([6-9])\.0\.jdk', # OSX
+ r'jdk1\.([6-9])\.0_[0-9]+.jdk', # OSX and Oracle tarball
+ r'jdk([6-9])-openjdk', # Arch
+ r'java-1\.([6-9])\.0-.*', # RedHat
+ r'java-([6-9])-oracle', # Debian WebUpd8
+ r'jdk-([6-9])-oracle-.*', # Debian make-jpkg
+ r'java-([6-9])-openjdk-[^c][^o][^m].*'): # Debian
+ m = re.match(regex, j)
+ if m:
+ osxhome = os.path.join(d, 'Contents', 'Home')
+ if os.path.exists(osxhome):
+ thisconfig['java_paths'][m.group(1)] = osxhome
+ else:
+ thisconfig['java_paths'][m.group(1)] = d
+
+ for java_version in ('7', '8', '9'):
+ java_home = thisconfig['java_paths'][java_version]
+ jarsigner = os.path.join(java_home, 'bin', 'jarsigner')
+ if os.path.exists(jarsigner):
+ thisconfig['jarsigner'] = jarsigner
+ thisconfig['keytool'] = os.path.join(java_home, 'bin', 'keytool')
+ break # Java7 is preferred, so quit if found
+
for k in ['ndk_paths', 'java_paths']:
d = thisconfig[k]
for k2 in d.copy():
for n in ['ANDROID_HOME', 'ANDROID_SDK']:
env[n] = config['sdk_path']
- for v in ['7', '8']:
- cpath = config['java_paths']['1.%s' % v]
- if cpath:
- env['JAVA%s_HOME' % v] = cpath
+ for k, v in config['java_paths'].items():
+ env['JAVA%s_HOME' % k] = v
for k in ["keystorepass", "keypass"]:
if k in config:
command line argments
'''
filename = '.fdroid.' + pwtype + '.txt'
- fd = os.open(filename, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0600)
+ fd = os.open(filename, os.O_CREAT | os.O_TRUNC | os.O_WRONLY, 0o600)
if password is None:
os.write(fd, config[pwtype])
else:
return ext == f_ext
-apk_regex = None
+apk_regex = re.compile(r"^(.+)_([0-9]+)\.apk$")
def clean_description(description):
def apknameinfo(filename):
- global apk_regex
filename = os.path.basename(filename)
- if apk_regex is None:
- apk_regex = re.compile(r"^(.+)_([0-9]+)\.apk$")
m = apk_regex.match(filename)
try:
result = (m.group(1), m.group(2))
try:
self.gotorevisionx(rev)
- except FDroidException, e:
+ except FDroidException as e:
exc = e
# If necessary, write the .fdroidvcs file.
if matches:
vercode = matches.group(1)
else:
- xml = parse_xml(path)
- if "package" in xml.attrib:
- s = xml.attrib["package"].encode('utf-8')
- if app_matches_packagename(app, s):
- package = s
- if "{http://schemas.android.com/apk/res/android}versionName" in xml.attrib:
- version = xml.attrib["{http://schemas.android.com/apk/res/android}versionName"].encode('utf-8')
- base_dir = os.path.dirname(path)
- version = retrieve_string_singleline(base_dir, version)
- if "{http://schemas.android.com/apk/res/android}versionCode" in xml.attrib:
- a = xml.attrib["{http://schemas.android.com/apk/res/android}versionCode"].encode('utf-8')
- if string_is_integer(a):
- vercode = a
+ try:
+ xml = parse_xml(path)
+ if "package" in xml.attrib:
+ s = xml.attrib["package"].encode('utf-8')
+ if app_matches_packagename(app, s):
+ package = s
+ if "{http://schemas.android.com/apk/res/android}versionName" in xml.attrib:
+ version = xml.attrib["{http://schemas.android.com/apk/res/android}versionName"].encode('utf-8')
+ base_dir = os.path.dirname(path)
+ version = retrieve_string_singleline(base_dir, version)
+ if "{http://schemas.android.com/apk/res/android}versionCode" in xml.attrib:
+ a = xml.attrib["{http://schemas.android.com/apk/res/android}versionCode"].encode('utf-8')
+ if string_is_integer(a):
+ vercode = a
+ except Exception:
+ logging.warning("Problem with xml at {0}".format(path))
# Remember package name, may be defined separately from version+vercode
if package is None:
if build.method() == 'gradle':
flavours = build.gradle
- gradlepluginver = None
-
- gradle_dirs = [root_dir]
-
- # Parent dir build.gradle
- parent_dir = os.path.normpath(os.path.join(root_dir, '..'))
- if parent_dir.startswith(build_dir):
- gradle_dirs.append(parent_dir)
-
- for dir_path in gradle_dirs:
- if gradlepluginver:
- break
- if not os.path.isdir(dir_path):
- continue
- for filename in os.listdir(dir_path):
- if not filename.endswith('.gradle'):
- continue
- path = os.path.join(dir_path, filename)
- if not os.path.isfile(path):
- continue
- for line in file(path):
- match = gradle_version_regex.match(line)
- if match:
- gradlepluginver = match.group(1)
- break
-
- if gradlepluginver:
- build.gradlepluginver = LooseVersion(gradlepluginver)
- else:
- logging.warn("Could not fetch the gradle plugin version, defaulting to 0.11")
- build.gradlepluginver = LooseVersion('0.11')
-
if build.target:
n = build.target.split('-')[1]
regsub_file(r'compileSdkVersion[ =]+[0-9]+',
(app.id, build.version), p.output)
# Generate (or update) the ant build file, build.xml...
- if build.update and build.update != ['no'] and build.method() == 'ant':
+ if build.method() == 'ant' and build.update != ['no']:
parms = ['android', 'update', 'lib-project']
lparms = ['android', 'update', 'project']
try:
p = subprocess.Popen(commands, cwd=cwd, shell=False, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- except OSError, e:
+ except OSError as e:
raise BuildException("OSError while trying to execute " +
' '.join(commands) + ': ' + str(e))
- stdout_queue = Queue.Queue()
+ stdout_queue = Queue()
stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue)
# Check the queue for output (until there is no more to get)
gradle_line_matches = [
re.compile(r'^[\t ]*signingConfig [^ ]*$'),
re.compile(r'.*android\.signingConfigs\.[^{]*$'),
- re.compile(r'.*variant\.outputFile = .*'),
- re.compile(r'.*output\.outputFile = .*'),
re.compile(r'.*\.readLine\(.*'),
]
for meta_inf_file in meta_inf_files:
unsigned_apk_as_zip.write(os.path.join(tmp_dir, meta_inf_file), arcname=meta_inf_file)
- if subprocess.call(['jarsigner', '-verify', unsigned_apk]) != 0:
+ if subprocess.call([config['jarsigner'], '-verify', unsigned_apk]) != 0:
logging.info("...NOT verified - {0}".format(signed_apk))
return compare_apks(signed_apk, unsigned_apk, tmp_dir)
logging.info("...successfully verified")
write_password_file("keystorepass", localconfig['keystorepass'])
write_password_file("keypass", localconfig['keypass'])
- p = FDroidPopen(['keytool', '-genkey',
+ p = FDroidPopen([config['keytool'], '-genkey',
'-keystore', localconfig['keystore'],
'-alias', localconfig['repo_keyalias'],
'-keyalg', 'RSA', '-keysize', '4096',
raise BuildException("Failed to generate key", p.output)
os.chmod(localconfig['keystore'], 0o0600)
# now show the lovely key that was just generated
- p = FDroidPopen(['keytool', '-list', '-v',
+ p = FDroidPopen([config['keytool'], '-list', '-v',
'-keystore', localconfig['keystore'],
'-alias', localconfig['repo_keyalias'],
'-storepass:file', config['keystorepassfile']])
repos = []
for root, dirs, files in os.walk(os.getcwd()):
for d in dirs:
- print 'checking', root, 'for', d
+ print('checking', root, 'for', d)
if d in ('archive', 'metadata', 'repo', 'srclibs', 'tmp'):
# standard parts of an fdroid repo, so never packageNames
continue