mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 01:57:13 +02:00
Added a new "-e, --environment" option to "platformio project init" command
This commit is contained in:
@ -17,6 +17,7 @@ PlatformIO Core 4
|
|||||||
|
|
||||||
* Added support for `custom targets <https://docs.platformio.org/page/projectconf/advanced_scripting.html#custom-targets>`__ (user cases: command shortcuts, pre/post processing based on dependencies, custom command launcher with options, etc.)
|
* Added support for `custom targets <https://docs.platformio.org/page/projectconf/advanced_scripting.html#custom-targets>`__ (user cases: command shortcuts, pre/post processing based on dependencies, custom command launcher with options, etc.)
|
||||||
* Added support for "globstar/`**`" (recursive) pattern for the different commands and configuration options (`platformio ci <https://docs.platformio.org/page/core/userguide/cmd_ci.html>`__, `src_filter <https://docs.platformio.org/page/projectconf/section_env_build.html#src-filter>`__, `check_patterns <https://docs.platformio.org/page/projectconf/section_env_check.html#check-patterns>`__, `library.json > srcFilter <https://docs.platformio.org/page/librarymanager/config.html#srcfilter>`__). Python 3.5+ is required.
|
* Added support for "globstar/`**`" (recursive) pattern for the different commands and configuration options (`platformio ci <https://docs.platformio.org/page/core/userguide/cmd_ci.html>`__, `src_filter <https://docs.platformio.org/page/projectconf/section_env_build.html#src-filter>`__, `check_patterns <https://docs.platformio.org/page/projectconf/section_env_check.html#check-patterns>`__, `library.json > srcFilter <https://docs.platformio.org/page/librarymanager/config.html#srcfilter>`__). Python 3.5+ is required.
|
||||||
|
* Added a new ``-e, --environment`` option to `platformio project init <https://docs.platformio.org/page/core/userguide/project/cmd_init.html#cmdoption-platformio-project-init-e>`__ command that helps to update a PlatformIO project using existing environment
|
||||||
* Fixed an issue with PIO Unit Testing when running multiple environments (`issue #3523 <https://github.com/platformio/platformio-core/issues/3523>`_)
|
* Fixed an issue with PIO Unit Testing when running multiple environments (`issue #3523 <https://github.com/platformio/platformio-core/issues/3523>`_)
|
||||||
|
|
||||||
4.3.4 (2020-05-23)
|
4.3.4 (2020-05-23)
|
||||||
|
2
docs
2
docs
Submodule docs updated: ec54ae9917...2178afaf33
2
examples
2
examples
Submodule examples updated: c442de34a5...bcdcf46691
@ -93,6 +93,7 @@ def validate_boards(ctx, param, value): # pylint: disable=W0613
|
|||||||
)
|
)
|
||||||
@click.option("-b", "--board", multiple=True, metavar="ID", callback=validate_boards)
|
@click.option("-b", "--board", multiple=True, metavar="ID", callback=validate_boards)
|
||||||
@click.option("--ide", type=click.Choice(ProjectGenerator.get_supported_ides()))
|
@click.option("--ide", type=click.Choice(ProjectGenerator.get_supported_ides()))
|
||||||
|
@click.option("-e", "--environment", help="Update using existing environment")
|
||||||
@click.option("-O", "--project-option", multiple=True)
|
@click.option("-O", "--project-option", multiple=True)
|
||||||
@click.option("--env-prefix", default="")
|
@click.option("--env-prefix", default="")
|
||||||
@click.option("-s", "--silent", is_flag=True)
|
@click.option("-s", "--silent", is_flag=True)
|
||||||
@ -102,6 +103,7 @@ def project_init(
|
|||||||
project_dir,
|
project_dir,
|
||||||
board,
|
board,
|
||||||
ide,
|
ide,
|
||||||
|
environment,
|
||||||
project_option,
|
project_option,
|
||||||
env_prefix,
|
env_prefix,
|
||||||
silent,
|
silent,
|
||||||
@ -139,7 +141,11 @@ def project_init(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ide:
|
if ide:
|
||||||
pg = ProjectGenerator(project_dir, ide, board)
|
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()
|
pg.generate()
|
||||||
|
|
||||||
if is_new_project:
|
if is_new_project:
|
||||||
@ -444,3 +450,23 @@ def _install_dependent_platforms(ctx, platforms):
|
|||||||
ctx.invoke(
|
ctx.invoke(
|
||||||
cli_platform_install, platforms=list(set(platforms) - set(installed_platforms))
|
cli_platform_install, platforms=list(set(platforms) - set(installed_platforms))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_best_envname(config, board_ids=None):
|
||||||
|
envname = None
|
||||||
|
default_envs = config.default_envs()
|
||||||
|
if default_envs:
|
||||||
|
envname = default_envs[0]
|
||||||
|
if not board_ids:
|
||||||
|
return envname
|
||||||
|
|
||||||
|
for env in config.envs():
|
||||||
|
if not board_ids:
|
||||||
|
return env
|
||||||
|
if not envname:
|
||||||
|
envname = env
|
||||||
|
items = config.items(env=env, as_dict=True)
|
||||||
|
if "board" in items and items.get("board") in board_ids:
|
||||||
|
return env
|
||||||
|
|
||||||
|
return envname
|
||||||
|
@ -15,47 +15,31 @@
|
|||||||
import codecs
|
import codecs
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from os.path import basename, isdir, isfile, join, realpath, relpath
|
|
||||||
|
|
||||||
import bottle
|
import bottle
|
||||||
|
|
||||||
from platformio import fs, util
|
from platformio import fs, util
|
||||||
from platformio.proc import where_is_program
|
from platformio.proc import where_is_program
|
||||||
from platformio.project.config import ProjectConfig
|
|
||||||
from platformio.project.helpers import load_project_ide_data
|
from platformio.project.helpers import load_project_ide_data
|
||||||
|
|
||||||
|
|
||||||
class ProjectGenerator(object):
|
class ProjectGenerator(object):
|
||||||
def __init__(self, project_dir, ide, boards):
|
def __init__(self, config, env_name, ide):
|
||||||
self.config = ProjectConfig.get_instance(join(project_dir, "platformio.ini"))
|
self.config = config
|
||||||
self.config.validate()
|
self.project_dir = os.path.dirname(config.path)
|
||||||
self.project_dir = project_dir
|
self.env_name = str(env_name)
|
||||||
self.ide = str(ide)
|
self.ide = str(ide)
|
||||||
self.env_name = str(self.get_best_envname(boards))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_supported_ides():
|
def get_supported_ides():
|
||||||
tpls_dir = join(fs.get_source_dir(), "ide", "tpls")
|
tpls_dir = os.path.join(fs.get_source_dir(), "ide", "tpls")
|
||||||
return sorted([d for d in os.listdir(tpls_dir) if isdir(join(tpls_dir, d))])
|
return sorted(
|
||||||
|
[
|
||||||
def get_best_envname(self, boards=None):
|
d
|
||||||
envname = None
|
for d in os.listdir(tpls_dir)
|
||||||
default_envs = self.config.default_envs()
|
if os.path.isdir(os.path.join(tpls_dir, d))
|
||||||
if default_envs:
|
]
|
||||||
envname = default_envs[0]
|
)
|
||||||
if not boards:
|
|
||||||
return envname
|
|
||||||
|
|
||||||
for env in self.config.envs():
|
|
||||||
if not boards:
|
|
||||||
return env
|
|
||||||
if not envname:
|
|
||||||
envname = env
|
|
||||||
items = self.config.items(env=env, as_dict=True)
|
|
||||||
if "board" in items and items.get("board") in boards:
|
|
||||||
return env
|
|
||||||
|
|
||||||
return envname
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def filter_includes(includes_map, ignore_scopes=None, to_unix_path=True):
|
def filter_includes(includes_map, ignore_scopes=None, to_unix_path=True):
|
||||||
@ -75,12 +59,12 @@ class ProjectGenerator(object):
|
|||||||
tpl_vars = {
|
tpl_vars = {
|
||||||
"config": self.config,
|
"config": self.config,
|
||||||
"systype": util.get_systype(),
|
"systype": util.get_systype(),
|
||||||
"project_name": basename(self.project_dir),
|
"project_name": os.path.basename(self.project_dir),
|
||||||
"project_dir": self.project_dir,
|
"project_dir": self.project_dir,
|
||||||
"env_name": self.env_name,
|
"env_name": self.env_name,
|
||||||
"user_home_dir": realpath(fs.expanduser("~")),
|
"user_home_dir": os.path.realpath(fs.expanduser("~")),
|
||||||
"platformio_path": sys.argv[0]
|
"platformio_path": sys.argv[0]
|
||||||
if isfile(sys.argv[0])
|
if os.path.isfile(sys.argv[0])
|
||||||
else where_is_program("platformio"),
|
else where_is_program("platformio"),
|
||||||
"env_path": os.getenv("PATH"),
|
"env_path": os.getenv("PATH"),
|
||||||
"env_pathsep": os.pathsep,
|
"env_pathsep": os.pathsep,
|
||||||
@ -97,7 +81,7 @@ class ProjectGenerator(object):
|
|||||||
"src_files": self.get_src_files(),
|
"src_files": self.get_src_files(),
|
||||||
"project_src_dir": self.config.get_optional_dir("src"),
|
"project_src_dir": self.config.get_optional_dir("src"),
|
||||||
"project_lib_dir": self.config.get_optional_dir("lib"),
|
"project_lib_dir": self.config.get_optional_dir("lib"),
|
||||||
"project_libdeps_dir": join(
|
"project_libdeps_dir": os.path.join(
|
||||||
self.config.get_optional_dir("libdeps"), self.env_name
|
self.config.get_optional_dir("libdeps"), self.env_name
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -120,12 +104,12 @@ class ProjectGenerator(object):
|
|||||||
with fs.cd(self.project_dir):
|
with fs.cd(self.project_dir):
|
||||||
for root, _, files in os.walk(self.config.get_optional_dir("src")):
|
for root, _, files in os.walk(self.config.get_optional_dir("src")):
|
||||||
for f in files:
|
for f in files:
|
||||||
result.append(relpath(join(root, f)))
|
result.append(os.path.relpath(os.path.join(root, f)))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_tpls(self):
|
def get_tpls(self):
|
||||||
tpls = []
|
tpls = []
|
||||||
tpls_dir = join(fs.get_source_dir(), "ide", "tpls", self.ide)
|
tpls_dir = os.path.join(fs.get_source_dir(), "ide", "tpls", self.ide)
|
||||||
for root, _, files in os.walk(tpls_dir):
|
for root, _, files in os.walk(tpls_dir):
|
||||||
for f in files:
|
for f in files:
|
||||||
if not f.endswith(".tpl"):
|
if not f.endswith(".tpl"):
|
||||||
@ -133,7 +117,7 @@ class ProjectGenerator(object):
|
|||||||
_relpath = root.replace(tpls_dir, "")
|
_relpath = root.replace(tpls_dir, "")
|
||||||
if _relpath.startswith(os.sep):
|
if _relpath.startswith(os.sep):
|
||||||
_relpath = _relpath[1:]
|
_relpath = _relpath[1:]
|
||||||
tpls.append((_relpath, join(root, f)))
|
tpls.append((_relpath, os.path.join(root, f)))
|
||||||
return tpls
|
return tpls
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
@ -141,12 +125,12 @@ class ProjectGenerator(object):
|
|||||||
for tpl_relpath, tpl_path in self.get_tpls():
|
for tpl_relpath, tpl_path in self.get_tpls():
|
||||||
dst_dir = self.project_dir
|
dst_dir = self.project_dir
|
||||||
if tpl_relpath:
|
if tpl_relpath:
|
||||||
dst_dir = join(self.project_dir, tpl_relpath)
|
dst_dir = os.path.join(self.project_dir, tpl_relpath)
|
||||||
if not isdir(dst_dir):
|
if not os.path.isdir(dst_dir):
|
||||||
os.makedirs(dst_dir)
|
os.makedirs(dst_dir)
|
||||||
file_name = basename(tpl_path)[:-4]
|
file_name = os.path.basename(tpl_path)[:-4]
|
||||||
contents = self._render_tpl(tpl_path, tpl_vars)
|
contents = self._render_tpl(tpl_path, tpl_vars)
|
||||||
self._merge_contents(join(dst_dir, file_name), contents)
|
self._merge_contents(os.path.join(dst_dir, file_name), contents)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _render_tpl(tpl_path, tpl_vars):
|
def _render_tpl(tpl_path, tpl_vars):
|
||||||
@ -155,7 +139,7 @@ class ProjectGenerator(object):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _merge_contents(dst_path, contents):
|
def _merge_contents(dst_path, contents):
|
||||||
if basename(dst_path) == ".gitignore" and isfile(dst_path):
|
if os.path.basename(dst_path) == ".gitignore" and os.path.isfile(dst_path):
|
||||||
return
|
return
|
||||||
with codecs.open(dst_path, "w", encoding="utf8") as fp:
|
with codecs.open(dst_path, "w", encoding="utf8") as fp:
|
||||||
fp.write(contents)
|
fp.write(contents)
|
||||||
|
@ -62,29 +62,50 @@ def test_init_ide_without_board(clirunner, tmpdir):
|
|||||||
assert isinstance(result.exception, ProjectEnvsNotAvailableError)
|
assert isinstance(result.exception, ProjectEnvsNotAvailableError)
|
||||||
|
|
||||||
|
|
||||||
def test_init_ide_atom(clirunner, validate_cliresult, tmpdir):
|
def test_init_ide_vscode(clirunner, validate_cliresult, tmpdir):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
result = clirunner.invoke(
|
result = clirunner.invoke(
|
||||||
cmd_init, ["--ide", "atom", "-b", "uno", "-b", "teensy31"]
|
cmd_init, ["--ide", "vscode", "-b", "uno", "-b", "teensy31"]
|
||||||
)
|
)
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(str(tmpdir))
|
validate_pioproject(str(tmpdir))
|
||||||
assert all(
|
assert all(
|
||||||
[tmpdir.join(f).check() for f in (".clang_complete", ".gcc-flags.json")]
|
[
|
||||||
|
tmpdir.join(".vscode").join(f).check()
|
||||||
|
for f in ("c_cpp_properties.json", "launch.json")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
"framework-arduino-avr"
|
||||||
|
in tmpdir.join(".vscode").join("c_cpp_properties.json").read()
|
||||||
)
|
)
|
||||||
assert "framework-arduino" in tmpdir.join(".clang_complete").read()
|
|
||||||
|
|
||||||
# switch to NodeMCU
|
# switch to NodeMCU
|
||||||
result = clirunner.invoke(cmd_init, ["--ide", "atom", "-b", "nodemcuv2"])
|
result = clirunner.invoke(cmd_init, ["--ide", "vscode", "-b", "nodemcuv2"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(str(tmpdir))
|
validate_pioproject(str(tmpdir))
|
||||||
assert "arduinoespressif" in tmpdir.join(".clang_complete").read()
|
assert (
|
||||||
|
"framework-arduinoespressif8266"
|
||||||
|
in tmpdir.join(".vscode").join("c_cpp_properties.json").read()
|
||||||
|
)
|
||||||
|
|
||||||
|
# switch to teensy31 via env name
|
||||||
|
result = clirunner.invoke(cmd_init, ["--ide", "vscode", "-e", "teensy31"])
|
||||||
|
validate_cliresult(result)
|
||||||
|
validate_pioproject(str(tmpdir))
|
||||||
|
assert (
|
||||||
|
"framework-arduinoteensy"
|
||||||
|
in tmpdir.join(".vscode").join("c_cpp_properties.json").read()
|
||||||
|
)
|
||||||
|
|
||||||
# switch to the first board
|
# switch to the first board
|
||||||
result = clirunner.invoke(cmd_init, ["--ide", "atom"])
|
result = clirunner.invoke(cmd_init, ["--ide", "vscode"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(str(tmpdir))
|
validate_pioproject(str(tmpdir))
|
||||||
assert "framework-arduino" in tmpdir.join(".clang_complete").read()
|
assert (
|
||||||
|
"framework-arduino-avr"
|
||||||
|
in tmpdir.join(".vscode").join("c_cpp_properties.json").read()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_init_ide_eclipse(clirunner, validate_cliresult):
|
def test_init_ide_eclipse(clirunner, validate_cliresult):
|
||||||
|
Reference in New Issue
Block a user