예제 #1
0
def pioplus_call(args, **kwargs):
    pioplus_install()
    pm = PioPlusPackageManager()
    pioplus_path = join(
        pm.get_package_dir(PACKAGE_DEPS['tool']['name'],
                           PACKAGE_DEPS['tool']['requirements']), "pioplus")
    os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path()
    os.environ['PYTHONPYSITEDIR'] = pm.get_package_dir(
        PACKAGE_DEPS['pysite']['name'], PACKAGE_DEPS['pysite']['requirements'])
    util.copy_pythonpath_to_osenv()
    code = subprocess.call([pioplus_path] + args, **kwargs)

    # handle remote update request
    if code == 13:
        count_attr = "_update_count"
        try:
            count_value = getattr(pioplus_call, count_attr)
        except AttributeError:
            count_value = 0
            setattr(pioplus_call, count_attr, 1)
        count_value += 1
        setattr(pioplus_call, count_attr, count_value)
        if count_value < AUTO_UPDATES_MAX:
            pioplus_update()
            return pioplus_call(args, **kwargs)

    # handle reload request
    elif code == 14:
        return pioplus_call(args, **kwargs)

    if code != 0:
        raise exception.ReturnErrorCode(1)
예제 #2
0
def pioplus_call(args, **kwargs):
    pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
    os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path()
    os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("pysite-pioplus")
    util.copy_pythonpath_to_osenv()
    code = subprocess.call([pioplus_path] + args, **kwargs)

    # handle remote update request
    if code == 13:
        count_attr = "_update_count"
        try:
            count_value = getattr(pioplus_call, count_attr)
        except AttributeError:
            count_value = 0
            setattr(pioplus_call, count_attr, 1)
        count_value += 1
        setattr(pioplus_call, count_attr, count_value)
        if count_value < PIOPLUS_AUTO_UPDATES_MAX:
            update_core_packages()
            return pioplus_call(args, **kwargs)

    # handle reload request
    elif code == 14:
        return pioplus_call(args, **kwargs)

    if code != 0:
        raise exception.ReturnErrorCode(1)
예제 #3
0
def pioplus_call(args, **kwargs):
    if "windows" in util.get_systype() and sys.version_info < (2, 7, 6):
        raise exception.PlatformioException(
            "PlatformIO Core Plus v%s does not run under Python version %s.\n"
            "Minimum supported version is 2.7.6, please upgrade Python.\n"
            "Python 3 is not yet supported.\n" %
            (__version__, sys.version.split()[0]))

    pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
    os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path()
    os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("pysite-pioplus")
    util.copy_pythonpath_to_osenv()
    code = subprocess.call([pioplus_path] + args, **kwargs)

    # handle remote update request
    if code == 13:
        count_attr = "_update_count"
        try:
            count_value = getattr(pioplus_call, count_attr)
        except AttributeError:
            count_value = 0
            setattr(pioplus_call, count_attr, 1)
        count_value += 1
        setattr(pioplus_call, count_attr, count_value)
        if count_value < PIOPLUS_AUTO_UPDATES_MAX:
            update_core_packages()
            return pioplus_call(args, **kwargs)

    # handle reload request
    elif code == 14:
        return pioplus_call(args, **kwargs)

    if code != 0:
        raise exception.ReturnErrorCode(1)
예제 #4
0
    def connect(self):
        self.log.info("Name: {name}", name=self.name)
        self.log.info("Connecting to PlatformIO Remote Development Cloud")

        # pylint: disable=protected-access
        proto, options = endpoints._parse(__pioremote_endpoint__)
        proto = proto[0]

        factory = RemoteClientFactory()
        factory.remote_client = self
        factory.sslContextFactory = None
        if proto == "ssl":
            factory.sslContextFactory = SSLContextFactory(options["host"])
            reactor.connectSSL(
                options["host"],
                int(options["port"]),
                factory,
                factory.sslContextFactory,
            )
        elif proto == "tcp":
            reactor.connectTCP(options["host"], int(options["port"]), factory)
        else:
            raise exception.PlatformioException(
                "Unknown PIO Remote Cloud protocol")
        reactor.run()

        if self._exit_code != 0:
            raise exception.ReturnErrorCode(self._exit_code)
