mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-29 17:47:14 +02:00
Merge branch 'release/v5.1.1'
This commit is contained in:
@ -1,3 +0,0 @@
|
||||
[settings]
|
||||
line_length=88
|
||||
known_third_party=OpenSSL, SCons, jsonrpc, twisted, zope
|
13
HISTORY.rst
13
HISTORY.rst
@ -8,12 +8,21 @@ PlatformIO Core 5
|
||||
|
||||
**A professional collaborative platform for embedded development**
|
||||
|
||||
5.1.1 (2021-03-17)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Fixed a "The command line is too long" issue with a linking process on Windows (`issue #3827 <https://github.com/platformio/platformio-core/issues/3827>`_)
|
||||
* Fixed an issue with `device monitor <https://docs.platformio.org/page/core/userguide/device/cmd_monitor.html>`__ when the "send_on_enter" filter didn't send EOL chars (`issue #3787 <https://github.com/platformio/platformio-core/issues/3787>`_)
|
||||
* Fixed an issue with silent mode when unwanted data is printed to stdout (`issue #3837 <https://github.com/platformio/platformio-core/issues/3837>`_)
|
||||
* Fixed an issue when code inspection fails with "Bad JSON" (`issue #3790 <https://github.com/platformio/platformio-core/issues/3790>`_)
|
||||
* Fixed an issue with overriding user-specified debugging configuration information in VSCode (`issue #3824 <https://github.com/platformio/platformio-core/issues/3824>`_)
|
||||
|
||||
5.1.0 (2021-01-28)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* **PlatformIO Home**
|
||||
|
||||
- Boosted PlatformIO Home performance thanks to migrating the codebase to the pure Python 3 Asynchronous I/O stack
|
||||
- Boosted `PlatformIO Home <https://docs.platformio.org/page/home/index.html>`__ performance thanks to migrating the codebase to the pure Python 3 Asynchronous I/O stack
|
||||
- Added a new ``--session-id`` option to `pio home <https://docs.platformio.org/page/core/userguide/cmd_home.html>`__ command that helps to keep PlatformIO Home isolated from other instances and protect from 3rd party access (`issue #3397 <https://github.com/platformio/platformio-core/issues/3397>`_)
|
||||
|
||||
* **Build System**
|
||||
@ -45,7 +54,7 @@ PlatformIO Core 5
|
||||
- Improved listing of `multicast DNS services <https://docs.platformio.org/page/core/userguide/device/cmd_list.html>`_
|
||||
- Fixed a "UnicodeDecodeError: 'utf-8' codec can't decode byte" when using J-Link for firmware uploading on Linux (`issue #3804 <https://github.com/platformio/platformio-core/issues/3804>`_)
|
||||
- Fixed an issue with a compiler driver for ".ccls" language server (`issue #3808 <https://github.com/platformio/platformio-core/issues/3808>`_)
|
||||
- Fixed an issue when `pio device monitor --eol <https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html#cmdoption-pio-device-monitor-eol>`__ and "send_on_enter" filter do not work properly (`issue #3787 <https://github.com/platformio/platformio-core/issues/3787>`_)
|
||||
- Fixed an issue when `pio device monitor --eol <https://docs.platformio.org/page/core/userguide/device/cmd_monitor.html#cmdoption-pio-device-monitor-eol>`__ and "send_on_enter" filter do not work properly (`issue #3787 <https://github.com/platformio/platformio-core/issues/3787>`_)
|
||||
|
||||
5.0.4 (2020-12-30)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
2
docs
2
docs
Submodule docs updated: 25edd66d55...3293903cac
2
examples
2
examples
Submodule examples updated: 8a6e639b2b...a0631a8b07
@ -14,7 +14,7 @@
|
||||
|
||||
import sys
|
||||
|
||||
VERSION = (5, 1, 0)
|
||||
VERSION = (5, 1, 1)
|
||||
__version__ = ".".join([str(s) for s in VERSION])
|
||||
|
||||
__title__ = "platformio"
|
||||
@ -47,7 +47,7 @@ __pioremote_endpoint__ = "ssl:host=remote.platformio.org:port=4413"
|
||||
__default_requests_timeout__ = (10, None) # (connect, read)
|
||||
|
||||
__core_packages__ = {
|
||||
"contrib-piohome": "~3.3.3",
|
||||
"contrib-piohome": "~3.3.4",
|
||||
"contrib-pysite": "~2.%d%d.0" % (sys.version_info.major, sys.version_info.minor),
|
||||
"tool-unity": "~1.20500.0",
|
||||
"tool-scons": "~2.20501.7" if sys.version_info.major == 2 else "~4.40100.2",
|
||||
|
@ -26,8 +26,8 @@ from platformio.compat import WINDOWS, hashlib_encode_data
|
||||
# There are the next limits depending on a platform:
|
||||
# - Windows = 8192
|
||||
# - Unix = 131072
|
||||
# We need ~256 characters for a temporary file path
|
||||
MAX_LINE_LENGTH = (8192 if WINDOWS else 131072) - 256
|
||||
# We need ~512 characters for compiler and temporary file paths
|
||||
MAX_LINE_LENGTH = (8192 if WINDOWS else 131072) - 512
|
||||
|
||||
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
|
||||
|
||||
|
@ -52,6 +52,7 @@ def BoardConfig(env, board=None):
|
||||
except (AssertionError, UnknownBoard) as e:
|
||||
sys.stderr.write("Error: %s\n" % str(e))
|
||||
env.Exit(1)
|
||||
return None
|
||||
|
||||
|
||||
def GetFrameworkScript(env, framework):
|
||||
|
@ -96,14 +96,13 @@ class CppcheckCheckTool(CheckToolBase):
|
||||
)
|
||||
click.echo()
|
||||
self._bad_input = True
|
||||
self._buffer = ""
|
||||
return None
|
||||
|
||||
self._buffer = ""
|
||||
return DefectItem(**args)
|
||||
|
||||
def configure_command(
|
||||
self, language, src_files
|
||||
): # pylint: disable=arguments-differ
|
||||
def configure_command(self, language, src_file): # pylint: disable=arguments-differ
|
||||
tool_path = os.path.join(get_core_package_dir("tool-cppcheck"), "cppcheck")
|
||||
|
||||
cmd = [
|
||||
@ -157,8 +156,8 @@ class CppcheckCheckTool(CheckToolBase):
|
||||
"--include=" + inc
|
||||
for inc in self.get_forced_includes(build_flags, self.cpp_includes)
|
||||
)
|
||||
cmd.append("--file-list=%s" % self._generate_src_file(src_files))
|
||||
cmd.append("--includes-file=%s" % self._generate_inc_file())
|
||||
cmd.append('"%s"' % src_file)
|
||||
|
||||
return cmd
|
||||
|
||||
@ -227,23 +226,25 @@ class CppcheckCheckTool(CheckToolBase):
|
||||
|
||||
def check(self, on_defect_callback=None):
|
||||
self._on_defect_callback = on_defect_callback
|
||||
project_files = self.get_project_target_files(self.options["patterns"])
|
||||
|
||||
languages = ("c", "c++")
|
||||
if not any([project_files[t] for t in languages]):
|
||||
project_files = self.get_project_target_files(self.options["patterns"])
|
||||
src_files_scope = ("c", "c++")
|
||||
if not any(project_files[t] for t in src_files_scope):
|
||||
click.echo("Error: Nothing to check.")
|
||||
return True
|
||||
for language in languages:
|
||||
if not project_files[language]:
|
||||
continue
|
||||
cmd = self.configure_command(language, project_files[language])
|
||||
if not cmd:
|
||||
self._bad_input = True
|
||||
continue
|
||||
if self.options.get("verbose"):
|
||||
click.echo(" ".join(cmd))
|
||||
|
||||
self.execute_check_cmd(cmd)
|
||||
for scope, files in project_files.items():
|
||||
if scope not in src_files_scope:
|
||||
continue
|
||||
for src_file in files:
|
||||
cmd = self.configure_command(scope, src_file)
|
||||
if not cmd:
|
||||
self._bad_input = True
|
||||
continue
|
||||
if self.options.get("verbose"):
|
||||
click.echo(" ".join(cmd))
|
||||
|
||||
self.execute_check_cmd(cmd)
|
||||
|
||||
self.clean_up()
|
||||
|
||||
|
@ -187,7 +187,13 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
|
||||
flags = self.cc_flags
|
||||
compiler = self.cc_path
|
||||
|
||||
cmd = [compiler, src_file, "-E", "-o", self._tmp_preprocessed_file]
|
||||
cmd = [
|
||||
compiler,
|
||||
'"%s"' % src_file,
|
||||
"-E",
|
||||
"-o",
|
||||
'"%s"' % self._tmp_preprocessed_file,
|
||||
]
|
||||
cmd.extend([f for f in flags if f])
|
||||
cmd.extend(["-D%s" % d for d in self.cpp_defines])
|
||||
cmd.append('@"%s"' % self._tmp_cmd_file)
|
||||
|
@ -192,7 +192,7 @@ def configure_esp32_load_cmds(debug_options, configuration):
|
||||
debug_options["load_cmds"] != ["load"],
|
||||
"xtensa-esp32" not in configuration.get("cc_path", ""),
|
||||
not flash_images,
|
||||
not all([isfile(item["path"]) for item in flash_images]),
|
||||
not all(isfile(item["path"]) for item in flash_images),
|
||||
]
|
||||
if any(ignore_conds):
|
||||
return debug_options["load_cmds"]
|
||||
|
@ -32,7 +32,7 @@ class SendOnEnter(DeviceMonitorFilter):
|
||||
def tx(self, text):
|
||||
self._buffer += text
|
||||
if self._buffer.endswith(self._eol):
|
||||
text = self._buffer[: len(self._eol) * -1]
|
||||
text = self._buffer
|
||||
self._buffer = ""
|
||||
return text
|
||||
return ""
|
||||
|
@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import jsonrpc
|
||||
from ajsonrpc.core import JSONRPC20DispatchException
|
||||
|
||||
from platformio.clients.account import AccountClient
|
||||
|
||||
@ -24,6 +24,6 @@ class AccountRPC:
|
||||
client = AccountClient()
|
||||
return getattr(client, method)(*args, **kwargs)
|
||||
except Exception as e: # pylint: disable=bare-except
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
raise JSONRPC20DispatchException(
|
||||
code=4003, message="PIO Account Call Error", data=str(e)
|
||||
)
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
import time
|
||||
|
||||
import jsonrpc
|
||||
from ajsonrpc.core import JSONRPC20DispatchException
|
||||
|
||||
from platformio.compat import get_running_loop
|
||||
|
||||
@ -25,7 +25,7 @@ class IDERPC:
|
||||
|
||||
def send_command(self, sid, command, params):
|
||||
if not self._queue.get(sid):
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
raise JSONRPC20DispatchException(
|
||||
code=4005, message="PIO Home IDE agent is not started"
|
||||
)
|
||||
while self._queue[sid]:
|
||||
@ -33,11 +33,11 @@ class IDERPC:
|
||||
{"id": time.time(), "method": command, "params": params}
|
||||
)
|
||||
|
||||
def listen_commands(self, sid=0):
|
||||
async def listen_commands(self, sid=0):
|
||||
if sid not in self._queue:
|
||||
self._queue[sid] = []
|
||||
self._queue[sid].append(get_running_loop().create_future())
|
||||
return self._queue[sid][-1]
|
||||
return await self._queue[sid][-1]
|
||||
|
||||
def open_project(self, sid, project_dir):
|
||||
return self.send_command(sid, "open_project", project_dir)
|
||||
|
@ -20,7 +20,7 @@ import sys
|
||||
from io import StringIO
|
||||
|
||||
import click
|
||||
import jsonrpc
|
||||
from ajsonrpc.core import JSONRPC20DispatchException
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
|
||||
from platformio import __main__, __version__, fs, proc
|
||||
@ -99,7 +99,7 @@ class PIOCoreRPC:
|
||||
result = await PIOCoreRPC._call_subprocess(args, options)
|
||||
return PIOCoreRPC._process_result(result, to_json)
|
||||
except Exception as e: # pylint: disable=bare-except
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
raise JSONRPC20DispatchException(
|
||||
code=4003, message="PIO Core Call Error", data=str(e)
|
||||
)
|
||||
|
||||
|
@ -18,7 +18,7 @@ import os
|
||||
import shutil
|
||||
import time
|
||||
|
||||
import jsonrpc
|
||||
from ajsonrpc.core import JSONRPC20DispatchException
|
||||
|
||||
from platformio import exception, fs
|
||||
from platformio.commands.home.rpc.handlers.app import AppRPC
|
||||
@ -257,18 +257,16 @@ class ProjectRPC:
|
||||
return arduino_project_dir
|
||||
|
||||
is_arduino_project = any(
|
||||
[
|
||||
os.path.isfile(
|
||||
os.path.join(
|
||||
arduino_project_dir,
|
||||
"%s.%s" % (os.path.basename(arduino_project_dir), ext),
|
||||
)
|
||||
os.path.isfile(
|
||||
os.path.join(
|
||||
arduino_project_dir,
|
||||
"%s.%s" % (os.path.basename(arduino_project_dir), ext),
|
||||
)
|
||||
for ext in ("ino", "pde")
|
||||
]
|
||||
)
|
||||
for ext in ("ino", "pde")
|
||||
)
|
||||
if not is_arduino_project:
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
raise JSONRPC20DispatchException(
|
||||
code=4000, message="Not an Arduino project: %s" % arduino_project_dir
|
||||
)
|
||||
|
||||
@ -303,7 +301,7 @@ class ProjectRPC:
|
||||
@staticmethod
|
||||
async def import_pio(project_dir):
|
||||
if not project_dir or not is_platformio_project(project_dir):
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
raise JSONRPC20DispatchException(
|
||||
code=4001, message="Not an PlatformIO project: %s" % project_dir
|
||||
)
|
||||
new_project_dir = os.path.join(
|
||||
|
@ -12,14 +12,12 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import inspect
|
||||
import json
|
||||
|
||||
import click
|
||||
import jsonrpc
|
||||
from ajsonrpc.dispatcher import Dispatcher
|
||||
from ajsonrpc.manager import AsyncJSONRPCResponseManager
|
||||
from starlette.endpoints import WebSocketEndpoint
|
||||
|
||||
from platformio.compat import create_task, get_running_loop, is_bytes
|
||||
from platformio.compat import create_task, get_running_loop
|
||||
from platformio.proc import force_exit
|
||||
|
||||
|
||||
@ -30,13 +28,15 @@ class JSONRPCServerFactoryBase:
|
||||
|
||||
def __init__(self, shutdown_timeout=0):
|
||||
self.shutdown_timeout = shutdown_timeout
|
||||
self.dispatcher = jsonrpc.Dispatcher()
|
||||
self.manager = AsyncJSONRPCResponseManager(
|
||||
Dispatcher(), is_server_error_verbose=True
|
||||
)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def addHandler(self, handler, namespace):
|
||||
self.dispatcher.build_method_map(handler, prefix="%s." % namespace)
|
||||
def addObjectHandler(self, handler, namespace):
|
||||
self.manager.dispatcher.add_object(handler, prefix="%s." % namespace)
|
||||
|
||||
def on_client_connect(self):
|
||||
self.connection_nums += 1
|
||||
@ -90,29 +90,8 @@ class WebSocketJSONRPCServer(WebSocketEndpoint):
|
||||
self.factory.on_client_disconnect() # pylint: disable=no-member
|
||||
|
||||
async def _handle_rpc(self, websocket, data):
|
||||
response = jsonrpc.JSONRPCResponseManager.handle(
|
||||
data, self.factory.dispatcher # pylint: disable=no-member
|
||||
)
|
||||
if response.result and inspect.isawaitable(response.result):
|
||||
try:
|
||||
response.result = await response.result
|
||||
response.data["result"] = response.result
|
||||
response.error = None
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
if not isinstance(exc, jsonrpc.exceptions.JSONRPCDispatchException):
|
||||
exc = jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
code=4999, message=str(exc)
|
||||
)
|
||||
response.result = None
|
||||
response.error = exc.error._data # pylint: disable=protected-access
|
||||
new_data = response.data.copy()
|
||||
new_data["error"] = response.error
|
||||
del new_data["result"]
|
||||
response.data = new_data
|
||||
|
||||
# pylint: disable=no-member
|
||||
response = await self.factory.manager.get_response_for_payload(data)
|
||||
if response.error:
|
||||
click.secho("Error: %s" % response.error, fg="red", err=True)
|
||||
if "result" in response.data and is_bytes(response.data["result"]):
|
||||
response.data["result"] = response.data["result"].decode("utf-8")
|
||||
|
||||
await websocket.send_text(json.dumps(response.data))
|
||||
click.secho("Error: %s" % response.error.data, fg="red", err=True)
|
||||
await websocket.send_text(self.factory.manager.serialize(response.body))
|
||||
|
@ -65,13 +65,13 @@ def run_server(host, port, no_open, shutdown_timeout, home_url):
|
||||
raise PlatformioException("Invalid path to PIO Home Contrib")
|
||||
|
||||
ws_rpc_factory = WebSocketJSONRPCServerFactory(shutdown_timeout)
|
||||
ws_rpc_factory.addHandler(AccountRPC(), namespace="account")
|
||||
ws_rpc_factory.addHandler(AppRPC(), namespace="app")
|
||||
ws_rpc_factory.addHandler(IDERPC(), namespace="ide")
|
||||
ws_rpc_factory.addHandler(MiscRPC(), namespace="misc")
|
||||
ws_rpc_factory.addHandler(OSRPC(), namespace="os")
|
||||
ws_rpc_factory.addHandler(PIOCoreRPC(), namespace="core")
|
||||
ws_rpc_factory.addHandler(ProjectRPC(), namespace="project")
|
||||
ws_rpc_factory.addObjectHandler(AccountRPC(), namespace="account")
|
||||
ws_rpc_factory.addObjectHandler(AppRPC(), namespace="app")
|
||||
ws_rpc_factory.addObjectHandler(IDERPC(), namespace="ide")
|
||||
ws_rpc_factory.addObjectHandler(MiscRPC(), namespace="misc")
|
||||
ws_rpc_factory.addObjectHandler(OSRPC(), namespace="os")
|
||||
ws_rpc_factory.addObjectHandler(PIOCoreRPC(), namespace="core")
|
||||
ws_rpc_factory.addObjectHandler(ProjectRPC(), namespace="project")
|
||||
|
||||
path = urlparse(home_url).path
|
||||
routes = [
|
||||
|
@ -25,6 +25,7 @@ from tabulate import tabulate
|
||||
from platformio import app, exception, fs, util
|
||||
from platformio.commands.test.embedded import EmbeddedTestProcessor
|
||||
from platformio.commands.test.native import NativeTestProcessor
|
||||
from platformio.platform.factory import PlatformFactory
|
||||
from platformio.project.config import ProjectConfig
|
||||
|
||||
|
||||
@ -128,9 +129,9 @@ def cli( # pylint: disable=redefined-builtin
|
||||
not environment and default_envs and envname not in default_envs,
|
||||
testname != "*"
|
||||
and patterns["filter"]
|
||||
and not any([fnmatch(testname, p) for p in patterns["filter"]]),
|
||||
and not any(fnmatch(testname, p) for p in patterns["filter"]),
|
||||
testname != "*"
|
||||
and any([fnmatch(testname, p) for p in patterns["ignore"]]),
|
||||
and any(fnmatch(testname, p) for p in patterns["ignore"]),
|
||||
]
|
||||
if any(skip_conditions):
|
||||
results.append({"env": envname, "test": testname})
|
||||
@ -140,9 +141,9 @@ def cli( # pylint: disable=redefined-builtin
|
||||
print_processing_header(testname, envname)
|
||||
|
||||
cls = (
|
||||
NativeTestProcessor
|
||||
if config.get(section, "platform") == "native"
|
||||
else EmbeddedTestProcessor
|
||||
EmbeddedTestProcessor
|
||||
if is_embedded_platform(config.get(section, "platform"))
|
||||
else NativeTestProcessor
|
||||
)
|
||||
tp = cls(
|
||||
ctx,
|
||||
@ -194,6 +195,12 @@ def get_test_names(test_dir):
|
||||
return names
|
||||
|
||||
|
||||
def is_embedded_platform(name):
|
||||
if not name:
|
||||
return False
|
||||
return PlatformFactory.new(name).is_embedded()
|
||||
|
||||
|
||||
def print_processing_header(test, env):
|
||||
click.echo(
|
||||
"Processing %s in %s environment"
|
||||
|
@ -95,7 +95,7 @@ class EmbeddedTestProcessor(TestProcessorBase):
|
||||
if isinstance(line, bytes):
|
||||
line = line.decode("utf8", "ignore")
|
||||
self.on_run_out(line)
|
||||
if all([l in line for l in ("Tests", "Failures", "Ignored")]):
|
||||
if all(l in line for l in ("Tests", "Failures", "Ignored")):
|
||||
break
|
||||
ser.close()
|
||||
return not self._run_failed
|
||||
|
130
platformio/ide/tpls/vscode/.vscode/launch.json.tpl
vendored
130
platformio/ide/tpls/vscode/.vscode/launch.json.tpl
vendored
@ -1,50 +1,96 @@
|
||||
// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
|
||||
|
||||
// PIO Unified Debugger
|
||||
//
|
||||
// Documentation: https://docs.platformio.org/page/plus/debugging.html
|
||||
// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html
|
||||
|
||||
% from os.path import dirname, join
|
||||
% import codecs
|
||||
% import json
|
||||
% import os
|
||||
%
|
||||
% def _escape(text):
|
||||
% return text.replace('"', '\"')
|
||||
% end
|
||||
%
|
||||
% def _escape_path(path):
|
||||
% return path.replace('\\\\', '/').replace('\\', '/').replace('"', '\\"')
|
||||
% end
|
||||
%
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "platformio-debug",
|
||||
"request": "launch",
|
||||
"name": "PIO Debug",
|
||||
"executable": "{{ _escape_path(prog_path) }}",
|
||||
"projectEnvName": "{{ env_name }}",
|
||||
"toolchainBinDir": "{{ _escape_path(dirname(gdb_path)) }}",
|
||||
% if svd_path:
|
||||
"svdPath": "{{ _escape_path(svd_path) }}",
|
||||
% def get_pio_configurations():
|
||||
% predebug = {
|
||||
% "type": "platformio-debug",
|
||||
% "request": "launch",
|
||||
% "name": "PIO Debug (skip Pre-Debug)",
|
||||
% "executable": _escape_path(prog_path),
|
||||
% "projectEnvName": env_name,
|
||||
% "toolchainBinDir": _escape_path(os.path.dirname(gdb_path)),
|
||||
% "internalConsoleOptions": "openOnSessionStart",
|
||||
% }
|
||||
%
|
||||
% if svd_path:
|
||||
% predebug["svdPath"] = _escape_path(svd_path)
|
||||
% end
|
||||
% debug = predebug.copy()
|
||||
% debug["name"] = "PIO Debug"
|
||||
% debug["preLaunchTask"] = {
|
||||
% "type": "PlatformIO",
|
||||
% "task": ("Pre-Debug (%s)" % env_name) if len(config.envs()) > 1 else "Pre-Debug",
|
||||
% }
|
||||
% return [debug, predebug]
|
||||
% end
|
||||
"preLaunchTask": {
|
||||
"type": "PlatformIO",
|
||||
% if len(config.envs()) > 1:
|
||||
"task": "Pre-Debug ({{ env_name }})"
|
||||
% else:
|
||||
"task": "Pre-Debug"
|
||||
%
|
||||
% def _remove_comments(lines):
|
||||
% data = ""
|
||||
% for line in lines:
|
||||
% line = line.strip()
|
||||
% if not line.startswith("//"):
|
||||
% data += line
|
||||
% end
|
||||
% end
|
||||
% return data
|
||||
% end
|
||||
},
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
},
|
||||
{
|
||||
"type": "platformio-debug",
|
||||
"request": "launch",
|
||||
"name": "PIO Debug (skip Pre-Debug)",
|
||||
"executable": "{{ _escape_path(prog_path) }}",
|
||||
"projectEnvName": "{{ env_name }}",
|
||||
"toolchainBinDir": "{{ _escape_path(dirname(gdb_path)) }}",
|
||||
% if svd_path:
|
||||
"svdPath": "{{ _escape_path(svd_path) }}",
|
||||
%
|
||||
% def _contains_external_configurations(launch_config):
|
||||
% return any(
|
||||
% c.get("type", "") != "platformio-debug"
|
||||
% for c in launch_config.get("configurations", [])
|
||||
% )
|
||||
% end
|
||||
"internalConsoleOptions": "openOnSessionStart"
|
||||
}
|
||||
]
|
||||
}
|
||||
%
|
||||
% def _remove_pio_configurations(launch_config):
|
||||
% if "configurations" not in launch_config:
|
||||
% return launch_config
|
||||
% end
|
||||
%
|
||||
% external_configurations = [
|
||||
% config
|
||||
% for config in launch_config["configurations"]
|
||||
% if config.get("type", "") != "platformio-debug"
|
||||
% ]
|
||||
%
|
||||
% launch_config["configurations"] = external_configurations
|
||||
% return launch_config
|
||||
% end
|
||||
%
|
||||
% def get_launch_configuration():
|
||||
% launch_config = {"version": "0.2.0", "configurations": []}
|
||||
% launch_file = os.path.join(project_dir, ".vscode", "launch.json")
|
||||
% if os.path.isfile(launch_file):
|
||||
% with codecs.open(launch_file, "r", encoding="utf8") as fp:
|
||||
% launch_data = _remove_comments(fp.readlines())
|
||||
% try:
|
||||
% prev_config = json.loads(launch_data)
|
||||
% if _contains_external_configurations(prev_config):
|
||||
% launch_config = _remove_pio_configurations(prev_config)
|
||||
% end
|
||||
% except:
|
||||
% pass
|
||||
% end
|
||||
% end
|
||||
% end
|
||||
% launch_config["configurations"].extend(get_pio_configurations())
|
||||
% return launch_config
|
||||
% end
|
||||
%
|
||||
// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY
|
||||
//
|
||||
// PIO Unified Debugger
|
||||
//
|
||||
// Documentation: https://docs.platformio.org/page/plus/debugging.html
|
||||
// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html
|
||||
|
||||
{{ json.dumps(get_launch_configuration(), indent=4, ensure_ascii=False) }}
|
||||
|
@ -349,8 +349,8 @@ def check_prune_system():
|
||||
if threshold_mb <= 0:
|
||||
return
|
||||
|
||||
unnecessary_mb = calculate_unnecessary_system_data() / 1024
|
||||
if unnecessary_mb < threshold_mb:
|
||||
unnecessary_size = calculate_unnecessary_system_data()
|
||||
if (unnecessary_size / 1024) < threshold_mb:
|
||||
return
|
||||
|
||||
terminal_width, _ = click.get_terminal_size()
|
||||
@ -360,6 +360,6 @@ def check_prune_system():
|
||||
"We found %s of unnecessary PlatformIO system data (temporary files, "
|
||||
"unnecessary packages, etc.).\nUse `pio system prune --dry-run` to list "
|
||||
"them or `pio system prune` to save disk space."
|
||||
% fs.humanize_file_size(unnecessary_mb),
|
||||
% fs.humanize_file_size(unnecessary_size),
|
||||
fg="yellow",
|
||||
)
|
||||
|
@ -207,9 +207,9 @@ class PackageManageRegistryMixin(object):
|
||||
time.sleep(1)
|
||||
return (None, None)
|
||||
|
||||
def pick_best_registry_version(self, versions, spec=None):
|
||||
def filter_incompatible_registry_versions(self, versions, spec=None):
|
||||
assert not spec or isinstance(spec, PackageSpec)
|
||||
best = None
|
||||
result = []
|
||||
for version in versions:
|
||||
semver = cast_version_to_semver(version["name"])
|
||||
if spec and spec.requirements and semver not in spec.requirements:
|
||||
@ -218,6 +218,13 @@ class PackageManageRegistryMixin(object):
|
||||
self.is_system_compatible(f.get("system")) for f in version["files"]
|
||||
):
|
||||
continue
|
||||
result.append(version)
|
||||
return result
|
||||
|
||||
def pick_best_registry_version(self, versions, spec=None):
|
||||
best = None
|
||||
for version in self.filter_incompatible_registry_versions(versions, spec):
|
||||
semver = cast_version_to_semver(version["name"])
|
||||
if not best or (semver > cast_version_to_semver(best["name"])):
|
||||
best = version
|
||||
return best
|
||||
|
@ -137,6 +137,9 @@ def build_contrib_pysite_package(target_dir, with_metadata=True):
|
||||
fs.rmtree(target_dir)
|
||||
os.makedirs(target_dir)
|
||||
|
||||
# issue 3865: There is no "rustup" in "Raspbian GNU/Linux 10 (buster)"
|
||||
os.environ["CRYPTOGRAPHY_DONT_BUILD_RUST"] = "1"
|
||||
|
||||
# build dependencies
|
||||
args = [
|
||||
get_pythonexe_path(),
|
||||
|
@ -568,6 +568,7 @@ class LibraryPropertiesManifestParser(BaseManifestParser):
|
||||
continue
|
||||
found = True
|
||||
item["maintainer"] = True
|
||||
# pylint: disable=unsupported-membership-test
|
||||
if not item.get("email") and email and "@" in email:
|
||||
item["email"] = email
|
||||
if not found:
|
||||
|
@ -253,5 +253,9 @@ class ManifestSchema(BaseSchema):
|
||||
@staticmethod
|
||||
@memoized(expire="1h")
|
||||
def load_spdx_licenses():
|
||||
spdx_data_url = "https://dl.bintray.com/platformio/dl-misc/spdx-licenses-3.json"
|
||||
version = "3.12"
|
||||
spdx_data_url = (
|
||||
"https://raw.githubusercontent.com/spdx/license-list-data/"
|
||||
"v%s/json/licenses.json" % version
|
||||
)
|
||||
return json.loads(fetch_remote_content(spdx_data_url))
|
||||
|
@ -134,7 +134,9 @@ class PlatformRunMixin(object):
|
||||
args,
|
||||
stdout=proc.BuildAsyncPipe(
|
||||
line_callback=self._on_stdout_line,
|
||||
data_callback=lambda data: _write_and_flush(sys.stdout, data),
|
||||
data_callback=lambda data: None
|
||||
if self.silent
|
||||
else _write_and_flush(sys.stdout, data),
|
||||
),
|
||||
stderr=proc.BuildAsyncPipe(
|
||||
line_callback=self._on_stderr_line,
|
||||
|
@ -252,6 +252,7 @@ class PlatformBase( # pylint: disable=too-many-instance-attributes,too-many-pub
|
||||
click.secho(
|
||||
"Could not install Python packages -> %s" % e, fg="red", err=True
|
||||
)
|
||||
return None
|
||||
|
||||
def uninstall_python_packages(self):
|
||||
if not self.python_packages:
|
||||
|
2
setup.py
2
setup.py
@ -43,7 +43,7 @@ if not PY2:
|
||||
|
||||
home_requirements = [
|
||||
"aiofiles==0.6.*",
|
||||
"json-rpc==1.13.*",
|
||||
"ajsonrpc==1.1.*",
|
||||
"starlette==0.14.*",
|
||||
"uvicorn==0.13.*",
|
||||
"wsproto==1.0.*",
|
||||
|
@ -23,7 +23,7 @@ def test_board_json_output(clirunner, validate_cliresult):
|
||||
validate_cliresult(result)
|
||||
boards = json.loads(result.output)
|
||||
assert isinstance(boards, list)
|
||||
assert any(["mbed" in b["frameworks"] for b in boards])
|
||||
assert any("mbed" in b["frameworks"] for b in boards)
|
||||
|
||||
|
||||
def test_board_raw_output(clirunner, validate_cliresult):
|
||||
|
@ -521,3 +521,16 @@ int main() {}
|
||||
verbose_errors, _, _ = count_defects(result.output)
|
||||
|
||||
assert verbose_errors == errors == 1
|
||||
|
||||
|
||||
def test_check_handles_spaces_in_paths(clirunner, validate_cliresult, tmpdir_factory):
|
||||
tmpdir = tmpdir_factory.mktemp("project dir")
|
||||
config = DEFAULT_CONFIG + "\ncheck_tool = cppcheck, clangtidy, pvs-studio"
|
||||
tmpdir.join("platformio.ini").write(config)
|
||||
tmpdir.mkdir("src").join("main.cpp").write(
|
||||
PVS_STUDIO_FREE_LICENSE_HEADER + TEST_CODE
|
||||
)
|
||||
|
||||
default_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
|
||||
validate_cliresult(default_result)
|
||||
|
@ -70,10 +70,8 @@ def test_init_ide_vscode(clirunner, validate_cliresult, tmpdir):
|
||||
validate_cliresult(result)
|
||||
validate_pioproject(str(tmpdir))
|
||||
assert all(
|
||||
[
|
||||
tmpdir.join(".vscode").join(f).check()
|
||||
for f in ("c_cpp_properties.json", "launch.json")
|
||||
]
|
||||
tmpdir.join(".vscode").join(f).check()
|
||||
for f in ("c_cpp_properties.json", "launch.json")
|
||||
)
|
||||
assert (
|
||||
"framework-arduino-avr"
|
||||
@ -113,7 +111,7 @@ def test_init_ide_eclipse(clirunner, validate_cliresult):
|
||||
result = clirunner.invoke(cmd_init, ["-b", "uno", "--ide", "eclipse"])
|
||||
validate_cliresult(result)
|
||||
validate_pioproject(getcwd())
|
||||
assert all([isfile(f) for f in (".cproject", ".project")])
|
||||
assert all(isfile(f) for f in (".cproject", ".project"))
|
||||
|
||||
|
||||
def test_init_special_board(clirunner, validate_cliresult):
|
||||
|
@ -172,27 +172,23 @@ def test_global_lib_list(clirunner, validate_cliresult):
|
||||
result = clirunner.invoke(cmd_lib, ["-g", "list"])
|
||||
validate_cliresult(result)
|
||||
assert all(
|
||||
[
|
||||
n in result.output
|
||||
for n in (
|
||||
"Source: https://github.com/Pedroalbuquerque/ESP32WebServer/archive/master.zip",
|
||||
"Version: 5.10.1",
|
||||
"Source: git+https://github.com/gioblu/PJON.git#3.0",
|
||||
"Version: 3.0.0+sha.1fb26fd",
|
||||
)
|
||||
]
|
||||
n in result.output
|
||||
for n in (
|
||||
"Source: https://github.com/Pedroalbuquerque/ESP32WebServer/archive/master.zip",
|
||||
"Version: 5.10.1",
|
||||
"Source: git+https://github.com/gioblu/PJON.git#3.0",
|
||||
"Version: 3.0.0+sha.1fb26fd",
|
||||
)
|
||||
)
|
||||
|
||||
result = clirunner.invoke(cmd_lib, ["-g", "list", "--json-output"])
|
||||
assert all(
|
||||
[
|
||||
n in result.output
|
||||
for n in (
|
||||
"__pkg_dir",
|
||||
'"__src_url": "git+https://github.com/gioblu/PJON.git#6.2"',
|
||||
'"version": "5.10.1"',
|
||||
)
|
||||
]
|
||||
n in result.output
|
||||
for n in (
|
||||
"__pkg_dir",
|
||||
'"__src_url": "git+https://github.com/gioblu/PJON.git#6.2"',
|
||||
'"version": "5.10.1"',
|
||||
)
|
||||
)
|
||||
items1 = [i["name"] for i in json.loads(result.output)]
|
||||
items2 = [
|
||||
@ -316,7 +312,7 @@ def test_global_lib_uninstall(clirunner, validate_cliresult, isolated_pio_core):
|
||||
def test_lib_show(clirunner, validate_cliresult):
|
||||
result = clirunner.invoke(cmd_lib, ["show", "64"])
|
||||
validate_cliresult(result)
|
||||
assert all([s in result.output for s in ("ArduinoJson", "Arduino", "Atmel AVR")])
|
||||
assert all(s in result.output for s in ("ArduinoJson", "Arduino", "Atmel AVR"))
|
||||
result = clirunner.invoke(cmd_lib, ["show", "OneWire", "--json-output"])
|
||||
validate_cliresult(result)
|
||||
assert "OneWire" in result.output
|
||||
@ -333,10 +329,8 @@ def test_lib_stats(clirunner, validate_cliresult):
|
||||
result = clirunner.invoke(cmd_lib, ["stats"])
|
||||
validate_cliresult(result)
|
||||
assert all(
|
||||
[
|
||||
s in result.output
|
||||
for s in ("UPDATED", "POPULAR", "https://platformio.org/lib/show")
|
||||
]
|
||||
s in result.output
|
||||
for s in ("UPDATED", "POPULAR", "https://platformio.org/lib/show")
|
||||
)
|
||||
|
||||
result = clirunner.invoke(cmd_lib, ["stats", "--json-output"])
|
||||
|
@ -103,7 +103,7 @@ def test_list_json_output(clirunner, validate_cliresult):
|
||||
def test_list_raw_output(clirunner, validate_cliresult):
|
||||
result = clirunner.invoke(cli_platform.platform_list)
|
||||
validate_cliresult(result)
|
||||
assert all([s in result.output for s in ("atmelavr", "espressif8266")])
|
||||
assert all(s in result.output for s in ("atmelavr", "espressif8266"))
|
||||
|
||||
|
||||
def test_update_check(clirunner, validate_cliresult, isolated_pio_core):
|
||||
|
@ -34,7 +34,7 @@ def test_local_env():
|
||||
if result["returncode"] != 1:
|
||||
pytest.fail(str(result))
|
||||
# pylint: disable=unsupported-membership-test
|
||||
assert all([s in result["err"] for s in ("PASSED", "FAILED")]), result["out"]
|
||||
assert all(s in result["err"] for s in ("PASSED", "FAILED")), result["out"]
|
||||
|
||||
|
||||
def test_multiple_env_build(clirunner, validate_cliresult, tmpdir):
|
||||
|
@ -21,7 +21,7 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core):
|
||||
matches = ("Platform Manager", "Library Manager")
|
||||
result = clirunner.invoke(cmd_update, ["--only-check"])
|
||||
validate_cliresult(result)
|
||||
assert all([m in result.output for m in matches])
|
||||
assert all(m in result.output for m in matches)
|
||||
result = clirunner.invoke(cmd_update)
|
||||
validate_cliresult(result)
|
||||
assert all([m in result.output for m in matches])
|
||||
assert all(m in result.output for m in matches)
|
||||
|
Reference in New Issue
Block a user