コード例 #1
0
def command_create():
    if os.path.exists(defaults.SRC_DIR):
        raise ForgeError(
            'Source folder "%s" already exists, if you really want to create a new app you will need to remove it!'
            % defaults.SRC_DIR)

    questions = {
        'description': 'Enter details for app',
        'properties': {
            'name': {
                'type':
                'string',
                'title':
                'App Name',
                'description':
                'This name is what your application will be called on devices. You can change it later through config.json.'
            }
        }
    }
    answers = cli.ask_question({'schema': questions})
    if 'name' in answers and answers['name']:
        forge.settings['name'] = answers['name']

    username = forge.settings['username']
    app_uuid = str(uuid.uuid4().hex)
    app_name = forge.settings['name']

    # generate app
    with open_file(path.join(config_dir, 'manifest.json')) as manifest_file:
        manifest = json.loads(manifest_file.read())
        zipf = InMemoryZip()
        for item in manifest:
            initial_file = template_file(
                config_dir, item["path"], item["template"], (
                    ('${username}', username),
                    ('${uuid}', app_uuid),
                    ('${name}', app_name),
                    ('${platform_version}', forge.settings['LAST_STABLE']),
                ))
            zipf.writestr(item["path"], initial_file)
        with zipfile.ZipFile(StringIO(zipf.read())) as myzip:
            myzip.extractall()

    LOG.info('App structure created. To proceed:')
    LOG.info('1) Put your code in the "%s" folder' % defaults.SRC_DIR)
    LOG.info('2) Run %s build to make a build' % ENTRY_POINT_NAME)
コード例 #2
0
def command_create():
	if os.path.exists(defaults.SRC_DIR):
		raise ForgeError('Source folder "%s" already exists, if you really want to create a new app you will need to remove it!' % defaults.SRC_DIR)

	questions = {
		'description': 'Enter details for app',
		'properties': {
			'name': {
				'type': 'string',
				'title': 'App Name',
				'description': 'This name is what your application will be called on devices. You can change it later through config.json.'
			}
		}
	}
	answers = cli.ask_question({ 'schema': questions })
	if 'name' in answers and answers['name']:
		forge.settings['name'] = answers['name']

	username = forge.settings['username']
	app_uuid = str(uuid.uuid4().hex)
	app_name = forge.settings['name']

	# generate app
	with open_file(path.join(config_dir, 'manifest.json')) as manifest_file:
		manifest = json.loads(manifest_file.read())
		zipf = InMemoryZip()
		for item in manifest:
			initial_file = template_file(config_dir, item["path"], item["template"],
				( ('${username}', username),
				  ('${uuid}', app_uuid),
				  ('${name}', app_name),
				  ('${platform_version}', forge.settings['LAST_STABLE']), ))
			zipf.writestr(item["path"], initial_file)
		with zipfile.ZipFile(StringIO(zipf.read())) as myzip:
			myzip.extractall()
	
	LOG.info('App structure created. To proceed:')
	LOG.info('1) Put your code in the "%s" folder' % defaults.SRC_DIR)
	LOG.info('2) Run %s build to make a build' % ENTRY_POINT_NAME)
コード例 #3
0
ファイル: main.py プロジェクト: mobilipia/build-tools
def _dispatch_command(command, other_args):
	"""Runs our subcommand in a separate thread, and handles events emitted by it"""
	call = None
	task_thread = None
	try:
		other_other_args = handle_secondary_options(command, other_args)

		subcommand = COMMANDS[command]

		# setup enough stuff so the target function can communicate back using events
		call = async.Call(
			call_id=0,
			target=subcommand,
			args=(other_other_args, ),
			input=Queue.Queue(),
			output=Queue.Queue(),
		)
		async.set_current_call(call, thread_local=True)

		# capture logging on any thread but this one and turn it into events
		handler = async.CallHandler(call)
		handler.setLevel(logging.DEBUG)

		current_thread = threading.current_thread().name
		filtered_handler = FilterHandler(handler, lambda r: r.threadName != current_thread)
		filtered_handler.setLevel(logging.DEBUG)

		logging.root.addHandler(filtered_handler)
		logging.root.setLevel(logging.DEBUG)

		task_thread = threading.Thread(target=call.run)
		task_thread.daemon = True
		task_thread.start()

		while True:
			try:
				# KeyboardInterrupts aren't seen until the .get() completes :S
				# So we set a timeout here to make sure we receive it
				next_event = call._output.get(block=True, timeout=1)
			except Queue.Empty:
				continue
			event_type = next_event['type']

			if event_type == 'question':
				answer = cli.ask_question(next_event)

				call.input({
					'eventId': next_event['eventId'],
					'data': answer,
				})

			if event_type == 'progressStart':
				cli.start_progress(next_event)

			if event_type == 'progressEnd':
				cli.end_progress(next_event)

			if event_type == 'progress':
				cli.progress_bar(next_event)

			# TODO: handle situation of logging while progress bar is running
			# e.g. extra newline before using LOG.log
			if event_type == 'log':
				# all logging in our task thread comes out as events, which we then
				# plug back into the logging system, which then directs it to file/console output
				logging_level = getattr(logging, next_event.get('level', 'DEBUG'))
				LOG.log(logging_level, next_event.get('message', ''))

			elif event_type == 'success':
				return 0

			elif event_type == 'error':
				# re-raise exception originally from other thread/process
				try:
					raise call.exception

				except RunningInForgeRoot:
					LOG.error(
						"You're trying to run commands in the build tools directory.\n"
						"You need to move to another directory outside of this one first.\n"
					)

				except UpdateRequired:
					LOG.info("An update to these command line tools is required, downloading...")

					# TODO: refactor so that we don't need to instantiate Remote here
					config = build_config.load()
					remote = Remote(config)
					try:
						remote.update()
						LOG.info("Update complete, run your command again to continue")

					except Exception as e:
						LOG.error("Upgrade process failed: %s" % e)
						LOG.debug("%s" % traceback.format_exc(e))
						LOG.error("You can get the tools from https://trigger.io/api/latest_tools and extract them yourself")
						LOG.error("Contact [email protected] if you have any further issues")

				except ForgeError as e:
					# thrown by us, expected
					LOG.error(next_event.get('message'))
					LOG.debug(str(next_event.get('traceback')))

				except Exception:
					LOG.error("Something went wrong that we didn't expect:")
					LOG.error(next_event.get('message'))
					LOG.debug(str(next_event.get('traceback')))

					LOG.error("See %s for more details" % ERROR_LOG_FILE)
					LOG.error("Please contact [email protected]")

				return 1
	except KeyboardInterrupt:
		sys.stdout.write('\n')
		LOG.info('Exiting...')
		if call:
			call.interrupt()
			task_thread.join(timeout=5)
		return 1