Merge branch 'release/v5.1.1'

This commit is contained in:
Ivan Kravets
2021-03-17 18:17:46 +02:00
36 changed files with 249 additions and 178 deletions

View File

@ -1,3 +0,0 @@
[settings]
line_length=88
known_third_party=OpenSSL, SCons, jsonrpc, twisted, zope

View File

@ -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

Submodule docs updated: 25edd66d55...3293903cac

View File

@ -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",

View File

@ -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"\\([^\"'\\]|$)")

View File

@ -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):

View File

@ -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()

View File

@ -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)

View 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"]

View File

@ -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 ""

View File

@ -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)
)

View File

@ -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)

View File

@ -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)
)

View File

@ -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(

View File

@ -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))

View File

@ -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 = [

View File

@ -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"

View File

@ -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

View File

@ -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) }}

View File

@ -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",
)

View File

@ -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

View File

@ -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(),

View File

@ -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:

View File

@ -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))

View File

@ -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,

View File

@ -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:

View File

@ -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.*",

View File

@ -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):

View File

@ -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)

View File

@ -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):

View File

@ -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"])

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -15,6 +15,10 @@
[tox]
envlist = py36,py37,py38,py39
[isort]
line_length = 88
known_third_party=OpenSSL, SCons, jsonrpc, twisted, zope
[testenv]
passenv = *
usedevelop = True