Example #1
0
 def process_extra_options(self):
     with fs.cd(self.path):
         self.env.ProcessFlags(self.build_flags)
         if self.extra_script:
             self.env.SConscriptChdir(1)
             self.env.SConscript(realpath(self.extra_script),
                                 exports={
                                     "env": self.env,
                                     "pio_lib_builder": self
                                 })
         self.env.ProcessUnFlags(self.build_unflags)
Example #2
0
def GetExtraScripts(env, scope):
    items = []
    for item in env.GetProjectOption("extra_scripts", []):
        if scope == "post" and ":" not in item:
            items.append(item)
        elif item.startswith("%s:" % scope):
            items.append(item[len(scope) + 1:])
    if not items:
        return items
    with fs.cd(env.subst("$PROJECT_DIR")):
        return [os.path.realpath(item) for item in items]
Example #3
0
def BoardConfig(env, board=None):
    with fs.cd(env.subst("$PROJECT_DIR")):
        try:
            p = env.PioPlatform()
            board = board or env.get("BOARD")
            assert board, "BoardConfig: Board is not defined"
            return p.board_config(board)
        except (AssertionError, UnknownBoard) as e:
            sys.stderr.write("Error: %s\n" % str(e))
            env.Exit(1)
    return None
Example #4
0
def package_publish(package, owner, released_at, private, notify):
    assert ensure_python3()
    with tempfile.TemporaryDirectory() as tmp_dir:  # pylint: disable=no-member
        with fs.cd(tmp_dir):
            p = PackagePacker(package)
            archive_path = p.pack()
            response = RegistryClient().publish_package(
                archive_path, owner, released_at, private, notify
            )
            os.remove(archive_path)
            click.secho(response.get("message"), fg="green")
    def _load_tplvars(self):
        tpl_vars = {
            "config":
            self.config,
            "systype":
            util.get_systype(),
            "project_name":
            basename(self.project_dir),
            "project_dir":
            self.project_dir,
            "env_name":
            self.env_name,
            "user_home_dir":
            realpath(fs.expanduser("~")),
            "platformio_path":
            sys.argv[0]
            if isfile(sys.argv[0]) else where_is_program("platformio"),
            "env_path":
            os.getenv("PATH"),
            "env_pathsep":
            os.pathsep,
        }

        # default env configuration
        tpl_vars.update(self.config.items(env=self.env_name, as_dict=True))
        # build data
        tpl_vars.update(
            load_project_ide_data(self.project_dir, self.env_name) or {})

        with fs.cd(self.project_dir):
            tpl_vars.update({
                "src_files":
                self.get_src_files(),
                "project_src_dir":
                self.config.get_optional_dir("src"),
                "project_lib_dir":
                self.config.get_optional_dir("lib"),
                "project_libdeps_dir":
                join(self.config.get_optional_dir("libdeps"), self.env_name),
            })

        for key, value in tpl_vars.items():
            if key.endswith(("_path", "_dir")):
                tpl_vars[key] = fs.to_unix_path(value)
        for key in ("src_files", "libsource_dirs"):
            if key not in tpl_vars:
                continue
            tpl_vars[key] = [fs.to_unix_path(inc) for inc in tpl_vars[key]]

        tpl_vars["to_unix_path"] = fs.to_unix_path
        tpl_vars["filter_includes"] = self.filter_includes
        return tpl_vars
