def package_android(build): jre = _get_jre() path_info = _find_or_install_sdk(build) lib_path = path.normpath(path.join('.template', 'lib')) dev_dir = path.normpath(path.join('development', 'android')) output = path.abspath(_generate_path_to_output_apk(build)) signing_info = _lookup_or_prompt_for_signing_info(build) signing_info["keystore"] = lib.expand_relative_path( build, signing_info["keystore"]) LOG.info('Creating Android .apk file') package_name = _generate_package_name(build) #zip with temp_file() as zipf_name: _create_apk_with_aapt(build, zipf_name, path_info, package_name, lib_path, dev_dir) with temp_file() as signed_zipf_name: #sign _sign_zipf_release(lib_path, jre, zipf_name, signed_zipf_name, **signing_info) # create output directory for APK if necessary _create_output_directory(output) #align _align_apk(path_info, signed_zipf_name, output) LOG.debug('removing zipfile and un-aligned APK') LOG.info("created APK: {output}".format(output=output)) return output
def package_android(build): jre = _get_jre() path_info = _find_or_install_sdk(build) lib_path = path.normpath(path.join('.template', 'lib')) dev_dir = path.normpath(path.join('development', 'android')) output = path.abspath(_generate_path_to_output_apk(build)) signing_info = _lookup_or_prompt_for_signing_info(build) signing_info["keystore"] = lib.expand_relative_path(build, signing_info["keystore"]) LOG.info('Creating Android .apk file') package_name = _generate_package_name(build) #zip with temp_file() as zipf_name: _create_apk_with_aapt(build, zipf_name, path_info, package_name, lib_path, dev_dir) with temp_file() as signed_zipf_name: #sign _sign_zipf_release(lib_path, jre, zipf_name, signed_zipf_name, **signing_info) # create output directory for APK if necessary _create_output_directory(output) #align _align_apk(path_info, signed_zipf_name, output) LOG.debug('removing zipfile and un-aligned APK') LOG.info("created APK: {output}".format(output=output)) return output
def _lookup_or_prompt_for_signing_info(build): """Obtain the required details for signing an APK, first by checking local_config.json and then asking the user for anything missing. """ required_info = { 'android.profile.keystore': { 'type': 'string', '_filepicker': True, 'description': 'The location of your release keystore', 'title': 'Keystore', }, 'android.profile.storepass': { 'type': 'string', '_password': True, 'description': 'The password for your release keystore', 'title': 'Keystore password', }, 'android.profile.keyalias': { 'type': 'string', 'description': 'The alias of your release key', 'title': 'Key alias', }, 'android.profile.keypass': { 'type': 'string', '_password': True, 'description': 'The password for your release key', 'title': 'Key password' } } signing_info = lib.get_or_ask_for_local_config( build, required_info, question_title='Enter details for signing your app', ) signing_info['android.profile.keystore'] = lib.expand_relative_path( build, signing_info['android.profile.keystore'] ) return signing_info
def _lookup_or_prompt_for_signing_info(build): """Obtain the required details for signing an APK, first by checking local_config.json and then asking the user for anything missing. """ required_info = { 'android.profile.keystore': { 'type': 'string', '_filepicker': True, 'description': 'The location of your release keystore', 'title': 'Keystore', }, 'android.profile.storepass': { 'type': 'string', '_password': True, 'description': 'The password for your release keystore', 'title': 'Keystore password', }, 'android.profile.keyalias': { 'type': 'string', 'description': 'The alias of your release key', 'title': 'Key alias', }, 'android.profile.keypass': { 'type': 'string', '_password': True, 'description': 'The password for your release key', 'title': 'Key password' } } signing_info = lib.get_or_ask_for_local_config( build, required_info, question_title='Enter details for signing your app', ) signing_info['android.profile.keystore'] = lib.expand_relative_path( build, signing_info['android.profile.keystore']) return signing_info
def _search_for_sdk(build): # Some sensible places to look for the Android SDK possible_sdk = [ "C:/Program Files (x86)/Android/android-sdk/", "C:/Program Files/Android/android-sdk/", "C:/Android/android-sdk/", "C:/Android/android-sdk-windows/", "C:/android-sdk-windows/", "/Applications/android-sdk-macosx", path.expanduser("~/.forge/android-sdk-linux") ] user_sdk = build.tool_config.get('android.sdk') if user_sdk: # if android SDK supplied by user, normalise the path and add # it to the list of places to look user_sdk = lib.expand_relative_path(build, user_sdk) possible_sdk.insert(0, user_sdk) for directory in possible_sdk: if path.isdir(directory): found_sdk = directory if directory.endswith( '/') else directory + '/' return _create_path_info_from_sdk(found_sdk)
def _search_for_sdk(build): # Some sensible places to look for the Android SDK possible_sdk = [ "C:/Program Files (x86)/Android/android-sdk/", "C:/Program Files/Android/android-sdk/", "C:/Android/android-sdk/", "C:/Android/android-sdk-windows/", "C:/android-sdk-windows/", "/Applications/android-sdk-macosx", path.expanduser("~/.forge/android-sdk-linux") ] user_sdk = build.tool_config.get('android.sdk') if user_sdk: # if android SDK supplied by user, normalise the path and add # it to the list of places to look user_sdk = lib.expand_relative_path(build, user_sdk) possible_sdk.insert(0, user_sdk) for directory in possible_sdk: if path.isdir(directory): found_sdk = directory if directory.endswith('/') else directory + '/' return _create_path_info_from_sdk(found_sdk)
def package_web(build): interactive = build.tool_config.get('general.interactive', True) development = lib.expand_relative_path(build, 'development/web') output = lib.expand_relative_path(build, 'release/web/heroku') # deploy to Heroku with cd(development): api_key = _get_heroku_api_key(build) chosen_app = _get_app_to_push_to(build, api_key) if not path.isdir(output): os.makedirs(output) with cd(output): if not path.isdir('.git'): LOG.debug('Creating git repo') _git('init') LOG.debug('Create dummy first commit') with open('.forge.txt', 'w') as forge_file: forge_file.write('') _git('add', '.') _git('commit', '-am', 'first commit') # remove all previous files/folders except for .git! with cd(output): for f in os.listdir('.'): if not f == '.git': if path.isfile(f): os.remove(f) elif path.isdir(f): shutil.rmtree(f) # copy code from development to release! with cd(development): for f in os.listdir('.'): if path.isfile(f): shutil.copy2(f, output) elif path.isdir(f) and path.basename(f) != '.git': shutil.copytree(f, path.join(output, f), ignore=shutil.ignore_patterns('.git')) with cd(output): # setup with the specified remote LOG.debug('Setting up git remote for %s' % chosen_app) # remove any previous remote try: _git('remote', 'rm', 'heroku') except WebError: pass _git('remote', 'add', 'heroku', '[email protected]:%s.git' % chosen_app) # commit _git('add', '.') diff = _git('diff', 'HEAD') if not diff.strip(): # not interactive basically means we're using the trigger toolkit, where 'forge build' # doesn't really make sense if interactive: LOG.warning( "No app changes detected: did you forget to forge build?" ) else: LOG.warning( "No app changes detected, pushing to heroku anyway") else: _git('commit', '-am', 'forge package web') # push LOG.info('Deploying to %s.herokuapp.com' % chosen_app) # TODO: when running a packaged up toolkit there is no commandline... need to make sure # we can use the ssh key earlier somehow and ask for passphrase if not # also provide docs on how to use ssh-agent/pageant if not interactive: LOG.warning( 'If the packaging process hangs here, you need to set up ssh-agent or Pageant' ) # TODO: show our own one line progress bar when running non-verbosely push_output = _git('push', 'heroku', '--all', '--force', command_log_level=logging.INFO) if push_output.startswith('Everything up-to-date'): remote_output = _git('remote', '-v') remote_pattern = re.compile( r'[email protected]:(.*?).git \(fetch\)') remote_match = remote_pattern.search(remote_output) if remote_match: app_url = 'http://%s.herokuapp.com' % remote_match.group(1) _open_url(app_url) LOG.info('Deployed at %s' % app_url) else: deploy_pattern = re.compile( r'(http://[^ ]+) deployed to Heroku') deploy_match = deploy_pattern.search(push_output) if deploy_match: _open_url(deploy_match.group(1)) LOG.info('Deployed at %s' % deploy_match.group(1))
def package_web(build): interactive = build.tool_config.get('general.interactive', True) development = lib.expand_relative_path(build, 'development/web') output = lib.expand_relative_path(build, 'release/web/heroku') # deploy to Heroku with cd(development): api_key = _get_heroku_api_key(build) chosen_app = _get_app_to_push_to(build, api_key) if not path.isdir(output): os.makedirs(output) with cd(output): if not path.isdir('.git'): LOG.debug('Creating git repo') _git('init') LOG.debug('Create dummy first commit') with open('.forge.txt', 'w') as forge_file: forge_file.write('') _git('add', '.') _git('commit', '-am', 'first commit') # remove all previous files/folders except for .git! with cd(output): for f in os.listdir('.'): if not f == '.git': if path.isfile(f): os.remove(f) elif path.isdir(f): shutil.rmtree(f) # copy code from development to release! with cd(development): for f in os.listdir('.'): if path.isfile(f): shutil.copy2(f, output) elif path.isdir(f) and path.basename(f) != '.git': shutil.copytree(f, path.join(output, f), ignore=shutil.ignore_patterns('.git')) with cd(output): # setup with the specified remote LOG.debug('Setting up git remote for %s' % chosen_app) # remove any previous remote try: _git('remote', 'rm', 'heroku') except WebError: pass _git('remote', 'add', 'heroku', '[email protected]:%s.git' % chosen_app) # commit _git('add', '.') diff = _git('diff', 'HEAD') if not diff.strip(): # not interactive basically means we're using the trigger toolkit, where 'forge build' # doesn't really make sense if interactive: LOG.warning("No app changes detected: did you forget to forge build?") else: LOG.warning("No app changes detected, pushing to heroku anyway") else: _git('commit', '-am', 'forge package web') # push LOG.info('Deploying to %s.herokuapp.com' % chosen_app) # TODO: when running a packaged up toolkit there is no commandline... need to make sure # we can use the ssh key earlier somehow and ask for passphrase if not # also provide docs on how to use ssh-agent/pageant if not interactive: LOG.warning('If the packaging process hangs here, you need to set up ssh-agent or Pageant') # TODO: show our own one line progress bar when running non-verbosely push_output = _git('push', 'heroku', '--all', '--force', command_log_level=logging.INFO) if push_output.startswith('Everything up-to-date'): remote_output = _git('remote', '-v') remote_pattern = re.compile(r'[email protected]:(.*?).git \(fetch\)') remote_match = remote_pattern.search(remote_output) if remote_match: app_url = 'http://%s.herokuapp.com' % remote_match.group(1) _open_url(app_url) LOG.info('Deployed at %s' % app_url) else: deploy_pattern = re.compile(r'(http://[^ ]+) deployed to Heroku') deploy_match = deploy_pattern.search(push_output) if deploy_match: _open_url(deploy_match.group(1)) LOG.info('Deployed at %s' % deploy_match.group(1))
def package_web(build): interactive = build.tool_config.get("general.interactive", True) development = lib.expand_relative_path(build, "development/web") output = lib.expand_relative_path(build, "release/web/heroku") # deploy to Heroku with cd(development): api_key = _get_heroku_api_key(build) chosen_app = _get_app_to_push_to(build, api_key) if not path.isdir(output): os.makedirs(output) with cd(output): if not path.isdir(".git"): LOG.debug("Creating git repo") _git("init") LOG.debug("Create dummy first commit") with open(".forge.txt", "w") as forge_file: forge_file.write("") _git("add", ".") _git("commit", "-am", "first commit") # remove all previous files/folders except for .git! with cd(output): for f in os.listdir("."): if not f == ".git": if path.isfile(f): os.remove(f) elif path.isdir(f): shutil.rmtree(f) # copy code from development to release! with cd(development): for f in os.listdir("."): if path.isfile(f): shutil.copy2(f, output) elif path.isdir(f) and path.basename(f) != ".git": shutil.copytree(f, path.join(output, f), ignore=shutil.ignore_patterns(".git")) with cd(output): # setup with the specified remote LOG.debug("Setting up git remote for %s" % chosen_app) # remove any previous remote try: _git("remote", "rm", "heroku") except WebError: pass _git("remote", "add", "heroku", "[email protected]:%s.git" % chosen_app) # commit _git("add", ".") diff = _git("diff", "HEAD") if not diff.strip(): # not interactive basically means we're using the trigger toolkit, where 'forge build' # doesn't really make sense if interactive: LOG.warning("No app changes detected: did you forget to forge build?") else: LOG.warning("No app changes detected, pushing to heroku anyway") else: _git("commit", "-am", "forge package web") # push LOG.info("Deploying to %s.herokuapp.com" % chosen_app) # TODO: when running a packaged up toolkit there is no commandline... need to make sure # we can use the ssh key earlier somehow and ask for passphrase if not # also provide docs on how to use ssh-agent/pageant if not interactive: LOG.warning("If the packaging process hangs here, you need to set up ssh-agent or Pageant") # TODO: show our own one line progress bar when running non-verbosely push_output = _git("push", "heroku", "--all", "--force", command_log_level=logging.INFO) if push_output.startswith("Everything up-to-date"): remote_output = _git("remote", "-v") remote_pattern = re.compile(r"[email protected]:(.*?).git \(fetch\)") remote_match = remote_pattern.search(remote_output) if remote_match: app_url = "http://%s.herokuapp.com" % remote_match.group(1) _open_url(app_url) LOG.info("Deployed at %s" % app_url) else: deploy_pattern = re.compile(r"(http://[^ ]+) deployed to Heroku") deploy_match = deploy_pattern.search(push_output) if deploy_match: _open_url(deploy_match.group(1)) LOG.info("Deployed at %s" % deploy_match.group(1))