import common
import metadata
-from common import FDroidException, BuildException, VCSException, FDroidPopen, SilentPopen
+from common import FDroidException, BuildException, VCSException, FDroidPopen, SdkToolsPopen
try:
import paramiko
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
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'),
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.:')
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):
: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)
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)
logging.info('Try running `fdroid init` in an empty directory.')
sys.exit()
- # try to find a working aapt, in all the recent possible paths
- build_tools = os.path.join(test_config['sdk_path'], 'build-tools')
- aaptdirs = []
- aaptdirs.append(os.path.join(build_tools, test_config['build_tools']))
- aaptdirs.append(build_tools)
- for f in os.listdir(build_tools):
- if os.path.isdir(os.path.join(build_tools, f)):
- aaptdirs.append(os.path.join(build_tools, f))
- for d in sorted(aaptdirs, reverse=True):
- if os.path.isfile(os.path.join(d, 'aapt')):
- aapt = os.path.join(d, 'aapt')
- break
- if os.path.isfile(aapt):
- dirname = os.path.basename(os.path.dirname(aapt))
- if dirname == 'build-tools':
- # this is the old layout, before versioned build-tools
- test_config['build_tools'] = ''
- 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)
+ 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 = []
+ aaptdirs.append(os.path.join(build_tools, test_config['build_tools']))
+ aaptdirs.append(build_tools)
+ for f in os.listdir(build_tools):
+ if os.path.isdir(os.path.join(build_tools, f)):
+ aaptdirs.append(os.path.join(build_tools, f))
+ for d in sorted(aaptdirs, reverse=True):
+ if os.path.isfile(os.path.join(d, 'aapt')):
+ aapt = os.path.join(d, 'aapt')
+ break
+ if os.path.isfile(aapt):
+ dirname = os.path.basename(os.path.dirname(aapt))
+ if dirname == 'build-tools':
+ # this is the old layout, before versioned build-tools
+ test_config['build_tools'] = ''
+ else:
+ test_config['build_tools'] = dirname
+ write_to_config(test_config, 'build_tools')
+ common.ensure_build_tools_exists(test_config)
# now that we have a local config.py, read configuration...
config = common.read_config(options)
import common
import metadata
-from common import FDroidPopen, SilentPopen
+from common import FDroidPopen, SdkToolsPopen
from metadata import MetaDataException
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):
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'))
#------------------------------------------------------------------------------#
echo_header "check that 'fdroid init' fails when build-tools cannot be found"
-REPOROOT=`create_test_dir`
-FAKE_ANDROID_HOME=`create_test_dir`
-create_fake_android_home $FAKE_ANDROID_HOME
-rm -f $FAKE_ANDROID_HOME/build-tools/*/aapt
-KEYSTORE=$REPOROOT/keystore.jks
-cd $REPOROOT
-set +e
-$fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME
-[ $? -eq 0 ] && exit 1
-set -e
+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
+ rm -f $FAKE_ANDROID_HOME/build-tools/*/aapt
+ KEYSTORE=$REPOROOT/keystore.jks
+ cd $REPOROOT
+ set +e
+ $fdroid init --keystore $KEYSTORE --android-home $FAKE_ANDROID_HOME
+ [ $? -eq 0 ] && exit 1
+ set -e
+fi
#------------------------------------------------------------------------------#