Added support for the latest Python "Click" package (CLI Builder) // Resolve #349

This commit is contained in:
Ivan Kravets
2019-05-09 00:51:28 +03:00
parent 7687a0a929
commit 62b80c396b
11 changed files with 75 additions and 58 deletions

View File

@ -14,6 +14,8 @@ PlatformIO 4.0
* Include external configuration files with `extra_configs <http://docs.platformio.org/page/projectconf/section_platformio.html#extra-configs>`__ option
(`issue #1590 <https://github.com/platformio/platformio-core/issues/1590>`_)
* Override default source and include directories for a library via `library.json <http://docs.platformio.org/page/librarymanager/config.html>`__ manifest using ``includeDir`` and ``srcDir`` fields
* Added support for the latest Python "Click" package (CLI Builder)
(`issue #349 <https://github.com/platformio/platformio-core/issues/349>`_)
PlatformIO 3.0
--------------

View File

@ -14,49 +14,13 @@
import os
import sys
from os.path import join
from platform import system
from traceback import format_exc
import click
from platformio import __version__, exception, maintenance
from platformio.util import get_source_dir
class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
def list_commands(self, ctx):
cmds = []
for filename in os.listdir(join(get_source_dir(), "commands")):
if filename.startswith("__init__"):
continue
if filename.endswith(".py"):
cmds.append(filename[:-3])
cmds.sort()
return cmds
def get_command(self, ctx, cmd_name):
mod = None
try:
mod = __import__("platformio.commands." + cmd_name, None, None,
["cli"])
except ImportError:
try:
return self._handle_obsolate_command(cmd_name)
except AttributeError:
raise click.UsageError('No such command "%s"' % cmd_name, ctx)
return mod.cli
@staticmethod
def _handle_obsolate_command(name):
if name == "platforms":
from platformio.commands import platform
return platform.cli
if name == "serialports":
from platformio.commands import device
return device.cli
raise AttributeError()
from platformio.commands import PlatformioCLI
@click.command(

View File

@ -11,3 +11,51 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from os.path import dirname, join
import click
class PlatformioCLI(click.MultiCommand):
leftover_args = []
def invoke(self, ctx):
PlatformioCLI.leftover_args = ctx.args
if hasattr(ctx, "protected_args"):
PlatformioCLI.leftover_args = ctx.protected_args + ctx.args
return super(PlatformioCLI, self).invoke(ctx)
def list_commands(self, ctx):
cmds = []
for filename in os.listdir(join(dirname(__file__), "commands")):
if filename.startswith("__init__"):
continue
if filename.endswith(".py"):
cmds.append(filename[:-3])
cmds.sort()
return cmds
def get_command(self, ctx, cmd_name):
mod = None
try:
mod = __import__("platformio.commands." + cmd_name, None, None,
["cli"])
except ImportError:
try:
return self._handle_obsolate_command(cmd_name)
except AttributeError:
raise click.UsageError('No such command "%s"' % cmd_name, ctx)
return mod.cli
@staticmethod
def _handle_obsolate_command(name):
if name == "platforms":
from platformio.commands import platform
return platform.cli
if name == "serialports":
from platformio.commands import device
return device.cli
raise AttributeError()

View File

@ -21,6 +21,7 @@ from os.path import isdir, join
import click
from platformio import exception, util
from platformio.commands import PlatformioCLI
from platformio.managers.lib import LibraryManager, get_builtin_libs
from platformio.project.helpers import (
get_project_dir, get_projectlibdeps_dir, is_platformio_project)
@ -78,7 +79,7 @@ def cli(ctx, **options):
ctx.invoked_subcommand)
ctx.obj = LibraryManager(storage_dir)
if "--json-output" not in ctx.args:
if "--json-output" not in PlatformioCLI.leftover_args:
click.echo("Library Storage: " + storage_dir)

View File