예제 #5
0
def cli(dev):
    if not dev and __version__ == get_latest_version():
        return click.secho(
            "You're up-to-date!\nPlatformIO %s is currently the "
            "newest version available." % __version__,
            fg="green")

    click.secho("Please wait while upgrading PlatformIO ...", fg="yellow")

    # kill all PIO Home servers, they block `pioplus` binary
    shutdown_piohome_servers()

    to_develop = dev or not all(c.isdigit() for c in __version__ if c != ".")
    cmds = (["pip", "install", "--upgrade",
             get_pip_package(to_develop)], ["platformio", "--version"])

    cmd = None
    r = {}
    try:
        for cmd in cmds:
            cmd = [get_pythonexe_path(), "-m"] + cmd
            r = exec_command(cmd)

            # try pip with disabled cache
            if r['returncode'] != 0 and cmd[2] == "pip":
                cmd.insert(3, "--no-cache-dir")
                r = exec_command(cmd)

            assert r['returncode'] == 0
        assert "version" in r['out']
        actual_version = r['out'].strip().split("version", 1)[1].strip()
        click.secho("PlatformIO has been successfully upgraded to %s" %
                    actual_version,
                    fg="green")
        click.echo("Release notes: ", nl=False)
        click.secho("https://docs.platformio.org/en/latest/history.html",
                    fg="cyan")
    except Exception as e:  # pylint: disable=broad-except
        if not r:
            raise exception.UpgradeError("\n".join([str(cmd), str(e)]))
        permission_errors = ("permission denied", "not permitted")
        if (any(m in r['err'].lower() for m in permission_errors)
                and not WINDOWS):
            click.secho("""
-----------------
Permission denied
-----------------
You need the `sudo` permission to install Python packages. Try

> sudo pip install -U platformio

WARNING! Don't use `sudo` for the rest PlatformIO commands.
""",
                        fg="yellow",
                        err=True)
            raise exception.ReturnErrorCode(1)
        raise exception.UpgradeError("\n".join([str(cmd), r['out'], r['err']]))

    return True
예제 #6
0
def cli(ctx, environment, target, upload_port, project_dir, project_conf, jobs,
        silent, verbose, disable_auto_clean):
    # find project directory on upper level
    if isfile(project_dir):
        project_dir = find_project_dir_above(project_dir)

    with util.cd(project_dir):
        # clean obsolete build dir
        if not disable_auto_clean:
            try:
                clean_build_dir(get_project_build_dir())
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "it manually to avoid build issues" %
                    get_project_build_dir(force=True),
                    fg="yellow")

        config = ProjectConfig.get_instance(
            project_conf or join(project_dir, "platformio.ini"))
        config.validate(environment)

        handle_legacy_libdeps(project_dir, config)

        results = []
        start_time = time()
        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
            ])
            if skipenv:
                results.append((envname, None))
                continue

            if not silent and any(status is not None
                                  for (_, status) in results):
                click.echo()

            ep = EnvironmentProcessor(ctx, envname, config, target,
                                      upload_port, silent, verbose, jobs)
            result = (envname, ep.process())
            results.append(result)

            if result[1] and "monitor" in ep.get_build_targets() and \
                    "nobuild" not in ep.get_build_targets():
                ctx.invoke(cmd_device_monitor,
                           environment=environment[0] if environment else None)

        found_error = any(status is False for (_, status) in results)

        if (found_error or not silent) and len(results) > 1:
            click.echo()
            print_summary(results, start_time)

        if found_error:
            raise exception.ReturnErrorCode(1)
        return True
예제 #7
0
def cli():
    last = get_latest_version()
    if __version__ == last:
        return click.secho(
            "You're up-to-date!\nPlatformIO %s is currently the "
            "newest version available." % __version__, fg="green"
        )
    else:
        click.secho("Please wait while upgrading PlatformIO ...",
                    fg="yellow")

        cmds = (
            ["pip", "install", "--upgrade", "platformio"],
            ["platformio", "--version"]
        )

        cmd = None
        r = None
        try:
            for cmd in cmds:
                r = None
                r = util.exec_command(cmd)

                # try pip with disabled cache
                if r['returncode'] != 0 and cmd[0] == "pip":
                    r = util.exec_command(["pip", "--no-cache-dir"] + cmd[1:])

                assert r['returncode'] == 0
            assert last in r['out'].strip()
            click.secho(
                "PlatformIO has been successfully upgraded to %s" % last,
                fg="green")
            click.echo("Release notes: ", nl=False)
            click.secho("http://docs.platformio.org/en/latest/history.html",
                        fg="cyan")
        except Exception as e:  # pylint: disable=W0703
            if not r:
                raise exception.UpgradeError(
                    "\n".join([str(cmd), str(e)]))
            permission_errors = (
                "permission denied",
                "not permitted"
            )
            if (any([m in r['err'].lower() for m in permission_errors]) and
                    "windows" not in util.get_systype()):
                click.secho("""
-----------------
Permission denied
-----------------
You need the `sudo` permission to install Python packages. Try

> sudo pip install -U platformio

WARNING! Don't use `sudo` for the rest PlatformIO commands.
""", fg="yellow", err=True)
                raise exception.ReturnErrorCode()
            else:
                raise exception.UpgradeError(
                    "\n".join([str(cmd), r['out'], r['err']]))
