Initial support for `Project Manager // Resolve #3335

This commit is contained in:
Ivan Kravets
2020-02-06 23:32:43 +02:00
parent d2033aacea
commit 73ce3c94e9
7 changed files with 88 additions and 23 deletions

View File

@ -6,7 +6,7 @@ Release Notes
PlatformIO Core 4.0 PlatformIO Core 4.0
------------------- -------------------
4.1.1 (2020-??-??) 4.2.0 (2020-02-??)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
* `PlatformIO Home 3.0 <http://docs.platformio.org/page/home/index.html>`__: * `PlatformIO Home 3.0 <http://docs.platformio.org/page/home/index.html>`__:
@ -18,6 +18,11 @@ PlatformIO Core 4.0
- Added support for `PVS-Studio <https://docs.platformio.org/page/plus/check-tools/pvs-studio.html>`__ static code analyzer - Added support for `PVS-Studio <https://docs.platformio.org/page/plus/check-tools/pvs-studio.html>`__ static code analyzer
* Initial support for `Project Manager <https://docs.platformio.org/page/userguide/project/cmd_config.html>`_ CLI:
- Show computed project configuration with a new `platformio project config <https://docs.platformio.org/page/userguide/project/cmd_config.html>`_ command or dump to JSON with ``platformio project config --json-output`` (`issue #3335 <https://github.com/platformio/platformio-core/issues/3335>`_)
- Moved ``platformio init`` command to `platformio project init <https://docs.platformio.org/page/userguide/project/cmd_init.html>`_
* Generate `compilation database "compile_commands.json" <https://docs.platformio.org/page/faq.html#compilation-database-compile-commands-json>`_ (`issue #2990 <https://github.com/platformio/platformio-core/issues/2990>`_) * Generate `compilation database "compile_commands.json" <https://docs.platformio.org/page/faq.html#compilation-database-compile-commands-json>`_ (`issue #2990 <https://github.com/platformio/platformio-core/issues/2990>`_)
* Control debug flags and optimization level with a new `debug_build_flags <https://docs.platformio.org/page/projectconf/section_env_debug.html#debug-build-flags>`__ option * Control debug flags and optimization level with a new `debug_build_flags <https://docs.platformio.org/page/projectconf/section_env_debug.html#debug-build-flags>`__ option
* Install a dev-platform with ALL declared packages using a new ``--with-all-packages`` option for `pio platform install <https://docs.platformio.org/page/userguide/platforms/cmd_install.html>`__ command (`issue #3345 <https://github.com/platformio/platformio-core/issues/3345>`_) * Install a dev-platform with ALL declared packages using a new ``--with-all-packages`` option for `pio platform install <https://docs.platformio.org/page/userguide/platforms/cmd_install.html>`__ command (`issue #3345 <https://github.com/platformio/platformio-core/issues/3345>`_)

2
docs

Submodule docs updated: ec5a17c390...506491d11c

View File

@ -63,5 +63,18 @@ class PlatformioCLI(click.MultiCommand):
mod_path = "platformio.commands.%s.command" % cmd_name mod_path = "platformio.commands.%s.command" % cmd_name
mod = __import__(mod_path, None, None, ["cli"]) mod = __import__(mod_path, None, None, ["cli"])
except ImportError: except ImportError:
try:
return self._handle_obsolate_command(cmd_name)
except AttributeError:
pass
raise click.UsageError('No such command "%s"' % cmd_name, ctx) raise click.UsageError('No such command "%s"' % cmd_name, ctx)
return mod.cli return mod.cli
@staticmethod
def _handle_obsolate_command(name):
# pylint: disable=import-outside-toplevel
if name == "init":
from platformio.commands.project import project_init
return project_init
raise AttributeError()

View File