Example #6
0
def device_monitor(**kwargs):  # pylint: disable=too-many-branches
    click.echo("Looking for advanced Serial Monitor with UI? "
               "Check http://bit.ly/pio-advanced-monitor")
    project_options = {}
    try:
        with fs.cd(kwargs["project_dir"]):
            project_options = get_project_options(kwargs["environment"])
        kwargs = apply_project_monitor_options(kwargs, project_options)
    except NotPlatformIOProjectError:
        pass

    if not kwargs["port"]:
        ports = util.get_serial_ports(filter_hwid=True)
        if len(ports) == 1:
            kwargs["port"] = ports[0]["port"]
        elif "platform" in project_options and "board" in project_options:
            board_hwids = get_board_hwids(
                kwargs["project_dir"],
                project_options["platform"],
                project_options["board"],
            )
            for item in ports:
                for hwid in board_hwids:
                    hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
                    if hwid_str in item["hwid"]:
                        kwargs["port"] = item["port"]
                        break
                if kwargs["port"]:
                    break
    elif kwargs["port"] and (set(["*", "?", "[", "]"]) & set(kwargs["port"])):
        for item in util.get_serial_ports():
            if fnmatch(item["port"], kwargs["port"]):
                kwargs["port"] = item["port"]
                break

    # override system argv with patched options
    sys.argv = ["monitor"] + options_to_argv(
        kwargs,
        project_options,
        ignore=("port", "baud", "rts", "dtr", "environment", "project_dir"),
    )

    try:
        miniterm.main(
            default_port=kwargs["port"],
            default_baudrate=kwargs["baud"] or 9600,
            default_rts=kwargs["rts"],
            default_dtr=kwargs["dtr"],
        )
    except Exception as e:
        raise exception.MinitermException(e)
Example #7
0
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", []
                )
Example #8
0
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)
Example #9
0
    def add_project_items(self, psync):
        with fs.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")
Example #10
0
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)
Example #11
0
    async def import_arduino(self, board, use_arduino_libs,
                             arduino_project_dir):
        board = str(board)
        # don't import PIO Project
        if is_platformio_project(arduino_project_dir):
            return arduino_project_dir

        is_arduino_project = any([
            os.path.isfile(
                os.path.join(
                    arduino_project_dir,
                    "%s.%s" % (os.path.basename(arduino_project_dir), ext),
                )) for ext in ("ino", "pde")
        ])
        if not is_arduino_project:
            raise jsonrpc.exceptions.JSONRPCDispatchException(
                code=4000,
                message="Not an Arduino project: %s" % arduino_project_dir)

        state = AppRPC.load_state()
        project_dir = os.path.join(state["storage"]["projectsDir"],
                                   time.strftime("%y%m%d-%H%M%S-") + board)
        if not os.path.isdir(project_dir):
            os.makedirs(project_dir)
        args = ["init", "--board", board]
        args.extend(["--project-option", "framework = arduino"])
        if use_arduino_libs:
            args.extend([
                "--project-option",
                "lib_extra_dirs = ~/Documents/Arduino/libraries"
            ])
        if (state["storage"]["coreCaller"] and state["storage"]["coreCaller"]
                in ProjectGenerator.get_supported_ides()):
            args.extend(["--ide", state["storage"]["coreCaller"]])
        await PIOCoreRPC.call(args,
                              options={
                                  "cwd": project_dir,
                                  "force_subprocess": True
                              })
        with fs.cd(project_dir):
            config = ProjectConfig()
            src_dir = config.get_optional_dir("src")
            if os.path.isdir(src_dir):
                fs.rmtree(src_dir)
            shutil.copytree(arduino_project_dir, src_dir, symlinks=True)
        return project_dir
Example #12
0
def test_base(tmpdir_factory):
    pkg_dir = tmpdir_factory.mktemp("package")
    pkg_dir.join(".git").mkdir().join("file").write("")
    pkg_dir.join(".gitignore").write("tests")
    pkg_dir.join("._ignored").write("")
    pkg_dir.join("main.cpp").write("#include <stdio.h>")
    p = PackagePacker(str(pkg_dir))
    # test missed manifest
    with pytest.raises(UnknownManifestError):
        p.pack()
    # minimal package
    pkg_dir.join("library.json").write('{"name": "foo", "version": "1.0.0"}')
    pkg_dir.mkdir("include").join("main.h").write("#ifndef")
    with fs.cd(str(pkg_dir)):
        p.pack()
    with tarfile.open(os.path.join(str(pkg_dir), "foo-1.0.0.tar.gz"),
                      "r:gz") as tar:
        assert set(tar.getnames()) == set(
            [".gitignore", "include/main.h", "library.json", "main.cpp"])