@ -22,6 +22,7 @@ import click
import semantic_version
from platformio import __version__, app, exception, telemetry, util
from platformio.commands import PlatformioCLI
from platformio.commands.lib import lib_update as cmd_lib_update
from platformio.commands.platform import \
platform_install as cmd_platform_install
@ -40,12 +41,12 @@ def on_platformio_start(ctx, force, caller):
set_caller(caller)
telemetry.on_command()
if not in_silence(ctx):
if not in_silence():
after_upgrade(ctx)
def on_platformio_end(ctx, result): # pylint: disable=W0613
if in_silence(ctx):
def on_platformio_end(ctx, result): # pylint: disable=unused-argument
if in_silence():
return
try:
@ -64,14 +65,11 @@ def on_platformio_exception(e):
telemetry.on_exception(e)
def in_silence(ctx=None):
ctx = ctx or app.get_session_var("command_ctx")
if not ctx:
return True
return ctx.args and any([
ctx.args[0] == "debug" and "--interpreter" in " ".join(ctx.args),
ctx.args[0] == "upgrade", "--json-output" in ctx.args,
"--version" in ctx.args
def in_silence():
args = PlatformioCLI.leftover_args
return args and any([
args[0] == "debug" and "--interpreter" in " ".join(args),
args[0] == "upgrade", "--json-output" in args, "--version" in args
])

View File

@ -27,7 +27,7 @@ CORE_PACKAGES = {
"contrib-piohome": "^2.0.1",
"contrib-pysite":
"~2.%d%d.190418" % (sys.version_info[0], sys.version_info[1]),
"tool-pioplus": "^2.1.4",
"tool-pioplus": "^2.1.5",
"tool-unity": "~1.20403.0",
"tool-scons": "~2.20501.7" if util.PY2 else "~3.30005.0"
}

View File

@ -27,6 +27,7 @@ import click
import requests
from platformio import __version__, app, exception, util
from platformio.commands import PlatformioCLI
try:
import queue
@ -133,10 +134,10 @@ class MeasurementProtocol(TelemetryBase):
return _arg
return None
if not app.get_session_var("command_ctx"):
return
ctx_args = app.get_session_var("command_ctx").args
args = [str(s).lower() for s in ctx_args if not str(s).startswith("-")]
args = [
str(arg).lower() for arg in PlatformioCLI.leftover_args
if not str(arg).startswith("-")
]
if not args:
return
cmd_path = args[:1]

View File

@ -19,7 +19,7 @@ from platformio import (__author__, __description__, __email__, __license__,
install_requires = [
"bottle<0.13",
"click>=5,<6",
"click>=5,<8",
"colorama",
"pyserial>=3,<4,!=3.3",
"requests>=2.4.0,<3",

View File

@ -57,7 +57,7 @@ def test_init_duplicated_boards(clirunner, validate_cliresult, tmpdir):
def test_init_ide_without_board(clirunner, tmpdir):
with tmpdir.as_cwd():
result = clirunner.invoke(cmd_init, ["--ide", "atom"])
assert result.exit_code == -1
assert result.exit_code != 0
assert isinstance(result.exception, exception.ProjectEnvsNotAvailable)

View File

@ -16,8 +16,11 @@ import json
import re
from platformio import exception
from platformio.commands import PlatformioCLI
from platformio.commands.lib import cli as cmd_lib
PlatformioCLI.leftover_args = ["--json-output"] # hook for click
def test_search(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_lib, ["search", "DHT22"])

View File

@ -38,14 +38,14 @@ def test_search_raw_output(clirunner, validate_cliresult):
def test_install_unknown_version(clirunner):
result = clirunner.invoke(cli_platform.platform_install,
["atmelavr@99.99.99"])
assert result.exit_code == -1
assert result.exit_code != 0
assert isinstance(result.exception, exception.UndefinedPackageVersion)
def test_install_unknown_from_registry(clirunner):
result = clirunner.invoke(cli_platform.platform_install,
["unknown-platform"])
assert result.exit_code == -1
assert result.exit_code != 0
assert isinstance(result.exception, exception.UnknownPackage)