def init_base_project(project_dir): with fs.cd(project_dir): config = ProjectConfig() config.save() dir_to_readme = [ (config.get_optional_dir("src"), None), (config.get_optional_dir("include"), init_include_readme), (config.get_optional_dir("lib"), init_lib_readme), (config.get_optional_dir("test"), init_test_readme), ] for (path, cb) in dir_to_readme: if os.path.isdir(path): continue os.makedirs(path) if cb: cb(path)
def cli(ctx, **options): storage_cmds = ("install", "uninstall", "update", "list") # skip commands that don't need storage folder if ctx.invoked_subcommand not in storage_cmds or ( len(ctx.args) == 2 and ctx.args[1] in ("-h", "--help") ): return storage_dirs = list(options["storage_dir"]) if options["global"]: storage_dirs.append(get_project_global_lib_dir()) if not storage_dirs: if is_platformio_project(): storage_dirs = [get_project_dir()] elif is_ci(): storage_dirs = [get_project_global_lib_dir()] click.secho( "Warning! Global library storage is used automatically. " "Please use `platformio lib --global %s` command to remove " "this warning." % ctx.invoked_subcommand, fg="yellow", ) if not storage_dirs: raise NotGlobalLibDir( get_project_dir(), get_project_global_lib_dir(), ctx.invoked_subcommand ) in_silence = PlatformioCLI.in_silence() ctx.meta[CTX_META_PROJECT_ENVIRONMENTS_KEY] = options["environment"] ctx.meta[CTX_META_INPUT_DIRS_KEY] = storage_dirs ctx.meta[CTX_META_STORAGE_DIRS_KEY] = [] ctx.meta[CTX_META_STORAGE_LIBDEPS_KEY] = {} for storage_dir in storage_dirs: if not is_platformio_project(storage_dir): ctx.meta[CTX_META_STORAGE_DIRS_KEY].append(storage_dir) continue with fs.cd(storage_dir): config = ProjectConfig.get_instance( os.path.join(storage_dir, "platformio.ini") ) config.validate(options["environment"], silent=in_silence) libdeps_dir = config.get_optional_dir("libdeps") for env in config.envs(): if options["environment"] and env not in options["environment"]: continue storage_dir = os.path.join(libdeps_dir, env) ctx.meta[CTX_META_STORAGE_DIRS_KEY].append(storage_dir) ctx.meta[CTX_META_STORAGE_LIBDEPS_KEY][storage_dir] = config.get( "env:" + env, "lib_deps", [] )
def __init__(self, options=None): """ Called by PlatformIO to pass context """ miniterm.Transform.__init__(self) self.options = options or {} self.project_dir = self.options.get("project_dir") self.environment = self.options.get("environment") self.config = ProjectConfig.get_instance() if not self.environment: default_envs = self.config.default_envs() if default_envs: self.environment = default_envs[0] elif self.config.envs(): self.environment = self.config.envs()[0]
def add_project_items(self, psync): with util.cd(self.options["project_dir"]): cfg = ProjectConfig.get_instance( os.path.join(self.options["project_dir"], "platformio.ini")) psync.add_item(cfg.path, "platformio.ini") psync.add_item(cfg.get_optional_dir("shared"), "shared") psync.add_item(cfg.get_optional_dir("boards"), "boards") if self.options["force_remote"]: self._add_project_source_items(cfg, psync) else: self._add_project_binary_items(cfg, psync) if self.command == "test": psync.add_item(cfg.get_optional_dir("test"), "test")
def init_base_project(project_dir): ProjectConfig(join(project_dir, "platformio.ini")).save() with fs.cd(project_dir): dir_to_readme = [ (get_project_src_dir(), None), (get_project_include_dir(), init_include_readme), (get_project_lib_dir(), init_lib_readme), (get_project_test_dir(), init_test_readme), ] for (path, cb) in dir_to_readme: if isdir(path): continue makedirs(path) if cb: cb(path)
def get_project_examples(): result = [] for manifest in PlatformManager().get_installed(): examples_dir = os.path.join(manifest["__pkg_dir"], "examples") if not os.path.isdir(examples_dir): continue items = [] for project_dir, _, __ in os.walk(examples_dir): project_description = None try: config = ProjectConfig( os.path.join(project_dir, "platformio.ini")) config.validate(silent=True) project_description = config.get("platformio", "description") except ProjectError: continue path_tokens = project_dir.split(os.path.sep) items.append({ "name": "/".join(path_tokens[path_tokens.index("examples") + 1:]), "path": project_dir, "description": project_description, }) result.append({ "platform": { "title": manifest["title"], "version": manifest["version"], }, "items": sorted(items, key=lambda item: item["name"]), }) return sorted(result, key=lambda data: data["platform"]["title"])
def __init__(self, manifest_path): self.manifest_path = manifest_path self.silent = False self.verbose = False self._manifest = fs.load_json(manifest_path) self._BOARDS_CACHE = {} self._custom_packages = None self.config = ProjectConfig.get_instance() self.pm = PackageManager(self.config.get_optional_dir("packages"), self.package_repositories) self._src_manifest = None src_manifest_path = self.pm.get_src_manifest_path(self.get_dir()) if src_manifest_path: self._src_manifest = fs.load_json(src_manifest_path)
def get_project_optional_dir(name, default=None): project_dir = get_project_dir() config = ProjectConfig.get_instance(join(project_dir, "platformio.ini")) optional_dir = config.get("platformio", name) if not optional_dir: return default if "$PROJECT_HASH" in optional_dir: optional_dir = optional_dir.replace( "$PROJECT_HASH", "%s-%s" % (basename(project_dir), sha1( hashlib_encode_data(project_dir)).hexdigest()[:10])) if optional_dir.startswith("~"): optional_dir = expanduser(optional_dir) return realpath(optional_dir)
def load_config(): items = ProjectConfig().items('features') for key in items: feature = key[0].upper() if not feature in FEATURE_CONFIG: FEATURE_CONFIG[feature] = {'lib_deps': []} add_to_feat_cnf(feature, key[1]) # Add options matching custom_marlin.MY_OPTION to the pile all_opts = env.GetProjectOptions() for n in all_opts: mat = re.match(r'custom_marlin\.(.+)', n[0]) if mat: try: val = env.GetProjectOption(n[0]) except: val = None if val: add_to_feat_cnf(mat.group(1).upper(), val)
def test_init_custom_framework(clirunner, validate_cliresult): with clirunner.isolated_filesystem(): result = clirunner.invoke( cmd_init, ["-b", "teensy31", "--project-option", "framework=mbed"]) validate_cliresult(result) validate_pioproject(getcwd()) config = ProjectConfig(join(getcwd(), "platformio.ini")) config.validate() expected_result = dict(platform="teensy", board="teensy31", framework=["mbed"]) assert config.has_section("env:teensy31") assert sorted(config.items(env="teensy31", as_dict=True).items()) == sorted( expected_result.items())
def test_init_enable_auto_uploading(clirunner, validate_cliresult): with clirunner.isolated_filesystem(): result = clirunner.invoke( cmd_init, ["-b", "uno", "--project-option", "targets=upload"]) validate_cliresult(result) validate_pioproject(getcwd()) config = ProjectConfig(join(getcwd(), "platformio.ini")) config.validate() expected_result = dict(targets=["upload"], platform="atmelavr", board="uno", framework=["arduino"]) assert config.has_section("env:uno") assert sorted(config.items(env="uno", as_dict=True).items()) == sorted( expected_result.items())
def test_update_and_clear(tmpdir_factory): tmpdir = tmpdir_factory.mktemp("project") tmpdir.join("platformio.ini").write(""" [platformio] extra_configs = a.ini, b.ini [env:myenv] board = myboard """) config = ProjectConfig(tmpdir.join("platformio.ini").strpath) assert config.sections() == ["platformio", "env:myenv"] config.update([["mysection", [("opt1", "value1"), ("opt2", "value2")]]], clear=True) assert config.as_tuple() == [("mysection", [("opt1", "value1"), ("opt2", "value2")])]
def save_project_libdeps(project_dir, specs, environments=None, action="add"): config = ProjectConfig.get_instance( os.path.join(project_dir, "platformio.ini")) config.validate(environments) for env in config.envs(): if environments and env not in environments: continue config.expand_interpolations = False lib_deps = [] try: lib_deps = ignore_deps_by_specs( config.get("env:" + env, "lib_deps"), specs) except InvalidProjectConfError: pass if action == "add": lib_deps.extend(spec.as_dependency() for spec in specs) if lib_deps: config.set("env:" + env, "lib_deps", lib_deps) elif config.has_option("env:" + env, "lib_deps"): config.remove_option("env:" + env, "lib_deps") config.save()
def project_config(project_dir, json_output): if not is_platformio_project(project_dir): raise NotPlatformIOProjectError(project_dir) with fs.cd(project_dir): config = ProjectConfig.get_instance() if json_output: return click.echo(config.to_json()) click.echo("Computed project configuration for %s" % click.style(project_dir, fg="cyan")) for section, options in config.as_tuple(): click.secho(section, fg="cyan") click.echo("-" * len(section)) click.echo( tabulate( [(name, "=", "\n".join(value) if isinstance(value, list) else value) for name, value in options], tablefmt="plain", )) click.echo() return None
def get_best_envname(project_dir, boards=None): config = ProjectConfig.get_instance(join(project_dir, "platformio.ini")) config.validate() envname = None default_envs = config.default_envs() if default_envs: envname = default_envs[0] if not boards: return envname for env in config.envs(): if not boards: return env if not envname: envname = env items = config.items(env=env, as_dict=True) if "board" in items and items.get("board") in boards: return env return envname
def load_features(): blab("========== Gather [features] entries...") for key in ProjectConfig().items('features'): feature = key[0].upper() if not feature in FEATURE_CONFIG: FEATURE_CONFIG[feature] = {'lib_deps': []} add_to_feat_cnf(feature, key[1]) # Add options matching custom_marlin.MY_OPTION to the pile blab("========== Gather custom_marlin entries...") for n in env.GetProjectOptions(): key = n[0] mat = re.match(r'custom_marlin\.(.+)', key) if mat: try: val = env.GetProjectOption(key) except: val = None if val: opt = mat[1].upper() blab("%s.custom_marlin.%s = '%s'" % (env['PIOENV'], opt, val)) add_to_feat_cnf(opt, val)
def test_init_special_board(clirunner, validate_cliresult): with clirunner.isolated_filesystem(): result = clirunner.invoke(cmd_init, ["-b", "uno"]) validate_cliresult(result) validate_pioproject(getcwd()) result = clirunner.invoke(cmd_boards, ["Arduino Uno", "--json-output"]) validate_cliresult(result) boards = json.loads(result.output) config = ProjectConfig(join(getcwd(), "platformio.ini")) config.validate() expected_result = dict(platform=str(boards[0]['platform']), board="uno", framework=[str(boards[0]['frameworks'][0])]) assert config.has_section("env:uno") assert sorted(config.items(env="uno", as_dict=True).items()) == sorted( expected_result.items())
def cli(ctx, project_dir, project_conf, environment, verbose, interface, __unprocessed): app.set_session_var("custom_project_conf", project_conf) # use env variables from Eclipse or CLion for sysenv in ("CWD", "PWD", "PLATFORMIO_PROJECT_DIR"): if is_platformio_project(project_dir): break if os.getenv(sysenv): project_dir = os.getenv(sysenv) with fs.cd(project_dir): config = ProjectConfig.get_instance(project_conf) config.validate(envs=[environment] if environment else None) env_name = environment or helpers.get_default_debug_env(config) env_options = config.items(env=env_name, as_dict=True) if not set(env_options.keys()) >= set(["platform", "board"]): raise ProjectEnvsNotAvailableError() debug_options = helpers.validate_debug_options(ctx, env_options) assert debug_options if not interface: return helpers.predebug_project(ctx, project_dir, env_name, False, verbose) configuration = load_project_ide_data(project_dir, env_name) if not configuration: raise DebugInvalidOptionsError("Could not load debug configuration") if "--version" in __unprocessed: result = proc.exec_command([configuration["gdb_path"], "--version"]) if result["returncode"] == 0: return click.echo(result["out"]) raise exception.PlatformioException("\n".join( [result["out"], result["err"]])) try: fs.ensure_udev_rules() except exception.InvalidUdevRules as e: click.echo( helpers.escape_gdbmi_stream("~", str(e) + "\n") if helpers.is_gdbmi_mode() else str(e) + "\n", nl=False, ) debug_options["load_cmds"] = helpers.configure_esp32_load_cmds( debug_options, configuration) rebuild_prog = False preload = debug_options["load_cmds"] == ["preload"] load_mode = debug_options["load_mode"] if load_mode == "always": rebuild_prog = preload or not helpers.has_debug_symbols( configuration["prog_path"]) elif load_mode == "modified": rebuild_prog = helpers.is_prog_obsolete( configuration["prog_path"]) or not helpers.has_debug_symbols( configuration["prog_path"]) else: rebuild_prog = not isfile(configuration["prog_path"]) if preload or (not rebuild_prog and load_mode != "always"): # don't load firmware through debug server debug_options["load_cmds"] = [] if rebuild_prog: if helpers.is_gdbmi_mode(): click.echo( helpers.escape_gdbmi_stream( "~", "Preparing firmware for debugging...\n"), nl=False, ) stream = helpers.GDBMIConsoleStream() with util.capture_std_streams(stream): helpers.predebug_project(ctx, project_dir, env_name, preload, verbose) stream.close() else: click.echo("Preparing firmware for debugging...") helpers.predebug_project(ctx, project_dir, env_name, preload, verbose) # save SHA sum of newly created prog if load_mode == "modified": helpers.is_prog_obsolete(configuration["prog_path"]) if not isfile(configuration["prog_path"]): raise DebugInvalidOptionsError("Program/firmware is missed") # run debugging client inject_contrib_pysite() # pylint: disable=import-outside-toplevel from platformio.commands.debug.process.client import GDBClient, reactor client = GDBClient(project_dir, __unprocessed, debug_options, env_options) client.spawn(configuration["gdb_path"], configuration["prog_path"]) signal.signal(signal.SIGINT, lambda *args, **kwargs: None) reactor.run() return True
def config_update_description(path, text): config = ProjectConfig(path, parse_extra=False, expand_interpolations=False) if not config.has_section("platformio"): config.add_section("platformio") if text: config.set("platformio", "description", text) else: if config.has_option("platformio", "description"): config.remove_option("platformio", "description") if not config.options("platformio"): config.remove_section("platformio") return config.save()
def config_dump(path, data): config = ProjectConfig(path, parse_extra=False, expand_interpolations=False) config.update(data, clear=True) return config.save()
def config_load(path): return ProjectConfig(path, parse_extra=False, expand_interpolations=False).as_tuple()
def fill_project_envs(ctx, project_dir, board_ids, project_option, env_prefix, force_download): config = ProjectConfig(join(project_dir, "platformio.ini"), parse_extra=False) used_boards = [] for section in config.sections(): cond = [ section.startswith("env:"), config.has_option(section, "board") ] if all(cond): used_boards.append(config.get(section, "board")) pm = PlatformManager() used_platforms = [] modified = False for id_ in board_ids: board_config = pm.board_config(id_) used_platforms.append(board_config['platform']) if id_ in used_boards: continue used_boards.append(id_) modified = True envopts = {"platform": board_config['platform'], "board": id_} # find default framework for board frameworks = board_config.get("frameworks") if frameworks: envopts['framework'] = frameworks[0] for item in project_option: if "=" not in item: continue _name, _value = item.split("=", 1) envopts[_name.strip()] = _value.strip() section = "env:%s%s" % (env_prefix, id_) config.add_section(section) for option, value in envopts.items(): config.set(section, option, value) if force_download and used_platforms: _install_dependent_platforms(ctx, used_platforms) if modified: config.save() config.reset_instances()
def project_init( ctx, # pylint: disable=R0913 project_dir, board, ide, environment, project_option, env_prefix, silent, ): if not silent: if project_dir == os.getcwd(): click.secho("\nThe current working directory", fg="yellow", nl=False) click.secho(" %s " % project_dir, fg="cyan", nl=False) click.secho("will be used for the project.", fg="yellow") click.echo("") click.echo("The next files/directories have been created in %s" % click.style(project_dir, fg="cyan")) click.echo("%s - Put project header files here" % click.style("include", fg="cyan")) click.echo("%s - Put here project specific (private) libraries" % click.style("lib", fg="cyan")) click.echo("%s - Put project source files here" % click.style("src", fg="cyan")) click.echo("%s - Project Configuration File" % click.style("platformio.ini", fg="cyan")) is_new_project = not is_platformio_project(project_dir) if is_new_project: init_base_project(project_dir) if environment: update_project_env(project_dir, environment, project_option) elif board: update_board_envs(ctx, project_dir, board, project_option, env_prefix, ide is not None) if ide: with fs.cd(project_dir): config = ProjectConfig.get_instance( os.path.join(project_dir, "platformio.ini")) config.validate() pg = ProjectGenerator(config, environment or get_best_envname(config, board), ide) pg.generate() if is_new_project: init_cvs_ignore(project_dir) if silent: return if ide: click.secho( "\nProject has been successfully %s including configuration files " "for `%s` IDE." % ("initialized" if is_new_project else "updated", ide), fg="green", ) else: click.secho( "\nProject has been successfully %s! Useful commands:\n" "`pio run` - process/build project from the current directory\n" "`pio run --target upload` or `pio run -t upload` " "- upload firmware to a target\n" "`pio run --target clean` - clean project (remove compiled files)" "\n`pio run --help` - additional information" % ("initialized" if is_new_project else "updated"), fg="green", )
def cli( environment, project_dir, project_conf, pattern, flags, severity, silent, verbose, json_output, fail_on_defect, skip_packages, ): app.set_session_var("custom_project_conf", project_conf) # find project directory on upper level if isfile(project_dir): project_dir = find_project_dir_above(project_dir) results = [] with fs.cd(project_dir): config = ProjectConfig.get_instance(project_conf) config.validate(environment) default_envs = config.default_envs() for envname in config.envs(): skipenv = any([ environment and envname not in environment, not environment and default_envs and envname not in default_envs, ]) env_options = config.items(env=envname, as_dict=True) env_dump = [] for k, v in env_options.items(): if k not in ("platform", "framework", "board"): continue env_dump.append( "%s: %s" % (k, ", ".join(v) if isinstance(v, list) else v)) default_patterns = [ config.get_optional_dir("src"), config.get_optional_dir("include"), ] tool_options = dict( verbose=verbose, silent=silent, patterns=pattern or env_options.get("check_patterns", default_patterns), flags=flags or env_options.get("check_flags"), severity=[ DefectItem.SEVERITY_LABELS[DefectItem.SEVERITY_HIGH] ] if silent else severity or config.get("env:" + envname, "check_severity"), skip_packages=skip_packages or env_options.get("check_skip_packages"), ) for tool in config.get("env:" + envname, "check_tool"): if skipenv: results.append({"env": envname, "tool": tool}) continue if not silent and not json_output: print_processing_header(tool, envname, env_dump) ct = CheckToolFactory.new(tool, project_dir, config, envname, tool_options) result = {"env": envname, "tool": tool, "duration": time()} rc = ct.check(on_defect_callback=None if ( json_output or verbose ) else lambda defect: click.echo(repr(defect))) result["defects"] = ct.get_defects() result["duration"] = time() - result["duration"] result["succeeded"] = rc == 0 if fail_on_defect: result["succeeded"] = rc == 0 and not any( DefectItem.SEVERITY_LABELS[ d.severity] in fail_on_defect for d in result["defects"]) result["stats"] = collect_component_stats(result) results.append(result) if verbose: click.echo("\n".join(repr(d) for d in result["defects"])) if not json_output and not silent: if rc != 0: click.echo("Error: %s failed to perform check! Please " "examine tool output in verbose mode." % tool) elif not result["defects"]: click.echo("No defects found") print_processing_footer(result) if json_output: click.echo(dump_json_to_unicode(results_to_json(results))) elif not silent: print_check_summary(results) command_failed = any(r.get("succeeded") is False for r in results) if command_failed: raise exception.ReturnErrorCode(1)
def test_update_and_save(tmpdir_factory): tmpdir = tmpdir_factory.mktemp("project") tmpdir.join("platformio.ini").write( """ [platformio] extra_configs = a.ini, b.ini [env:myenv] board = myboard """ ) config = ProjectConfig(tmpdir.join("platformio.ini").strpath) assert config.envs() == ["myenv"] assert config.as_tuple()[0][1][0][1] == ["a.ini", "b.ini"] config.update( [ ["platformio", [("extra_configs", ["extra.ini"])]], ["env:myenv", [("framework", ["espidf", "arduino"])]], ["check_types", [("float_option", 13.99), ("bool_option", True)]], ] ) assert config.get("platformio", "extra_configs") == ["extra.ini"] config.remove_section("platformio") assert config.as_tuple() == [ ("env:myenv", [("board", "myboard"), ("framework", ["espidf", "arduino"])]), ("check_types", [("float_option", "13.99"), ("bool_option", "yes")]), ] config.save() contents = tmpdir.join("platformio.ini").read() assert contents[-4:] == "yes\n" lines = [ line.strip() for line in contents.split("\n") if line.strip() and not line.startswith((";", "#")) ] assert lines == [ "[env:myenv]", "board = myboard", "framework =", "espidf", "arduino", "[check_types]", "float_option = 13.99", "bool_option = yes", ]
def cli(ctx, project_dir, project_conf, environment, verbose, interface, __unprocessed): # use env variables from Eclipse or CLion for sysenv in ("CWD", "PWD", "PLATFORMIO_PROJECT_DIR"): if is_platformio_project(project_dir): break if os.getenv(sysenv): project_dir = os.getenv(sysenv) with util.cd(project_dir): config = ProjectConfig.get_instance( project_conf or join(project_dir, "platformio.ini")) config.validate(envs=[environment] if environment else None) env_name = environment or helpers.get_default_debug_env(config) env_options = config.items(env=env_name, as_dict=True) if not set(env_options.keys()) >= set(["platform", "board"]): raise exception.ProjectEnvsNotAvailable() debug_options = helpers.validate_debug_options(ctx, env_options) assert debug_options if not interface: return helpers.predebug_project(ctx, project_dir, env_name, False, verbose) configuration = load_project_ide_data(project_dir, env_name) if not configuration: raise exception.DebugInvalidOptions( "Could not load debug configuration") if "--version" in __unprocessed: result = util.exec_command([configuration['gdb_path'], "--version"]) if result['returncode'] == 0: return click.echo(result['out']) raise exception.PlatformioException("\n".join( [result['out'], result['err']])) try: util.ensure_udev_rules() except NameError: pass except exception.InvalidUdevRules as e: for line in str(e).split("\n") + [""]: click.echo( ('~"%s\\n"' if helpers.is_mi_mode(__unprocessed) else "%s") % line) debug_options['load_cmds'] = helpers.configure_esp32_load_cmds( debug_options, configuration) rebuild_prog = False preload = debug_options['load_cmds'] == ["preload"] load_mode = debug_options['load_mode'] if load_mode == "always": rebuild_prog = ( preload or not helpers.has_debug_symbols(configuration['prog_path'])) elif load_mode == "modified": rebuild_prog = ( helpers.is_prog_obsolete(configuration['prog_path']) or not helpers.has_debug_symbols(configuration['prog_path'])) else: rebuild_prog = not isfile(configuration['prog_path']) if preload or (not rebuild_prog and load_mode != "always"): # don't load firmware through debug server debug_options['load_cmds'] = [] if rebuild_prog: if helpers.is_mi_mode(__unprocessed): click.echo('~"Preparing firmware for debugging...\\n"') output = helpers.GDBBytesIO() with util.capture_std_streams(output): helpers.predebug_project(ctx, project_dir, env_name, preload, verbose) output.close() else: click.echo("Preparing firmware for debugging...") helpers.predebug_project(ctx, project_dir, env_name, preload, verbose) # save SHA sum of newly created prog if load_mode == "modified": helpers.is_prog_obsolete(configuration['prog_path']) if not isfile(configuration['prog_path']): raise exception.DebugInvalidOptions("Program/firmware is missed") # run debugging client inject_contrib_pysite() from platformio.commands.debug.client import GDBClient, reactor client = GDBClient(project_dir, __unprocessed, debug_options, env_options) client.spawn(configuration['gdb_path'], configuration['prog_path']) signal.signal(signal.SIGINT, lambda *args, **kwargs: None) reactor.run() return True
def cli( # pylint: disable=redefined-builtin ctx, environment, ignore, filter, upload_port, test_port, project_dir, project_conf, without_building, without_uploading, without_testing, no_reset, monitor_rts, monitor_dtr, verbose): with fs.cd(project_dir): test_dir = get_project_test_dir() if not isdir(test_dir): raise exception.TestDirNotExists(test_dir) test_names = get_test_names(test_dir) config = ProjectConfig.get_instance( project_conf or join(project_dir, "platformio.ini")) config.validate(envs=environment) click.echo("Verbose mode can be enabled via `-v, --verbose` option") click.secho("Collected %d items" % len(test_names), bold=True) results = [] default_envs = config.default_envs() for testname in test_names: for envname in config.envs(): section = "env:%s" % envname # filter and ignore patterns patterns = dict(filter=list(filter), ignore=list(ignore)) for key in patterns: patterns[key].extend( config.get(section, "test_%s" % key, [])) skip_conditions = [ environment and envname not in environment, not environment and default_envs and envname not in default_envs, testname != "*" and patterns['filter'] and not any([fnmatch(testname, p) for p in patterns['filter']]), testname != "*" and any([fnmatch(testname, p) for p in patterns['ignore']]), ] if any(skip_conditions): results.append({"env": envname, "test": testname}) continue click.echo() print_processing_header(testname, envname) cls = (NativeTestProcessor if config.get(section, "platform") == "native" else EmbeddedTestProcessor) tp = cls( ctx, testname, envname, dict(project_config=config, project_dir=project_dir, upload_port=upload_port, test_port=test_port, without_building=without_building, without_uploading=without_uploading, without_testing=without_testing, no_reset=no_reset, monitor_rts=monitor_rts, monitor_dtr=monitor_dtr, verbose=verbose)) result = { "env": envname, "test": testname, "duration": time(), "succeeded": tp.process() } result['duration'] = time() - result['duration'] results.append(result) print_processing_footer(result) if without_testing: return print_testing_summary(results) command_failed = any(r.get("succeeded") is False for r in results) if command_failed: raise exception.ReturnErrorCode(1)
def __init__(self, package_dir=None): self.config = ProjectConfig.get_instance() super(LibraryManager, self).__init__(package_dir or self.config.get_optional_dir("globallib"))
def _process_cmd_run_or_test( # pylint: disable=too-many-locals,too-many-branches self, command, options): assert options and "project_id" in options project_dir = join(self.working_dir, "projects", options["project_id"]) origin_pio_ini = join(project_dir, "platformio.ini") back_pio_ini = join(project_dir, "platformio.ini.bak") # remove insecure project options try: conf = ProjectConfig(origin_pio_ini) if isfile(back_pio_ini): os.remove(back_pio_ini) os.rename(origin_pio_ini, back_pio_ini) # cleanup if conf.has_section("platformio"): for opt in conf.options("platformio"): if opt.endswith("_dir"): conf.remove_option("platformio", opt) else: conf.add_section("platformio") conf.set("platformio", "build_dir", ".pio/build") conf.save(origin_pio_ini) # restore A/M times os.utime(origin_pio_ini, (getatime(back_pio_ini), getmtime(back_pio_ini))) except NotPlatformIOProjectError as e: raise pb.Error(str(e)) cmd_args = ["platformio", "--force", command, "-d", project_dir] for env in options.get("environment", []): cmd_args.extend(["-e", env]) for target in options.get("target", []): cmd_args.extend(["-t", target]) for ignore in options.get("ignore", []): cmd_args.extend(["-i", ignore]) if options.get("upload_port", False): cmd_args.extend(["--upload-port", options.get("upload_port")]) if options.get("test_port", False): cmd_args.extend(["--test-port", options.get("test_port")]) if options.get("disable_auto_clean", False): cmd_args.append("--disable-auto-clean") if options.get("without_building", False): cmd_args.append("--without-building") if options.get("without_uploading", False): cmd_args.append("--without-uploading") if options.get("silent", False): cmd_args.append("-s") if options.get("verbose", False): cmd_args.append("-v") paused_acs = [] for ac in self._acs.values(): if not isinstance(ac, SerialPortAsyncCmd): continue self.log.info("Pause active monitor at {port}", port=ac.options["port"]) ac.pause() paused_acs.append(ac) def _cb_on_end(): if isfile(back_pio_ini): if isfile(origin_pio_ini): os.remove(origin_pio_ini) os.rename(back_pio_ini, origin_pio_ini) for ac in paused_acs: ac.unpause() self.log.info("Unpause active monitor at {port}", port=ac.options["port"]) return self._defer_async_cmd( ProcessAsyncCmd( { "executable": proc.where_is_program("platformio"), "args": cmd_args }, on_end_callback=_cb_on_end, ))
for env in cfg.envs(): platform = cfg.get("env:{}".format(env), "platform") if "espressif8266" in platform: yield {"chip": "esp8266", "env": env} elif "espressif32" in platform: yield {"chip": "esp32", "env": env} else: raise ValueError("Unknown `platform = {}` for `[env:{}]`".format( platform, env)) def filter_jobs(jobs, ignore=("spec_", )): for job in jobs: if job["env"].startswith(ignore): continue yield job if __name__ == "__main__": jobs = list(filter_jobs(get_jobs(ProjectConfig.get_instance()))) sort = [] for job in jobs: if job["chip"] == "esp8266": sort.append(job["env"]) sort.sort(key=str.casefold) serialized = json.dumps({"include": jobs}) print("::set-output name=matrix::{}".format(serialized))