mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-10-05 18:50:09 +02:00
find cmds from SDK build-tools in a more flexible way, on the fly
This is a more flexible approach than testing for the complete SDK and build-tools up front. This will only test for the commands that are actually being run, so that if you only have `aapt` installed, you can do `fdroid update` without errors, but other commands will still give appropriate errors. This also makes the build_tools item in config.py optional, it is only needed if you want to force a specific version of the build-tools.
This commit is contained in:
parent
298a88a498
commit
9244256461
@ -35,7 +35,7 @@ import logging
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import FDroidException, BuildException, VCSException, FDroidPopen, SilentPopen
|
||||
from common import FDroidException, BuildException, VCSException, FDroidPopen, SdkToolsPopen
|
||||
|
||||
try:
|
||||
import paramiko
|
||||
@ -754,7 +754,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
|
||||
if not os.path.exists(src):
|
||||
raise BuildException("Unsigned apk is not at expected location of " + src)
|
||||
|
||||
p = SilentPopen([config['aapt'], 'dump', 'badging', src])
|
||||
p = SdkToolsPopen(['aapt', 'dump', 'badging', src])
|
||||
|
||||
vercode = None
|
||||
version = None
|
||||
|
@ -130,9 +130,6 @@ def read_config(opts, config_file='config.py'):
|
||||
|
||||
fill_config_defaults(config)
|
||||
|
||||
if not test_build_tools_exists(config):
|
||||
sys.exit(3)
|
||||
|
||||
bin_paths = {
|
||||
'aapt': [
|
||||
os.path.join(config['sdk_path'], 'build-tools', config['build_tools'], 'aapt'),
|
||||
@ -194,7 +191,42 @@ def read_config(opts, config_file='config.py'):
|
||||
return config
|
||||
|
||||
|
||||
def find_sdk_tools_cmd(cmd):
|
||||
'''find a working path to a tool from the Android SDK'''
|
||||
|
||||
tooldirs = []
|
||||
if 'sdk_path' in config and os.path.exists(config['sdk_path']):
|
||||
# try to find a working path to this command, in all the recent possible paths
|
||||
if 'build_tools' in config:
|
||||
build_tools = os.path.join(config['sdk_path'], 'build-tools')
|
||||
# if 'build_tools' was manually set and exists, check only that one
|
||||
configed_build_tools = os.path.join(build_tools, config['build_tools'])
|
||||
if os.path.exists(configed_build_tools):
|
||||
tooldirs.append(configed_build_tools)
|
||||
else:
|
||||
# no configed version, so hunt known paths for it
|
||||
for f in sorted(os.listdir(build_tools), reverse=True):
|
||||
if os.path.isdir(os.path.join(build_tools, f)):
|
||||
tooldirs.append(os.path.join(build_tools, f))
|
||||
tooldirs.append(build_tools)
|
||||
sdk_tools = os.path.join(config['sdk_path'], 'tools')
|
||||
if os.path.exists(sdk_tools):
|
||||
tooldirs.append(sdk_tools)
|
||||
sdk_platform_tools = os.path.join(config['sdk_path'], 'platform-tools')
|
||||
if os.path.exists(sdk_platform_tools):
|
||||
tooldirs.append(sdk_platform_tools)
|
||||
tooldirs.append('/usr/bin')
|
||||
for d in tooldirs:
|
||||
if os.path.isfile(os.path.join(d, cmd)):
|
||||
return os.path.join(d, cmd)
|
||||
# did not find the command, exit with error message
|
||||
ensure_build_tools_exists(config)
|
||||
|
||||
|
||||
def test_sdk_exists(thisconfig):
|
||||
if 'sdk_path' not in thisconfig:
|
||||
logging.error("'sdk_path' not set in config.py!")
|
||||
return False
|
||||
if thisconfig['sdk_path'] == default_config['sdk_path']:
|
||||
logging.error('No Android SDK found!')
|
||||
logging.error('You can use ANDROID_HOME to set the path to your SDK, i.e.:')
|
||||
@ -214,16 +246,15 @@ def test_sdk_exists(thisconfig):
|
||||
return True
|
||||
|
||||
|
||||
def test_build_tools_exists(thisconfig):
|
||||
def ensure_build_tools_exists(thisconfig):
|
||||
if not test_sdk_exists(thisconfig):
|
||||
return False
|
||||
sys.exit(3)
|
||||
build_tools = os.path.join(thisconfig['sdk_path'], 'build-tools')
|
||||
versioned_build_tools = os.path.join(build_tools, thisconfig['build_tools'])
|
||||
if not os.path.isdir(versioned_build_tools):
|
||||
logging.critical('Android Build Tools path "'
|
||||
+ versioned_build_tools + '" does not exist!')
|
||||
return False
|
||||
return True
|
||||
sys.exit(3)
|
||||
|
||||
|
||||
def write_password_file(pwtype, password=None):
|
||||
@ -1597,8 +1628,7 @@ def isApkDebuggable(apkfile, config):
|
||||
|
||||
:param apkfile: full path to the apk to check"""
|
||||
|
||||
p = SilentPopen([config['aapt'],
|
||||
'dump', 'xmltree', apkfile, 'AndroidManifest.xml'])
|
||||
p = SdkToolsPopen(['aapt', 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'])
|
||||
if p.returncode != 0:
|
||||
logging.critical("Failed to get apk manifest information")
|
||||
sys.exit(1)
|
||||
@ -1637,6 +1667,14 @@ class PopenResult:
|
||||
output = ''
|
||||
|
||||
|
||||
def SdkToolsPopen(commands, cwd=None, shell=False):
|
||||
cmd = commands[0]
|
||||
if cmd not in config:
|
||||
config[cmd] = find_sdk_tools_cmd(commands[0])
|
||||
return FDroidPopen([config[cmd]] + commands[1:],
|
||||
cwd=cwd, shell=shell, output=False)
|
||||
|
||||
|
||||
def SilentPopen(commands, cwd=None, shell=False):
|
||||
return FDroidPopen(commands, cwd=cwd, shell=shell, output=False)
|
||||
|
||||
|
@ -168,6 +168,10 @@ def main():
|
||||
logging.info('Try running `fdroid init` in an empty directory.')
|
||||
sys.exit()
|
||||
|
||||
if os.path.exists('/usr/bin/aapt'):
|
||||
# make sure at least aapt is found, since this can't do anything without it
|
||||
config['aapt'] = common.find_sdk_tools_cmd('aapt')
|
||||
else:
|
||||
# try to find a working aapt, in all the recent possible paths
|
||||
build_tools = os.path.join(test_config['sdk_path'], 'build-tools')
|
||||
aaptdirs = []
|
||||
@ -188,8 +192,7 @@ def main():
|
||||
else:
|
||||
test_config['build_tools'] = dirname
|
||||
write_to_config(test_config, 'build_tools')
|
||||
if not common.test_build_tools_exists(test_config):
|
||||
sys.exit(3)
|
||||
common.ensure_build_tools_exists(test_config)
|
||||
|
||||
# now that we have a local config.py, read configuration...
|
||||
config = common.read_config(options)
|
||||
|
@ -39,7 +39,7 @@ import logging
|
||||
|
||||
import common
|
||||
import metadata
|
||||
from common import FDroidPopen, SilentPopen
|
||||
from common import FDroidPopen, SdkToolsPopen
|
||||
from metadata import MetaDataException
|
||||
|
||||
|
||||
@ -436,7 +436,7 @@ def scan_apks(apps, apkcache, repodir, knownapks):
|
||||
thisinfo['features'] = set()
|
||||
thisinfo['icons_src'] = {}
|
||||
thisinfo['icons'] = {}
|
||||
p = SilentPopen([config['aapt'], 'dump', 'badging', apkfile])
|
||||
p = SdkToolsPopen(['aapt', 'dump', 'badging', apkfile])
|
||||
if p.returncode != 0:
|
||||
if options.delete_unknown:
|
||||
if os.path.exists(apkfile):
|
||||
|
@ -21,9 +21,50 @@ import fdroidserver.common
|
||||
class CommonTest(unittest.TestCase):
|
||||
'''fdroidserver/common.py'''
|
||||
|
||||
def _set_build_tools(self):
|
||||
build_tools = os.path.join(fdroidserver.common.config['sdk_path'], 'build-tools')
|
||||
if os.path.exists(build_tools):
|
||||
fdroidserver.common.config['build_tools'] = ''
|
||||
for f in sorted(os.listdir(build_tools), reverse=True):
|
||||
versioned = os.path.join(build_tools, f)
|
||||
if os.path.isdir(versioned) \
|
||||
and os.path.isfile(os.path.join(versioned, 'aapt')):
|
||||
fdroidserver.common.config['build_tools'] = versioned
|
||||
break
|
||||
return True
|
||||
else:
|
||||
print 'no build-tools found: ' + build_tools
|
||||
return False
|
||||
|
||||
def _find_all(self):
|
||||
for cmd in ('aapt', 'adb', 'android', 'zipalign'):
|
||||
path = fdroidserver.common.find_sdk_tools_cmd(cmd)
|
||||
if path is not None:
|
||||
self.assertTrue(os.path.exists(path))
|
||||
self.assertTrue(os.path.isfile(path))
|
||||
|
||||
def test_find_sdk_tools_cmd(self):
|
||||
fdroidserver.common.config = dict()
|
||||
# TODO add this once everything works without sdk_path set in config
|
||||
#self._find_all()
|
||||
sdk_path = os.getenv('ANDROID_HOME')
|
||||
if os.path.exists(sdk_path):
|
||||
fdroidserver.common.config['sdk_path'] = sdk_path
|
||||
if os.path.exists('/usr/bin/aapt'):
|
||||
# this test only works when /usr/bin/aapt is installed
|
||||
self._find_all()
|
||||
build_tools = os.path.join(sdk_path, 'build-tools')
|
||||
if self._set_build_tools():
|
||||
self._find_all()
|
||||
else:
|
||||
print 'no build-tools found: ' + build_tools
|
||||
|
||||
def testIsApkDebuggable(self):
|
||||
config = dict()
|
||||
config['aapt'] = '/usr/bin/aapt'
|
||||
config['sdk_path'] = os.getenv('ANDROID_HOME')
|
||||
fdroidserver.common.config = config
|
||||
self._set_build_tools();
|
||||
config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt')
|
||||
# these are set debuggable
|
||||
testfiles = []
|
||||
testfiles.append(os.path.join(os.path.dirname(__file__), 'urzip.apk'))
|
||||
|
@ -209,6 +209,9 @@ $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME
|
||||
#------------------------------------------------------------------------------#
|
||||
echo_header "check that 'fdroid init' fails when build-tools cannot be found"
|
||||
|
||||
if [ -e /usr/bin/aapt ]; then
|
||||
echo "/usr/bin/aapt exists, not running test"
|
||||
else
|
||||
REPOROOT=`create_test_dir`
|
||||
FAKE_ANDROID_HOME=`create_test_dir`
|
||||
create_fake_android_home $FAKE_ANDROID_HOME
|
||||
@ -219,6 +222,7 @@ set +e
|
||||
$fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME
|
||||
[ $? -eq 0 ] && exit 1
|
||||
set -e
|
||||
fi
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------#
|
||||
|
Loading…
Reference in New Issue
Block a user