예제 #8
0
def cli(
        ctx,
        environment,
        target,
        upload_port,  # pylint: disable=R0913,R0914
        project_dir,
        verbose,
        disable_auto_clean):
    with util.cd(project_dir):
        config = util.get_project_config()

        if not config.sections():
            raise exception.ProjectEnvsNotAvailable()

        known = set([s[4:] for s in config.sections() if s.startswith("env:")])
        unknown = set(environment) - known
        if unknown:
            raise exception.UnknownEnvNames(", ".join(unknown),
                                            ", ".join(known))

        # clean obsolete .pioenvs dir
        if not disable_auto_clean:
            try:
                _clean_pioenvs_dir(util.get_pioenvs_dir())
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "`.pioenvs` directory from the project manually to avoid "
                    "build issues" % util.get_pioenvs_dir(),
                    fg="yellow")

        results = []
        for section in config.sections():
            # skip main configuration section
            if section == "platformio":
                continue

            if not section.startswith("env:"):
                raise exception.InvalidEnvName(section)

            envname = section[4:]
            if environment and envname not in environment:
                # echo("Skipped %s environment" % style(envname, fg="yellow"))
                continue

            if results:
                click.echo()

            options = {}
            for k, v in config.items(section):
                options[k] = v

            ep = EnvironmentProcessor(ctx, envname, options, target,
                                      upload_port, verbose)
            results.append(ep.process())

        if not all(results):
            raise exception.ReturnErrorCode()
예제 #9
0
def cli(ctx, environment, target, upload_port, project_dir, project_conf, jobs,
        silent, verbose, disable_auto_clean):
    # 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 or join(project_dir, "platformio.ini"))
        config.validate(environment)

        # clean obsolete build dir
        if not disable_auto_clean:
            try:
                clean_build_dir(get_project_build_dir(), config)
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "it manually to avoid build issues" %
                    get_project_build_dir(force=True),
                    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
예제 #10
0
def cli(
        ctx,
        environment,
        target,
        upload_port,  # pylint: disable=R0913,R0914
        project_dir,
        verbose):
    with util.cd(project_dir):
        config = util.get_project_config()

        if not config.sections():
            raise exception.ProjectEnvsNotAvailable()

        unknown = set(environment) - set([s[4:] for s in config.sections()])
        if unknown:
            raise exception.UnknownEnvNames(", ".join(unknown))

        # clean obsolete .pioenvs dir
        _clean_pioenvs_dir()

        results = []
        for section in config.sections():
            # skip main configuration section
            if section == "platformio":
                continue

            if not section.startswith("env:"):
                raise exception.InvalidEnvName(section)

            envname = section[4:]
            if environment and envname not in environment:
                # echo("Skipped %s environment" % style(envname, fg="yellow"))
                continue

            if results:
                click.echo()

            options = {}
            for k, v in config.items(section):
                options[k] = v

            ep = EnvironmentProcessor(ctx, envname, options, target,
                                      upload_port, verbose)
            results.append(ep.process())

        if not all(results):
            raise exception.ReturnErrorCode()
