def test_run(pioproject_dir): with util.cd(pioproject_dir): build_dir = util.get_projectbuild_dir() if isdir(build_dir): util.rmtree_(build_dir) env_names = [] for section in util.load_project_config().sections(): if section.startswith("env:"): env_names.append(section[4:]) result = util.exec_command( ["platformio", "run", "-e", random.choice(env_names)]) if result['returncode'] != 0: pytest.fail(result) assert isdir(build_dir) # check .elf file for item in listdir(build_dir): if not isdir(item): continue assert isfile(join(build_dir, item, "firmware.elf")) # check .hex or .bin files firmwares = [] for ext in ("bin", "hex"): firmwares += glob(join(build_dir, item, "firmware*.%s" % ext)) if not firmwares: pytest.fail("Missed firmware file") for firmware in firmwares: assert getsize(firmware) > 0
def get_first_board(project_dir): config = util.load_project_config(project_dir) for section in config.sections(): if not section.startswith("env:"): continue elif config.has_option(section, "board"): return config.get(section, "board") return None
def test_init_duplicated_boards(clirunner, validate_cliresult, tmpdir): with tmpdir.as_cwd(): for _ in range(2): result = clirunner.invoke(cmd_init, ["-b", "uno", "-b", "uno"]) validate_cliresult(result) validate_pioproject(str(tmpdir)) config = util.load_project_config() assert set(config.sections()) == set(["env:uno"])
def get_project_env(self): data = {"env_name": "PlatformIO"} config = util.load_project_config(self.project_dir) for section in config.sections(): if not section.startswith("env:"): continue data = {"env_name": section[4:]} for k, v in config.items(section): data[k] = v if self.board == data.get("board"): break return data
def get_project_env(self): data = {} config = util.load_project_config(self.project_dir) for section in config.sections(): if not section.startswith("env:"): continue if self.env_name != section[4:]: continue data = {"env_name": section[4:]} for k, v in config.items(section): data[k] = v return data
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 = util.load_project_config() expected_result = [("platform", "teensy"), ("framework", "mbed"), ("board", "teensy31")] assert config.has_section("env:teensy31") assert not set(expected_result).symmetric_difference( set(config.items("env:teensy31")))
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 = util.load_project_config() expected_result = [("platform", "atmelavr"), ("framework", "arduino"), ("board", "uno"), ("targets", "upload")] assert config.has_section("env:uno") assert not set(expected_result).symmetric_difference( set(config.items("env:uno")))
def fill_project_envs( # pylint: disable=too-many-arguments,too-many-locals ctx, project_dir, board_ids, project_option, env_prefix, force_download): installed_boards = PlatformManager().get_installed_boards() content = [] used_boards = [] used_platforms = [] config = util.load_project_config(project_dir) for section in config.sections(): if not all( [section.startswith("env:"), config.has_option(section, "board")]): continue used_boards.append(config.get(section, "board")) for id_ in board_ids: manifest = None for boards in (installed_boards, PlatformManager.get_registered_boards()): for b in boards: if b['id'] == id_: manifest = b break assert manifest is not None used_platforms.append(manifest['platform']) if id_ in used_boards: continue used_boards.append(id_) content.append("") content.append("[env:%s%s]" % (env_prefix, id_)) content.append("platform = %s" % manifest['platform']) # find default framework for board frameworks = manifest.get("frameworks") if frameworks: content.append("framework = %s" % frameworks[0]) content.append("board = %s" % id_) if project_option: content.extend(project_option) if force_download and used_platforms: _install_dependent_platforms(ctx, used_platforms) if not content: return with open(join(project_dir, "platformio.ini"), "a") as f: content.append("") f.write("\n".join(content))
def get_project_env(self): data = None config = util.load_project_config(self.project_dir) for section in config.sections(): if not section.startswith("env:"): continue if self.env_name != section[4:]: continue data = {"env_name": section[4:]} for k, v in config.items(section): data[k] = v return data
def fill_project_envs(ctx, project_dir, board_ids, project_option, env_prefix, force_download): content = [] used_boards = [] used_platforms = [] config = util.load_project_config(project_dir) 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() 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_) 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() content.append("") content.append("[env:%s%s]" % (env_prefix, id_)) for name, value in envopts.items(): content.append("%s = %s" % (name, value)) if force_download and used_platforms: _install_dependent_platforms(ctx, used_platforms) if not content: return with open(join(project_dir, "platformio.ini"), "a") as f: content.append("") f.write("\n".join(content))
def get_best_envname(project_dir, boards=None): config = util.load_project_config(project_dir) env_default = None if config.has_option("platformio", "env_default"): env_default = config.get("platformio", "env_default").split(", ")[0].strip() if env_default: return env_default for section in config.sections(): if not section.startswith("env:"): continue elif config.has_option(section, "board") and (not boards or config.get( section, "board") in boards): return section[4:] return None
def get_best_envname(project_dir, boards=None): config = util.load_project_config(project_dir) env_default = None if config.has_option("platformio", "env_default"): env_default = config.get("platformio", "env_default").split(", ")[0].strip() if env_default: return env_default section = None for section in config.sections(): if not section.startswith("env:"): continue elif config.has_option(section, "board") and (not boards or config.get( section, "board") in boards): break return section[4:] if section else None
def get_best_envname(project_dir, boards=None): config = util.load_project_config(project_dir) env_default = None if config.has_option("platformio", "env_default"): env_default = util.parse_conf_multi_values( config.get("platformio", "env_default")) check_project_envs(config, env_default) if env_default: return env_default[0] section = None for section in config.sections(): if not section.startswith("env:"): continue elif config.has_option(section, "board") and (not boards or config.get( section, "board") in boards): break return section[4:] if section else None
def init_base_project(project_dir): if not util.is_platformio_project(project_dir): copyfile(join(util.get_source_dir(), "projectconftpl.ini"), join(project_dir, "platformio.ini")) lib_dir = join(project_dir, "lib") src_dir = join(project_dir, "src") config = util.load_project_config(project_dir) if config.has_option("platformio", "src_dir"): src_dir = join(project_dir, config.get("platformio", "src_dir")) for d in (src_dir, lib_dir): if not isdir(d): makedirs(d) init_lib_readme(lib_dir) init_ci_conf(project_dir) init_cvs_ignore(project_dir)
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 = util.load_project_config() expected_result = [("platform", str(boards[0]['platform'])), ("framework", str(boards[0]['frameworks'][0])), ("board", "uno")] assert config.has_section("env:uno") assert not set(expected_result).symmetric_difference( set(config.items("env:uno")))
def init_base_project(project_dir): if not util.is_platformio_project(project_dir): copyfile( join(util.get_source_dir(), "projectconftpl.ini"), join(project_dir, "platformio.ini")) lib_dir = join(project_dir, "lib") src_dir = join(project_dir, "src") config = util.load_project_config(project_dir) if config.has_option("platformio", "src_dir"): src_dir = join(project_dir, config.get("platformio", "src_dir")) for d in (src_dir, lib_dir): if not isdir(d): makedirs(d) init_lib_readme(lib_dir) init_ci_conf(project_dir) init_cvs_ignore(project_dir)
def get_project_options(project_dir, environment): config = util.load_project_config(project_dir) if not config.sections(): return None known_envs = [s[4:] for s in config.sections() if s.startswith("env:")] if environment: if environment in known_envs: return config.items("env:%s" % environment) raise exception.UnknownEnvNames(environment, ", ".join(known_envs)) if not known_envs: return None if config.has_option("platformio", "env_default"): env_default = config.get("platformio", "env_default").split(", ")[0].strip() if env_default and env_default in known_envs: return config.items("env:%s" % env_default) return config.items("env:%s" % known_envs[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
def _copy_project_conf(build_dir, project_conf): config = util.load_project_config(project_conf) if config.has_section("platformio"): config.remove_section("platformio") with open(join(build_dir, "platformio.ini"), "w") as fp: config.write(fp)
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 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((envname, ep.process())) if len(results) > 1: click.echo() print_summary(results, start_time) if any([status is False for (_, status) in results]): raise exception.ReturnErrorCode(1) return True
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 build dir if not disable_auto_clean: try: _clean_build_dir(util.get_projectbuild_dir()) except: # pylint: disable=bare-except click.secho( "Can not remove temporary directory `%s`. Please remove " "it manually to avoid build issues" % util.get_projectbuild_dir(force=True), fg="yellow") config = util.load_project_config() env_default = None if config.has_option("platformio", "env_default"): env_default = util.parse_conf_multi_values( config.get("platformio", "env_default")) check_project_defopts(config) check_project_envs(config, environment or env_default) 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, 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
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
# build.py # pre-build script, setting up build environment import sys import os import os.path import requests from os.path import basename from platformio import util Import("env") # get platformio environment variables project_config = util.load_project_config() # check if file loraconf.h is present in source directory keyfile = str(env.get("PROJECTSRC_DIR")) + "/loraconf.h" if os.path.isfile(keyfile) and os.access(keyfile, os.R_OK): print "Parsing LORAWAN keys from " + keyfile else: sys.exit( "Missing file loraconf.h, please create it using template loraconf.sample.h! Aborting." ) # check if file ota.conf is present in source directory keyfile = str(env.get("PROJECTSRC_DIR")) + "/" + project_config.get( "common", "keyfile") if os.path.isfile(keyfile) and os.access(keyfile, os.R_OK): print "Parsing OTA keys from " + keyfile else: sys.exit(
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