Example #13
0
 def _generate_project_main(_, project_dir, framework):
     main_content = None
     if framework == "arduino":
         main_content = "\n".join([
             "#include <Arduino.h>",
             "",
             "void setup() {",
             "  // put your setup code here, to run once:",
             "}",
             "",
             "void loop() {",
             "  // put your main code here, to run repeatedly:",
             "}",
             "",
         ])
     elif framework == "mbed":
         main_content = "\n".join([
             "#include <mbed.h>",
             "",
             "int main() {",
             "",
             "  // put your setup code here, to run once:",
             "",
             "  while(1) {",
             "    // put your main code here, to run repeatedly:",
             "  }",
             "}",
             "",
         ])
     if not main_content:
         return project_dir
     with fs.cd(project_dir):
         config = ProjectConfig()
         src_dir = config.get_optional_dir("src")
         main_path = os.path.join(src_dir, "main.cpp")
         if os.path.isfile(main_path):
             return project_dir
         if not os.path.isdir(src_dir):
             os.makedirs(src_dir)
         with open(main_path, "w") as fp:
             fp.write(main_content.strip())
     return project_dir
Example #14
0
def device_monitor(ctx, agents, **kwargs):
    from platformio.commands.remote.client.device_monitor import DeviceMonitorClient

    if kwargs["sock"]:
        return DeviceMonitorClient(agents, **kwargs).connect()

    project_options = {}
    try:
        with fs.cd(kwargs["project_dir"]):
            project_options = device_helpers.get_project_options(
                kwargs["environment"])
        kwargs = device_helpers.apply_project_monitor_options(
            kwargs, project_options)
    except NotPlatformIOProjectError:
        pass

    kwargs["baud"] = kwargs["baud"] or 9600

    def _tx_target(sock_dir):
        subcmd_argv = ["remote", "device", "monitor"]
        subcmd_argv.extend(
            device_helpers.options_to_argv(kwargs, project_options))
        subcmd_argv.extend(["--sock", sock_dir])
        subprocess.call([proc.where_is_program("platformio")] + subcmd_argv)

    sock_dir = mkdtemp(suffix="pio")
    sock_file = os.path.join(sock_dir, "sock")
    try:
        t = threading.Thread(target=_tx_target, args=(sock_dir, ))
        t.start()
        while t.is_alive() and not os.path.isfile(sock_file):
            sleep(0.1)
        if not t.is_alive():
            return
        with open(sock_file) as fp:
            kwargs["port"] = fp.read()
        ctx.invoke(cmd_device_monitor, **kwargs)
        t.join(2)
    finally:
        fs.rmtree(sock_dir)

    return True
Example #15
0
def package_publish(package, owner, released_at, private, notify):
    assert ensure_python3()

    # publish .tar.gz instantly without repacking
    if not os.path.isdir(package) and isinstance(
            FileUnpacker.new_archiver(package), TARArchiver):
        response = RegistryClient().publish_package(package, owner,
                                                    released_at, private,
                                                    notify)
        click.secho(response.get("message"), fg="green")
        return

    with tempfile.TemporaryDirectory() as tmp_dir:  # pylint: disable=no-member
        with fs.cd(tmp_dir):
            p = PackagePacker(package)
            archive_path = p.pack()
            response = RegistryClient().publish_package(
                archive_path, owner, released_at, private, notify)
            os.remove(archive_path)
            click.secho(response.get("message"), fg="green")
Example #16
0
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
Example #17
0
def get_board_hwids(project_dir, platform, board):
    with fs.cd(project_dir):
        return platform.board_config(board).get("build.hwids", [])