예제 #11
0
def cli(ctx, environment, target, upload_port):

    config = util.get_project_config()

    if not config.sections():
        raise exception.ProjectEnvsNotAvailable()

    unknown = set(environment) - set([s[4:] for s in config.sections()])
    if unknown:
        raise exception.UnknownEnvNames(", ".join(unknown))

    # remove ".pioenvs" if project config is modified
    _pioenvs_dir = util.get_pioenvs_dir()
    if (isdir(_pioenvs_dir)
            and getmtime(join(util.get_project_dir(),
                              "platformio.ini")) > getmtime(_pioenvs_dir)):
        rmtree(_pioenvs_dir)

    found_error = False
    _first_done = False
    for section in config.sections():
        # skip main configuration section
        if section == "platformio":
            continue
        elif section[:4] != "env:":
            raise exception.InvalidEnvName(section)

        envname = section[4:]
        if environment and envname not in environment:
            # echo("Skipped %s environment" % style(envname, fg="yellow"))
            continue

        options = {}
        for k, v in config.items(section):
            options[k] = v

        if _first_done:
            click.echo()

        if not process_environment(ctx, envname, options, target, upload_port):
            found_error = True
        _first_done = True

    if found_error:
        raise exception.ReturnErrorCode()
예제 #12
0
def pioplus_call(args, **kwargs):
    if WINDOWS and sys.version_info < (2, 7, 6):
        raise exception.PlatformioException(
            "PlatformIO Core Plus v%s does not run under Python version %s.\n"
            "Minimum supported version is 2.7.6, please upgrade Python.\n"
            "Python 3 is not yet supported.\n" % (__version__, sys.version))

    pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
    pythonexe_path = get_pythonexe_path()
    os.environ["PYTHONEXEPATH"] = pythonexe_path
    os.environ["PYTHONPYSITEDIR"] = get_core_package_dir("contrib-pysite")
    os.environ["PIOCOREPYSITEDIR"] = dirname(fs.get_source_dir() or "")
    if dirname(pythonexe_path) not in os.environ["PATH"].split(os.pathsep):
        os.environ["PATH"] = (os.pathsep).join(
            [dirname(pythonexe_path), os.environ["PATH"]])
    copy_pythonpath_to_osenv()
    code = subprocess.call([pioplus_path] + args, **kwargs)

    # handle remote update request
    if code == 13:
        count_attr = "_update_count"
        try:
            count_value = getattr(pioplus_call, count_attr)
        except AttributeError:
            count_value = 0
            setattr(pioplus_call, count_attr, 1)
        count_value += 1
        setattr(pioplus_call, count_attr, count_value)
        if count_value < PIOPLUS_AUTO_UPDATES_MAX:
            update_core_packages()
            return pioplus_call(args, **kwargs)

    # handle reload request
    elif code == 14:
        return pioplus_call(args, **kwargs)

    if code != 0:
        raise exception.ReturnErrorCode(1)

    return True
예제 #13
0
def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
        disable_auto_clean):
    # find project directory on upper level
    if isfile(project_dir):
        project_dir = util.find_project_dir_above(project_dir)

    if not util.is_platformio_project(project_dir):
        raise exception.NotPlatformIOProject(project_dir)

    with util.cd(project_dir):
        # clean obsolete .pioenvs dir
        if not disable_auto_clean:
            try:
                _clean_pioenvs_dir(util.get_projectpioenvs_dir())
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "`.pioenvs` directory from the project manually to avoid "
                    "build issues" % util.get_projectpioenvs_dir(force=True),
                    fg="yellow")

        config = util.load_project_config()
        check_project_defopts(config)
        assert check_project_envs(config, environment)

        env_default = None
        if config.has_option("platformio", "env_default"):
            env_default = [
                e.strip()
                for e in config.get("platformio", "env_default").split(",")
            ]

        results = {}
        start_time = time()
        for section in config.sections():
            if not section.startswith("env:"):
                continue

            envname = section[4:]
            skipenv = any([
                environment and envname not in environment, not environment
                and env_default and envname not in env_default
            ])
            if skipenv:
                results[envname] = None
                continue

            if results:
                click.echo()

            options = {}
            for k, v in config.items(section):
                options[k] = v
            if "piotest" not in options and "piotest" in ctx.meta:
                options['piotest'] = ctx.meta['piotest']

            ep = EnvironmentProcessor(ctx, envname, options, target,
                                      upload_port, silent, verbose)
            results[envname] = ep.process()

        if len(results) > 1:
            click.echo()
            print_header("[%s]" % click.style("SUMMARY"))

            successed = True
            for envname, status in results.items():
                status_str = click.style("SUCCESS", fg="green")
                if status is False:
                    successed = False
                    status_str = click.style("ERROR", fg="red")
                elif status is None:
                    status_str = click.style("SKIP", fg="yellow")

                click.echo("Environment %s\t[%s]" %
                           (click.style(envname, fg="cyan"), status_str),
                           err=status is False)

            print_header(
                "[%s] Took %.2f seconds" %
                ((click.style("SUCCESS", fg="green", bold=True)
                  if successed else click.style("ERROR", fg="red", bold=True)),
                 time() - start_time),
                is_error=not successed)

        if any([r is False for r in results.values()]):
            raise exception.ReturnErrorCode()
        return True
