예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
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))
예제 #8
0
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))
예제 #9
0
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))