Example #18
0
 def src_dir(self):
     if "srcDir" in self._manifest.get("build", {}):
         with fs.cd(self.path):
             return realpath(self._manifest.get("build").get("srcDir"))
     return LibBuilderBase.src_dir.fget(self)
Example #19
0
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)
Example #20
0
 def src_dir(self):
     if "srcDir" in self._manifest.get("build", {}):
         with fs.cd(self.path):
             return os.path.realpath(
                 self._manifest.get("build").get("srcDir"))
     return LibBuilderBase.src_dir.fget(self)  # pylint: disable=no-member
Example #21
0
 def include_dir(self):
     if "includeDir" in self._manifest.get("build", {}):
         with fs.cd(self.path):
             return realpath(self._manifest.get("build").get("includeDir"))
     return LibBuilderBase.include_dir.fget(self)
Example #22
0
    def _get_projects(project_dirs=None):
        def _get_project_data():
            data = {"boards": [], "envLibdepsDirs": [], "libExtraDirs": []}
            config = ProjectConfig()
            data["envs"] = config.envs()
            data["description"] = config.get("platformio", "description")
            data["libExtraDirs"].extend(
                config.get("platformio", "lib_extra_dirs", []))

            libdeps_dir = config.get_optional_dir("libdeps")
            for section in config.sections():
                if not section.startswith("env:"):
                    continue
                data["envLibdepsDirs"].append(join(libdeps_dir, section[4:]))
                if config.has_option(section, "board"):
                    data["boards"].append(config.get(section, "board"))
                data["libExtraDirs"].extend(
                    config.get(section, "lib_extra_dirs", []))

            # skip non existing folders and resolve full path
            for key in ("envLibdepsDirs", "libExtraDirs"):
                data[key] = [
                    fs.expanduser(d) if d.startswith("~") else realpath(d)
                    for d in data[key] if isdir(d)
                ]

            return data

        def _path_to_name(path):
            return (sep).join(path.split(sep)[-2:])

        if not project_dirs:
            project_dirs = AppRPC.load_state()["storage"]["recentProjects"]

        result = []
        pm = PlatformManager()
        for project_dir in project_dirs:
            data = {}
            boards = []
            try:
                with fs.cd(project_dir):
                    data = _get_project_data()
            except exception.PlatformIOProjectException:
                continue

            for board_id in data.get("boards", []):
                name = board_id
                try:
                    name = pm.board_config(board_id)["name"]
                except exception.PlatformioException:
                    pass
                boards.append({"id": board_id, "name": name})

            result.append({
                "path":
                project_dir,
                "name":
                _path_to_name(project_dir),
                "modified":
                int(getmtime(project_dir)),
                "boards":
                boards,
                "description":
                data.get("description"),
                "envs":
                data.get("envs", []),
                "envLibStorages": [{
                    "name": basename(d),
                    "path": d
                } for d in data.get("envLibdepsDirs", [])],
                "extraLibStorages": [{
                    "name": _path_to_name(d),
                    "path": d
                } for d in data.get("libExtraDirs", [])],
            })
        return result
Example #23
0
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
Example #24
0
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)
Example #25
0
 def _thread_task():
     with fs.cd(cwd):
         exit_code = __main__.main(["-c"] + args)
     return (PIOCoreRPC.thread_stdout.get_value_and_reset(),
             PIOCoreRPC.thread_stderr.get_value_and_reset(), exit_code)