예제 #14
0
def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
        disable_auto_clean):
    # find project directory on upper level
    if isfile(project_dir):
        project_dir = util.find_project_dir_above(project_dir)

    if not util.is_platformio_project(project_dir):
        raise exception.NotPlatformIOProject(project_dir)

    with util.cd(project_dir):
        # clean obsolete .pioenvs dir
        if not disable_auto_clean:
            try:
                _clean_pioenvs_dir(util.get_projectpioenvs_dir())
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "`.pioenvs` directory from the project manually to avoid "
                    "build issues" % util.get_projectpioenvs_dir(force=True),
                    fg="yellow")

        config = util.load_project_config()
        check_project_defopts(config)
        assert check_project_envs(config, environment)

        env_default = None
        if config.has_option("platformio", "env_default"):
            env_default = [
                e.strip()
                for e in config.get("platformio", "env_default").split(", ")
            ]

        results = []
        start_time = time()
        for section in config.sections():
            if not section.startswith("env:"):
                continue

            envname = section[4:]
            skipenv = any([
                environment and envname not in environment, not environment
                and env_default and envname not in env_default
            ])
            if skipenv:
                results.append((envname, None))
                continue

            if not silent and results:
                click.echo()

            options = {}
            for k, v in config.items(section):
                options[k] = v
            if "piotest" not in options and "piotest" in ctx.meta:
                options['piotest'] = ctx.meta['piotest']

            ep = EnvironmentProcessor(ctx, envname, options, target,
                                      upload_port, silent, verbose)
            result = (envname, ep.process())
            results.append(result)
            if result[1] and "monitor" in ep.get_build_targets() and \
                    "nobuild" not in ep.get_build_targets():
                ctx.invoke(cmd_device_monitor)

        found_error = any([status is False for (_, status) in results])

        if (found_error or not silent) and len(results) > 1:
            click.echo()
            print_summary(results, start_time)

        if found_error:
            raise exception.ReturnErrorCode(1)
        return True
예제 #15
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)
예제 #16
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)
예제 #17
0
async def run(
    queue,
    ctx=Context(Command('run')),
    environment='',
    target=[],
    upload_port='',
    project_dir='.',
    project_conf='./platformio.ini',
    jobs=8,
    silent='',
    verbose='',
    disable_auto_clean='',
):
    saveStdout, saveStderr = sys.stdout, sys.stderr
    sys.stderr = MyStringIOERR(queue)
    sys.stdout = MyStringIO(queue)
    # sys.stderr,sys.stdout=logger,logger
    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 = False  # 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)
        # sys.stdout,sys.stderr=saveStdout,saveStderr
        queue.put("QUIT")
        if command_failed:
            raise exception.ReturnErrorCode(1)
        return True