@ -21,8 +21,8 @@ from tempfile import mkdtemp
import click import click
from platformio import app, fs from platformio import app, fs
from platformio.commands.init import cli as cmd_init from platformio.commands.project import project_init as cmd_project_init
from platformio.commands.init import validate_boards from platformio.commands.project import validate_boards
from platformio.commands.run.command import cli as cmd_run from platformio.commands.run.command import cli as cmd_run
from platformio.compat import glob_escape from platformio.compat import glob_escape
from platformio.exception import CIBuildEnvsEmpty from platformio.exception import CIBuildEnvsEmpty
@ -111,7 +111,10 @@ def cli( # pylint: disable=too-many-arguments, too-many-branches
# initialise project # initialise project
ctx.invoke( ctx.invoke(
cmd_init, project_dir=build_dir, board=board, project_option=project_option cmd_project_init,
project_dir=build_dir,
board=board,
project_option=project_option,
) )
# process project # process project

View File

@ -14,19 +14,61 @@
# pylint: disable=too-many-arguments,too-many-locals, too-many-branches # pylint: disable=too-many-arguments,too-many-locals, too-many-branches
from os import getcwd, makedirs import os
from os.path import isdir, isfile, join
import click import click
from tabulate import tabulate
from platformio import exception, fs from platformio import exception, fs
from platformio.commands.platform import platform_install as cli_platform_install from platformio.commands.platform import platform_install as cli_platform_install
from platformio.ide.projectgenerator import ProjectGenerator from platformio.ide.projectgenerator import ProjectGenerator
from platformio.managers.platform import PlatformManager from platformio.managers.platform import PlatformManager
from platformio.project.config import ProjectConfig from platformio.project.config import ProjectConfig
from platformio.project.exception import NotPlatformIOProjectError
from platformio.project.helpers import is_platformio_project from platformio.project.helpers import is_platformio_project
@click.group(short_help="Project Manager")
def cli():
pass
@cli.command("config", short_help="Show computed configuration")
@click.option(
"-d",
"--project-dir",
default=os.getcwd,
type=click.Path(
exists=True, file_okay=True, dir_okay=True, writable=True, resolve_path=True
),
)
@click.option("--json-output", is_flag=True)
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.echo()
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",
)
)
return None
def validate_boards(ctx, param, value): # pylint: disable=W0613 def validate_boards(ctx, param, value): # pylint: disable=W0613
pm = PlatformManager() pm = PlatformManager()
for id_ in value: for id_ in value:
@ -40,11 +82,11 @@ def validate_boards(ctx, param, value): # pylint: disable=W0613
return value return value
@click.command("init", short_help="Initialize PlatformIO project or update existing") @cli.command("init", short_help="Initialize a project or update existing")
@click.option( @click.option(
"--project-dir", "--project-dir",
"-d", "-d",
default=getcwd, default=os.getcwd,
type=click.Path( type=click.Path(
exists=True, file_okay=False, dir_okay=True, writable=True, resolve_path=True exists=True, file_okay=False, dir_okay=True, writable=True, resolve_path=True
), ),
@ -55,7 +97,7 @@ def validate_boards(ctx, param, value): # pylint: disable=W0613
@click.option("--env-prefix", default="") @click.option("--env-prefix", default="")
@click.option("-s", "--silent", is_flag=True) @click.option("-s", "--silent", is_flag=True)
@click.pass_context @click.pass_context
def cli( def project_init(
ctx, # pylint: disable=R0913 ctx, # pylint: disable=R0913
project_dir, project_dir,
board, board,
@ -65,7 +107,7 @@ def cli(
silent, silent,
): ):
if not silent: if not silent:
if project_dir == getcwd(): if project_dir == os.getcwd():
click.secho("\nThe current working directory", fg="yellow", nl=False) click.secho("\nThe current working directory", fg="yellow", nl=False)
click.secho(" %s " % project_dir, fg="cyan", nl=False) click.secho(" %s " % project_dir, fg="cyan", nl=False)
click.secho("will be used for the project.", fg="yellow") click.secho("will be used for the project.", fg="yellow")
@ -137,16 +179,16 @@ def init_base_project(project_dir):
(config.get_optional_dir("test"), init_test_readme), (config.get_optional_dir("test"), init_test_readme),
] ]
for (path, cb) in dir_to_readme: for (path, cb) in dir_to_readme:
if isdir(path): if os.path.isdir(path):
continue continue
makedirs(path) os.makedirs(path)
if cb: if cb:
cb(path) cb(path)
def init_include_readme(include_dir): def init_include_readme(include_dir):
fs.write_file_contents( fs.write_file_contents(
join(include_dir, "README"), os.path.join(include_dir, "README"),
""" """
This directory is intended for project header files. This directory is intended for project header files.
@ -193,7 +235,7 @@ https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
def init_lib_readme(lib_dir): def init_lib_readme(lib_dir):
# pylint: disable=line-too-long # pylint: disable=line-too-long
fs.write_file_contents( fs.write_file_contents(
join(lib_dir, "README"), os.path.join(lib_dir, "README"),
""" """
This directory is intended for project specific (private) libraries. This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file. PlatformIO will compile them to static libraries and link into executable file.
@ -246,7 +288,7 @@ More information about PlatformIO Library Dependency Finder
def init_test_readme(test_dir): def init_test_readme(test_dir):
fs.write_file_contents( fs.write_file_contents(
join(test_dir, "README"), os.path.join(test_dir, "README"),
""" """
This directory is intended for PIO Unit Testing and project tests. This directory is intended for PIO Unit Testing and project tests.
@ -263,8 +305,8 @@ More information about PIO Unit Testing:
def init_ci_conf(project_dir): def init_ci_conf(project_dir):
conf_path = join(project_dir, ".travis.yml") conf_path = os.path.join(project_dir, ".travis.yml")
if isfile(conf_path): if os.path.isfile(conf_path):
return return
fs.write_file_contents( fs.write_file_contents(
conf_path, conf_path,
@ -340,8 +382,8 @@ def init_ci_conf(project_dir):
def init_cvs_ignore(project_dir): def init_cvs_ignore(project_dir):
conf_path = join(project_dir, ".gitignore") conf_path = os.path.join(project_dir, ".gitignore")
if isfile(conf_path): if os.path.isfile(conf_path):
return return
fs.write_file_contents(conf_path, ".pio\n") fs.write_file_contents(conf_path, ".pio\n")
@ -349,7 +391,9 @@ def init_cvs_ignore(project_dir):
def fill_project_envs( def fill_project_envs(
ctx, project_dir, board_ids, project_option, env_prefix, force_download ctx, project_dir, board_ids, project_option, env_prefix, force_download
): ):
config = ProjectConfig(join(project_dir, "platformio.ini"), parse_extra=False) config = ProjectConfig(
os.path.join(project_dir, "platformio.ini"), parse_extra=False
)
used_boards = [] used_boards = []
for section in config.sections(): for section in config.sections():
cond = [section.startswith("env:"), config.has_option(section, "board")] cond = [section.startswith("env:"), config.has_option(section, "board")]

View File

@ -24,7 +24,7 @@ class NotPlatformIOProjectError(ProjectError, UserSideException):
MESSAGE = ( MESSAGE = (
"Not a PlatformIO project. `platformio.ini` file has not been " "Not a PlatformIO project. `platformio.ini` file has not been "
"found in current working directory ({0}). To initialize new project " "found in current working directory ({0}). To initialize new project "
"please use `platformio init` command" "please use `platformio project init` command"
) )

View File

@ -17,7 +17,7 @@ from os import getcwd, makedirs
from os.path import getsize, isdir, isfile, join from os.path import getsize, isdir, isfile, join
from platformio.commands.boards import cli as cmd_boards from platformio.commands.boards import cli as cmd_boards
from platformio.commands.init import cli as cmd_init from platformio.commands.project import project_init as cmd_init
from platformio.project.config import ProjectConfig from platformio.project.config import ProjectConfig
from platformio.project.exception import ProjectEnvsNotAvailableError from platformio.project.exception import ProjectEnvsNotAvailableError