Example #26
0
def device_monitor(**kwargs):  # pylint: disable=too-many-branches
    # load default monitor filters
    filters_dir = os.path.join(fs.get_source_dir(), "commands", "device", "filters")
    for name in os.listdir(filters_dir):
        if not name.endswith(".py"):
            continue
        device_helpers.load_monitor_filter(os.path.join(filters_dir, name))

    project_options = {}
    try:
        with fs.cd(kwargs["project_dir"]):
            project_options = device_helpers.get_project_options(kwargs["environment"])
        kwargs = device_helpers.apply_project_monitor_options(kwargs, project_options)
    except NotPlatformIOProjectError:
        pass

    platform = None
    if "platform" in project_options:
        with fs.cd(kwargs["project_dir"]):
            platform = PlatformFactory.newPlatform(project_options["platform"])
            device_helpers.register_platform_filters(
                platform, kwargs["project_dir"], kwargs["environment"]
            )

    if not kwargs["port"]:
        ports = util.get_serial_ports(filter_hwid=True)
        if len(ports) == 1:
            kwargs["port"] = ports[0]["port"]
        elif "platform" in project_options and "board" in project_options:
            board_hwids = device_helpers.get_board_hwids(
                kwargs["project_dir"], platform, project_options["board"],
            )
            for item in ports:
                for hwid in board_hwids:
                    hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
                    if hwid_str in item["hwid"]:
                        kwargs["port"] = item["port"]
                        break
                if kwargs["port"]:
                    break
    elif kwargs["port"] and (set(["*", "?", "[", "]"]) & set(kwargs["port"])):
        for item in util.get_serial_ports():
            if fnmatch(item["port"], kwargs["port"]):
                kwargs["port"] = item["port"]
                break

    # override system argv with patched options
    sys.argv = ["monitor"] + device_helpers.options_to_argv(
        kwargs,
        project_options,
        ignore=("port", "baud", "rts", "dtr", "environment", "project_dir"),
    )

    if not kwargs["quiet"]:
        click.echo(
            "--- Available filters and text transformations: %s"
            % ", ".join(sorted(miniterm.TRANSFORMATIONS.keys()))
        )
        click.echo("--- More details at http://bit.ly/pio-monitor-filters")
    try:
        miniterm.main(
            default_port=kwargs["port"],
            default_baudrate=kwargs["baud"] or 9600,
            default_rts=kwargs["rts"],
            default_dtr=kwargs["dtr"],
        )
    except Exception as e:
        raise exception.MinitermException(e)
Example #27
0
def cli(
    ctx,
    environment,
    target,
    upload_port,
    project_dir,
    project_conf,
    jobs,
    silent,
    verbose,
    disable_auto_clean,
):
    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)

    is_test_running = CTX_META_TEST_IS_RUNNING in ctx.meta

    with fs.cd(project_dir):
        config = ProjectConfig.get_instance(project_conf)
        config.validate(environment)

        # clean obsolete build dir
        if not disable_auto_clean:
            build_dir = config.get_optional_dir("build")
            try:
                clean_build_dir(build_dir, config)
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "it manually to avoid build issues" % build_dir,
                    fg="yellow",
                )

        handle_legacy_libdeps(project_dir, config)

        default_envs = config.default_envs()
        results = []
        for env in config.envs():
            skipenv = any([
                environment and env not in environment,
                not environment and default_envs and env not in default_envs,
            ])
            if skipenv:
                results.append({"env": env})
                continue

            # print empty line between multi environment project
            if not silent and any(
                    r.get("succeeded") is not None for r in results):
                click.echo()

            results.append(
                process_env(
                    ctx,
                    env,
                    config,
                    environment,
                    target,
                    upload_port,
                    silent,
                    verbose,
                    jobs,
                    is_test_running,
                ))

        command_failed = any(r.get("succeeded") is False for r in results)

        if not is_test_running and (command_failed
                                    or not silent) and len(results) > 1:
            print_processing_summary(results)

        if command_failed:
            raise exception.ReturnErrorCode(1)
        return True
Example #28
0
def get_board_hwids(project_dir, platform, board):
    with fs.cd(project_dir):
        return (PlatformFactory.newPlatform(platform).board_config(board).get(
            "build.hwids", []))
Example #29
0
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",
        )
Example #30
0
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 fs.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 = 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:
        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