forked from platformio/platformio-core
Support "force_ansi" option for core.exec and allow to raise exception on cmd error
This commit is contained in:
@ -14,6 +14,7 @@
|
||||
|
||||
import asyncio
|
||||
import functools
|
||||
import os
|
||||
|
||||
from platformio import __main__, __version__, app, proc, util
|
||||
from platformio.compat import (
|
||||
@ -21,10 +22,16 @@ from platformio.compat import (
|
||||
aio_create_task,
|
||||
aio_get_running_loop,
|
||||
get_locale_encoding,
|
||||
shlex_join,
|
||||
)
|
||||
from platformio.exception import UserSideException
|
||||
from platformio.home.rpc.handlers.base import BaseRPCHandler
|
||||
|
||||
|
||||
class PIOCoreCallError(UserSideException):
|
||||
MESSAGE = 'An error occured while executing PIO Core command: "{0}"\n\n{1}'
|
||||
|
||||
|
||||
class PIOCoreProtocol(asyncio.SubprocessProtocol):
|
||||
def __init__(self, exit_future, on_data_callback=None):
|
||||
self.exit_future = exit_future
|
||||
@ -66,27 +73,41 @@ class CoreRPC(BaseRPCHandler):
|
||||
def version():
|
||||
return __version__
|
||||
|
||||
async def exec(self, args, options=None):
|
||||
async def exec(self, args, options=None, raise_exception=False):
|
||||
options = options or {}
|
||||
loop = aio_get_running_loop()
|
||||
exit_future = loop.create_future()
|
||||
data_callback = functools.partial(
|
||||
self._on_exec_data_received, exec_options=options
|
||||
)
|
||||
|
||||
if args[0] != "--caller" and app.get_session_var("caller_id"):
|
||||
args = ["--caller", app.get_session_var("caller_id")] + args
|
||||
kwargs = options.get("spawn", {})
|
||||
|
||||
if "forceANSI" in options:
|
||||
environ = kwargs.get("env", os.environ.copy())
|
||||
environ["PLATFORMIO_FORCE_ANSI"] = "true"
|
||||
kwargs["env"] = environ
|
||||
|
||||
transport, protocol = await loop.subprocess_exec(
|
||||
lambda: PIOCoreProtocol(exit_future, data_callback),
|
||||
get_core_fullpath(),
|
||||
*args,
|
||||
stdin=None,
|
||||
**options.get("spawn", {}),
|
||||
**kwargs,
|
||||
)
|
||||
await exit_future
|
||||
transport.close()
|
||||
return_code = transport.get_returncode()
|
||||
if return_code != 0 and raise_exception:
|
||||
raise PIOCoreCallError(
|
||||
shlex_join(["pio"] + args), f"{protocol.stdout}\n{protocol.stderr}"
|
||||
)
|
||||
return {
|
||||
"stdout": protocol.stdout,
|
||||
"stderr": protocol.stderr,
|
||||
"returncode": transport.get_returncode(),
|
||||
"returncode": return_code,
|
||||
}
|
||||
|
||||
def _on_exec_data_received(self, exec_options, pipe, data):
|
||||
|
@ -48,19 +48,15 @@ class ProjectRPC(BaseRPCHandler):
|
||||
if not os.path.isdir(project_dir):
|
||||
os.makedirs(project_dir)
|
||||
|
||||
envclone = os.environ.copy()
|
||||
envclone["PLATFORMIO_FORCE_ANSI"] = "true"
|
||||
options = options or {}
|
||||
options["spawn"] = {"env": envclone, "cwd": project_dir}
|
||||
|
||||
args = ["project", "init"]
|
||||
args = ["project", "init", "-d", project_dir]
|
||||
ide = app.get_session_var("caller_id")
|
||||
if ide in ProjectGenerator.get_supported_ides():
|
||||
args.extend(["--ide", ide])
|
||||
|
||||
exec_options = options.get("exec", {})
|
||||
if configuration.get("example"):
|
||||
await self.factory.notify_clients(
|
||||
method=options.get("stdoutNotificationMethod"),
|
||||
method=exec_options.get("stdoutNotificationMethod"),
|
||||
params=["Copying example files...\n"],
|
||||
actor="frontend",
|
||||
)
|
||||
@ -68,7 +64,9 @@ class ProjectRPC(BaseRPCHandler):
|
||||
else:
|
||||
args.extend(self._pre_init_empty(configuration))
|
||||
|
||||
return await self.factory.manager.dispatcher["core.exec"](args, options=options)
|
||||
return await self.factory.manager.dispatcher["core.exec"](
|
||||
args, options=exec_options
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _pre_init_empty(configuration):
|
||||
@ -115,9 +113,9 @@ class ProjectRPC(BaseRPCHandler):
|
||||
def configuration(project_dir, env):
|
||||
assert is_platformio_project(project_dir)
|
||||
with fs.cd(project_dir):
|
||||
config = ProjectConfig(os.path.join(project_dir, "platformio.ini"))
|
||||
platform = PlatformFactory.from_env(env, autoinstall=True)
|
||||
platform_pkg = PlatformPackageManager().get_package(platform.get_dir())
|
||||
config = ProjectConfig.get_instance()
|
||||
board_id = config.get(f"env:{env}", "board", None)
|
||||
|
||||
# frameworks
|
||||
|
Reference in New Issue
Block a user