def cli():
    # Update PlatformIO's Core packages
    update_core_packages(silent=True)

    latest = get_latest_version()
    if __version__ == latest:
        return click.secho(
            "You're up-to-date!\nPlatformIO %s is currently the "
            "newest version available." % __version__,
            fg="green")
    else:
        click.secho("Please wait while upgrading PlatformIO ...", fg="yellow")

        to_develop = not all([c.isdigit() for c in latest if c != "."])
        cmds = ([
            "pip", "install", "--upgrade",
            "https://github.com/platformio/platformio-core/archive/develop.zip"
            if to_develop else "platformio"
        ], ["platformio", "--version"])

        cmd = None
        r = None
        try:
            for cmd in cmds:
                cmd = [util.get_pythonexe_path(), "-m"] + cmd
                r = None
                r = util.exec_command(cmd)

                # try pip with disabled cache
                if r['returncode'] != 0 and cmd[2] == "pip":
                    cmd.insert(3, "--no-cache-dir")
                    r = util.exec_command(cmd)

                assert r['returncode'] == 0
            assert "version" in r['out']
            actual_version = r['out'].strip().split("version", 1)[1].strip()
            click.secho("PlatformIO has been successfully upgraded to %s" %
                        actual_version,
                        fg="green")
            click.echo("Release notes: ", nl=False)
            click.secho("http://docs.platformio.org/en/latest/history.html",
                        fg="cyan")
        except Exception as e:  # pylint: disable=broad-except
            if not r:
                raise exception.UpgradeError("\n".join([str(cmd), str(e)]))
            permission_errors = ("permission denied", "not permitted")
            if (any([m in r['err'].lower() for m in permission_errors])
                    and "windows" not in util.get_systype()):
                click.secho("""
-----------------
Permission denied
-----------------
You need the `sudo` permission to install Python packages. Try

> sudo pip install -U platformio

WARNING! Don't use `sudo` for the rest PlatformIO commands.
""",
                            fg="yellow",
                            err=True)
                raise exception.ReturnErrorCode(1)
            else:
                raise exception.UpgradeError("\n".join(
                    [str(cmd), r['out'], r['err']]))
예제 #19
0
def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
        disable_auto_clean):
    # find project directory on upper level
    if isfile(project_dir):
        project_dir = util.find_project_dir_above(project_dir)

    if not util.is_platformio_project(project_dir):
        raise exception.NotPlatformIOProject(project_dir)

    with util.cd(project_dir):
        # clean obsolete .pioenvs dir
        if not disable_auto_clean:
            try:
                _clean_pioenvs_dir(util.get_projectpioenvs_dir())
            except:  # pylint: disable=bare-except
                click.secho(
                    "Can not remove temporary directory `%s`. Please remove "
                    "`.pioenvs` directory from the project manually to avoid "
                    "build issues" % util.get_projectpioenvs_dir(force=True),
                    fg="yellow")

        config = util.load_project_config()
        check_project_defopts(config)
        assert check_project_envs(config, environment)

        env_default = None
        if config.has_option("platformio", "env_default"):
            env_default = [
                e.strip()
                for e in config.get("platformio", "env_default").split(",")
            ]

        results = []
        for section in config.sections():
            # skip main configuration section
            if section == "platformio":
                continue

            if not section.startswith("env:"):
                raise exception.InvalidEnvName(section)

            envname = section[4:]
            skipenv = any([
                environment and envname not in environment, not environment
                and env_default and envname not in env_default
            ])
            if skipenv:
                # echo("Skipped %s environment" % style(envname, fg="yellow"))
                continue

            if results:
                click.echo()

            options = {}
            for k, v in config.items(section):
                options[k] = v
            if "piotest" not in options and "piotest" in ctx.meta:
                options['piotest'] = ctx.meta['piotest']

            ep = EnvironmentProcessor(ctx, envname, options, target,
                                      upload_port, silent, verbose)
            results.append(ep.process())

        if not all(results):
            raise exception.ReturnErrorCode()
        return True
예제 #20
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 util.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.echo("Collected %d items" % len(test_names))

        results = []
        start_time = time()
        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((None, testname, envname))
                    continue

                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))
                results.append((tp.process(), testname, envname))

    if without_testing:
        return

    passed_nums = 0
    failed_nums = 0
    testname_max_len = max([len(r[1]) for r in results])
    envname_max_len = max([len(click.style(r[2], fg="cyan")) for r in results])

    print_header("[%s]" % click.style("TEST SUMMARY"))
    click.echo()

    for result in results:
        status, testname, envname = result
        if status is False:
            failed_nums += 1
            status_str = click.style("FAILED", fg="red")
        elif status is None:
            status_str = click.style("IGNORED", fg="yellow")
        else:
            passed_nums += 1
            status_str = click.style("PASSED", fg="green")

        format_str = "test/{:<%d} > {:<%d}\t[{}]" % (testname_max_len,
                                                     envname_max_len)
        click.echo(format_str.format(testname, click.style(envname, fg="cyan"),
                                     status_str),
                   err=status is False)

    print_header("%s%d passed in %.2f seconds" %
                 ("%d failed, " % failed_nums if failed_nums else "",
                  passed_nums, time() - start_time),
                 is_error=failed_nums,
                 fg="red" if failed_nums else "green")

    if failed_nums:
        raise exception.ReturnErrorCode(1)