#!/usr/bin/env python import os import sys import re import logging import subprocess import argparse sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from wlauto.exceptions import WAError, ToolError from wlauto.utils.doc import format_simple_table def get_aapt_path(): """Return the full path to aapt tool.""" sdk_path = os.getenv('ANDROID_HOME') if not sdk_path: raise ToolError('Please make sure you have Android SDK installed and have ANDROID_HOME set.') build_tools_directory = os.path.join(sdk_path, 'build-tools') versions = os.listdir(build_tools_directory) for version in reversed(sorted(versions)): aapt_path = os.path.join(build_tools_directory, version, 'aapt') if os.path.isfile(aapt_path): logging.debug('Found aapt for version {}'.format(version)) return aapt_path else: raise ToolError('aapt not found. Please make sure at least one Android platform is installed.') def get_apks(path): """Return a list of paths to all APK files found under the specified directory.""" apks = [] for root, dirs, files in os.walk(path): for file in files: _, ext = os.path.splitext(file) if ext.lower() == '.apk': apks.append(os.path.join(root, file)) return apks class ApkVersionInfo(object): def __init__(self, workload=None, package=None, label=None, version_name=None, version_code=None): self.workload = workload self.package = package self.label = label self.version_name = version_name self.version_code = version_code def to_tuple(self): return (self.workload, self.package, self.label, self.version_name, self.version_code) version_regex = re.compile(r"name='(?P[^']+)' versionCode='(?P[^']+)' versionName='(?P[^']+)'") def extract_version_info(apk_path, aapt): command = [aapt, 'dump', 'badging', apk_path] output = subprocess.check_output(command) version_info = ApkVersionInfo(workload=apk_path.split(os.sep)[-2]) for line in output.split('\n'): if line.startswith('application-label:'): version_info.label = line.split(':')[1].strip().replace('\'', '') elif line.startswith('package:'): match = version_regex.search(line) if match: version_info.package = match.group('name') version_info.version_code = match.group('vcode') version_info.version_name = match.group('vname') else: pass # not interested return version_info def get_apk_versions(path, aapt): apks = get_apks(path) versions = [extract_version_info(apk, aapt) for apk in apks] return versions if __name__ == '__main__': try: aapt = get_aapt_path() parser = argparse.ArgumentParser() parser.add_argument('path', metavar='PATH', help='Location to look for APKs.') args = parser.parse_args() versions = get_apk_versions(args.path, aapt) table = format_simple_table([v.to_tuple() for v in versions], align='<<<>>', headers=['workload', 'package', 'name', 'version code', 'version name']) print table except WAError, e: logging.error(e) sys.exit(1)