diff --git a/buildozer/__init__.py b/buildozer/__init__.py index bffd8b6..f08ec88 100644 --- a/buildozer/__init__.py +++ b/buildozer/__init__.py @@ -72,6 +72,7 @@ class Buildozer(object): m = __import__('buildozer.targets.%s' % target, fromlist=['buildozer']) self.target = m.get_target(self) self.check_build_layout() + self.target.check_configuration_tokens() def prepare_for_build(self): '''Prepare the build. @@ -248,7 +249,7 @@ class Buildozer(object): ', required by "version.regex"') if errors: - self.error('{0} errors found in the buildozer.spec'.format( + self.error('{0} error(s) found in the buildozer.spec'.format( len(errors))) for error in errors: print error diff --git a/buildozer/target.py b/buildozer/target.py index 08e0a1f..6f68fbb 100644 --- a/buildozer/target.py +++ b/buildozer/target.py @@ -11,6 +11,16 @@ class Target(object): def check_requirements(self): pass + def check_configuration_tokens(self, errors=None): + if errors: + self.buildozer.info('Check target configuration tokens') + self.buildozer.error( + '{0} error(s) found in the buildozer.spec'.format( + len(errors))) + for error in errors: + print error + exit(1) + def compile_platform(self): pass @@ -26,7 +36,7 @@ class Target(object): def run_commands(self, args): if not args: - print 'ERROR: missing target command' + self.buildozer.error('Missing target command') self.buildozer.usage() exit(1) @@ -40,7 +50,7 @@ class Target(object): last_command.append(arg) else: if not last_command: - print 'ERROR: argument passed without a command' + self.buildozer.error('Argument passed without a command') self.buildozer.usage() exit(1) last_command.append(arg) @@ -50,7 +60,7 @@ class Target(object): for item in result: command, args = item[0], item[1:] if not hasattr(self, 'cmd_{0}'.format(command)): - print 'Unknown command {0}'.format(command) + self.buildozer.error('Unknow command {0}'.format(command)) exit(1) getattr(self, 'cmd_{0}'.format(command))(args) diff --git a/buildozer/targets/android.py b/buildozer/targets/android.py index c0ce3ac..8611caf 100644 --- a/buildozer/targets/android.py +++ b/buildozer/targets/android.py @@ -108,6 +108,51 @@ class TargetAndroid(Target): checkbin('Java compiler', self.javac_cmd) checkbin('Java keytool', self.keytool_cmd) + def check_configuration_tokens(self): + errors = [] + + # check the permission + available_permissions = self._get_available_permissions() + if available_permissions: + permissions = self.buildozer.config.getlist( + 'app', 'android.permissions', []) + for permission in permissions: + if permission not in available_permissions: + errors.append( + '[app] "android.permission" contain an unknown' + ' permission {0}'.format(permission)) + + super(TargetAndroid, self).check_configuration_tokens(errors) + + def _get_available_permissions(self): + key = 'android:available_permissions' + key_sdk = 'android:available_permissions_sdk' + + refresh_permissions = False + sdk = self.buildozer.state.get(key_sdk, None) + if not sdk or sdk != self.android_sdk_version: + refresh_permissions = True + if key not in self.buildozer.state: + refresh_permissions = True + if not refresh_permissions: + return self.buildozer.state[key] + + try: + self.buildozer.debug('Read available permissions from api-versions.xml') + import xml.etree.ElementTree as ET + fn = join(self.android_sdk_dir, 'platform-tools', + 'api', 'api-versions.xml') + with open(fn) as fd: + doc = ET.fromstring(fd.read()) + fields = doc.findall('.//class[@name="android/Manifest$permission"]/field[@name]') + available_permissions = [x.attrib['name'] for x in fields] + + self.buildozer.state[key] = available_permissions + self.buildozer.state[key_sdk] = self.android_sdk_version + return available_permissions + except: + return None + def _set_win32_java_home(self): if 'JAVA_HOME' in self.buildozer.environ: return @@ -237,6 +282,10 @@ class TargetAndroid(Target): self._install_android_ndk() self._install_android_packages() + # ultimate configuration check. + # some of our configuration cannot be check without platform. + self.check_configuration_tokens() + self.buildozer.environ.update({ 'ANDROIDSDK': self.android_sdk_dir, 'ANDROIDNDK': self.android_ndk_dir,