forked from platformio/platformio-core
Merge branch 'release/v6.1.14'
This commit is contained in:
14
HISTORY.rst
14
HISTORY.rst
@ -7,6 +7,7 @@ Release Notes
|
||||
.. |INTERPOLATION| replace:: `Interpolation of Values <https://docs.platformio.org/en/latest/projectconf/interpolation.html>`__
|
||||
.. |UNITTESTING| replace:: `Unit Testing <https://docs.platformio.org/en/latest/advanced/unit-testing/index.html>`__
|
||||
.. |DEBUGGING| replace:: `Debugging <https://docs.platformio.org/en/latest/plus/debugging.html>`__
|
||||
.. |STATICCODEANALYSIS| replace:: `Static Code Analysis <https://docs.platformio.org/en/latest/advanced/static-code-analysis/index.html>`__
|
||||
|
||||
.. _release_notes_6:
|
||||
|
||||
@ -17,6 +18,19 @@ Unlock the true potential of embedded software development with
|
||||
PlatformIO's collaborative ecosystem, embracing declarative principles,
|
||||
test-driven methodologies, and modern toolchains for unrivaled success.
|
||||
|
||||
6.1.14 (2024-03-21)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* Introduced the ``--json-output`` option to the `pio test <https://docs.platformio.org/en/latest/core/userguide/cmd_test.html>`__ command, enabling users to generate test results in the JSON format
|
||||
* Upgraded the build engine to the latest version of SCons (4.7.0) to improve build performance, reliability, and compatibility with other tools and systems (`release notes <https://github.com/SCons/scons/releases/tag/4.7.0>`__)
|
||||
* Broadened version support for the ``pyelftools`` dependency, enabling compatibility with lower versions and facilitating integration with a wider range of third-party tools (`issue #4834 <https://github.com/platformio/platformio-core/issues/4834>`_)
|
||||
* Addressed an issue where passing a relative path (``--project-dir``) to the `pio project init <https://docs.platformio.org/en/latest/core/userguide/project/cmd_init.html>`__ command resulted in an error (`issue #4847 <https://github.com/platformio/platformio-core/issues/4847>`_)
|
||||
* Enhanced |STATICCODEANALYSIS| to accommodate scenarios where custom ``src_dir`` or ``include_dir`` are located outside the project folder (`pull #4874 <https://github.com/platformio/platformio-core/pull/4874>`_)
|
||||
* Corrected the validation of ``symlink://`` `package specifications <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_install.html#local-folder>`__ , resolving an issue that caused the package manager to repeatedly reinstall dependencies (`pull #4870 <https://github.com/platformio/platformio-core/pull/4870>`_)
|
||||
* Resolved an issue related to the relative package path in the `pio pkg publish <https://docs.platformio.org/en/latest/core/userguide/pkg/cmd_publish.html>`__ command
|
||||
* Resolved an issue where the |LDF| selected an incorrect library version (`issue #4860 <https://github.com/platformio/platformio-core/issues/4860>`_)
|
||||
* Resolved an issue with the ``hexlify`` filter in the `device monitor <https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html>`__ command, ensuring proper representation of characters with Unicode code points higher than 127 (`issue #4732 <https://github.com/platformio/platformio-core/issues/4732>`_)
|
||||
|
||||
6.1.13 (2024-01-12)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
2
docs
2
docs
Submodule docs updated: 3f02152561...670721e923
@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
VERSION = (6, 1, 13)
|
||||
VERSION = (6, 1, 14)
|
||||
__version__ = ".".join([str(s) for s in VERSION])
|
||||
|
||||
__title__ = "platformio"
|
||||
@ -38,15 +38,6 @@ __registry_mirror_hosts__ = [
|
||||
]
|
||||
__pioremote_endpoint__ = "ssl:host=remote.platformio.org:port=4413"
|
||||
|
||||
__core_packages__ = {
|
||||
"contrib-piohome": "~3.4.2",
|
||||
"contrib-pioremote": "~1.0.0",
|
||||
"tool-scons": "~4.40600.0",
|
||||
"tool-cppcheck": "~1.21100.0",
|
||||
"tool-clangtidy": "~1.150005.0",
|
||||
"tool-pvs-studio": "~7.18.0",
|
||||
}
|
||||
|
||||
__check_internet_hosts__ = [
|
||||
"185.199.110.153", # Github.com
|
||||
"88.198.170.159", # platformio.org
|
||||
|
@ -48,11 +48,13 @@ def team_list_cmd(orgname, json_output):
|
||||
table_data.append(
|
||||
(
|
||||
"Members:",
|
||||
", ".join(
|
||||
(member.get("username") for member in team.get("members"))
|
||||
)
|
||||
if team.get("members")
|
||||
else "-",
|
||||
(
|
||||
", ".join(
|
||||
(member.get("username") for member in team.get("members"))
|
||||
)
|
||||
if team.get("members")
|
||||
else "-"
|
||||
),
|
||||
)
|
||||
)
|
||||
click.echo(tabulate(table_data, tablefmt="plain"))
|
||||
|
@ -36,6 +36,8 @@ ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", MODE:="0666", ENV{ID_MM_DEVIC
|
||||
|
||||
# QinHeng Electronics HL-340 USB-Serial adapter
|
||||
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
# QinHeng Electronics CH343 USB-Serial adapter
|
||||
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d3", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
# QinHeng Electronics CH9102 USB-Serial adapter
|
||||
ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", MODE:="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
|
||||
@ -85,6 +87,8 @@ ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="[01]*", MODE:="0666", ENV{ID_MM_DEVI
|
||||
# AIR32F103
|
||||
ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
|
||||
# STM32 virtual COM port
|
||||
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
|
||||
#
|
||||
# Debuggers
|
||||
@ -173,4 +177,4 @@ ATTRS{product}=="*CMSIS-DAP*", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID
|
||||
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2107", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
|
||||
# Espressif USB JTAG/serial debug unit
|
||||
ATTRS{idVendor}=="303a", ATTR{idProduct}=="1001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
ATTRS{idVendor}=="303a", ATTR{idProduct}=="1001", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1"
|
||||
|
@ -54,7 +54,7 @@ def GetBuildType(env):
|
||||
modes.append("debug")
|
||||
if "__test" in COMMAND_LINE_TARGETS or env.GetProjectOption("build_type") == "test":
|
||||
modes.append("test")
|
||||
return "+".join(modes or ["release"])
|
||||
return ", ".join(modes or ["release"])
|
||||
|
||||
|
||||
def BuildProgram(env):
|
||||
|
@ -309,10 +309,10 @@ class LibBuilderBase:
|
||||
if not self.dependencies or self._deps_are_processed:
|
||||
return
|
||||
self._deps_are_processed = True
|
||||
for item in self.dependencies:
|
||||
for dependency in self.dependencies:
|
||||
found = False
|
||||
for lb in self.env.GetLibBuilders():
|
||||
if item["name"] != lb.name:
|
||||
if not lb.is_dependency_compatible(dependency):
|
||||
continue
|
||||
found = True
|
||||
if lb not in self.depbuilders:
|
||||
@ -322,9 +322,20 @@ class LibBuilderBase:
|
||||
if not found and self.verbose:
|
||||
sys.stderr.write(
|
||||
"Warning: Ignored `%s` dependency for `%s` "
|
||||
"library\n" % (item["name"], self.name)
|
||||
"library\n" % (dependency["name"], self.name)
|
||||
)
|
||||
|
||||
def is_dependency_compatible(self, dependency):
|
||||
pkg = PackageItem(self.path)
|
||||
qualifiers = {"name": self.name, "version": self.version}
|
||||
if pkg.metadata:
|
||||
qualifiers = {"name": pkg.metadata.name, "version": pkg.metadata.version}
|
||||
if pkg.metadata.spec and pkg.metadata.spec.owner:
|
||||
qualifiers["owner"] = pkg.metadata.spec.owner
|
||||
return PackageCompatibility.from_dependency(
|
||||
{k: v for k, v in dependency.items() if k in ("owner", "name", "version")}
|
||||
).is_compatible(PackageCompatibility(**qualifiers))
|
||||
|
||||
def get_search_files(self):
|
||||
return [
|
||||
os.path.join(self.src_dir, item)
|
||||
|
@ -23,10 +23,10 @@ from SCons.Subst import quote_spaces # pylint: disable=import-error
|
||||
from platformio.compat import IS_WINDOWS, hashlib_encode_data
|
||||
|
||||
# There are the next limits depending on a platform:
|
||||
# - Windows = 8192
|
||||
# - Windows = 8191
|
||||
# - Unix = 131072
|
||||
# We need ~512 characters for compiler and temporary file paths
|
||||
MAX_LINE_LENGTH = (8192 if IS_WINDOWS else 131072) - 512
|
||||
MAX_LINE_LENGTH = (8191 if IS_WINDOWS else 131072) - 512
|
||||
|
||||
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
|
||||
|
||||
|
@ -75,9 +75,11 @@ def LoadPioPlatform(env):
|
||||
continue
|
||||
env.PrependENVPath(
|
||||
"PATH",
|
||||
os.path.join(pkg.path, "bin")
|
||||
if os.path.isdir(os.path.join(pkg.path, "bin"))
|
||||
else pkg.path,
|
||||
(
|
||||
os.path.join(pkg.path, "bin")
|
||||
if os.path.isdir(os.path.join(pkg.path, "bin"))
|
||||
else pkg.path
|
||||
),
|
||||
)
|
||||
if (
|
||||
not IS_WINDOWS
|
||||
|
@ -103,10 +103,21 @@ def cli(
|
||||
"%s: %s" % (k, ", ".join(v) if isinstance(v, list) else v)
|
||||
)
|
||||
|
||||
default_src_filters = [
|
||||
"+<%s>" % os.path.basename(config.get("platformio", "src_dir")),
|
||||
"+<%s>" % os.path.basename(config.get("platformio", "include_dir")),
|
||||
]
|
||||
default_src_filters = []
|
||||
for d in (
|
||||
config.get("platformio", "src_dir"),
|
||||
config.get("platformio", "include_dir"),
|
||||
):
|
||||
try:
|
||||
default_src_filters.append("+<%s>" % os.path.relpath(d))
|
||||
except ValueError as exc:
|
||||
# On Windows if sources are located on a different logical drive
|
||||
if not json_output and not silent:
|
||||
click.echo(
|
||||
"Error: Project cannot be analyzed! The project folder `%s`"
|
||||
" is located on a different logical drive\n" % d
|
||||
)
|
||||
raise exception.ReturnErrorCode(1) from exc
|
||||
|
||||
env_src_filters = (
|
||||
src_filters
|
||||
@ -122,9 +133,11 @@ def cli(
|
||||
silent=silent,
|
||||
src_filters=env_src_filters,
|
||||
flags=flags or env_options.get("check_flags"),
|
||||
severity=[DefectItem.SEVERITY_LABELS[DefectItem.SEVERITY_HIGH]]
|
||||
if silent
|
||||
else severity or config.get("env:" + envname, "check_severity"),
|
||||
severity=(
|
||||
[DefectItem.SEVERITY_LABELS[DefectItem.SEVERITY_HIGH]]
|
||||
if silent
|
||||
else severity or config.get("env:" + envname, "check_severity")
|
||||
),
|
||||
skip_packages=skip_packages or env_options.get("check_skip_packages"),
|
||||
platform_packages=env_options.get("platform_packages"),
|
||||
)
|
||||
@ -142,9 +155,11 @@ def cli(
|
||||
|
||||
result = {"env": envname, "tool": tool, "duration": time()}
|
||||
rc = ct.check(
|
||||
on_defect_callback=None
|
||||
if (json_output or verbose)
|
||||
else lambda defect: click.echo(repr(defect))
|
||||
on_defect_callback=(
|
||||
None
|
||||
if (json_output or verbose)
|
||||
else lambda defect: click.echo(repr(defect))
|
||||
)
|
||||
)
|
||||
|
||||
result["defects"] = ct.get_defects()
|
||||
|
@ -19,9 +19,9 @@ import subprocess
|
||||
import click
|
||||
|
||||
from platformio import VERSION, __version__, app, exception
|
||||
from platformio.dependencies import get_pip_dependencies
|
||||
from platformio.http import fetch_remote_content
|
||||
from platformio.package.manager.core import update_core_packages
|
||||
from platformio.pipdeps import get_pip_dependencies
|
||||
from platformio.proc import get_pythonexe_path
|
||||
|
||||
PYPI_JSON_URL = "https://pypi.org/pypi/platformio/json"
|
||||
|
@ -17,6 +17,7 @@
|
||||
import importlib.util
|
||||
import inspect
|
||||
import locale
|
||||
import os
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
@ -41,10 +42,14 @@ else:
|
||||
if sys.version_info >= (3, 9):
|
||||
from asyncio import to_thread as aio_to_thread
|
||||
else:
|
||||
from starlette.concurrency import run_in_threadpool as aio_to_thread
|
||||
try:
|
||||
from starlette.concurrency import run_in_threadpool as aio_to_thread
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
PY2 = sys.version_info[0] == 2 # DO NOT REMOVE IT. ESP8266/ESP32 depend on it
|
||||
PY36 = sys.version_info[0:2] == (3, 6)
|
||||
IS_CYGWIN = sys.platform.startswith("cygwin")
|
||||
IS_WINDOWS = WINDOWS = sys.platform.startswith("win")
|
||||
IS_MACOS = sys.platform.startswith("darwin")
|
||||
@ -132,3 +137,12 @@ def path_to_unicode(path):
|
||||
and custom device monitor filters
|
||||
"""
|
||||
return path
|
||||
|
||||
|
||||
def is_proxy_set(socks=False):
|
||||
for var in ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"):
|
||||
value = os.getenv(var, os.getenv(var.lower()))
|
||||
if not value or (socks and not value.startswith("socks5://")):
|
||||
continue
|
||||
return True
|
||||
return False
|
||||
|
@ -148,7 +148,9 @@ class DebugConfigBase: # pylint: disable=too-many-instance-attributes
|
||||
)
|
||||
|
||||
def _load_build_data(self):
|
||||
data = load_build_metadata(os.getcwd(), self.env_name, cache=True, debug=True)
|
||||
data = load_build_metadata(
|
||||
os.getcwd(), self.env_name, cache=True, build_type="debug"
|
||||
)
|
||||
if not data:
|
||||
raise DebugInvalidOptionsError("Could not load a build configuration")
|
||||
return data
|
||||
@ -194,9 +196,11 @@ class DebugConfigBase: # pylint: disable=too-many-instance-attributes
|
||||
cwd=server_package_dir if server_package else None,
|
||||
executable=result.get("executable"),
|
||||
arguments=[
|
||||
a.replace("$PACKAGE_DIR", server_package_dir)
|
||||
if server_package_dir
|
||||
else a
|
||||
(
|
||||
a.replace("$PACKAGE_DIR", server_package_dir)
|
||||
if server_package_dir
|
||||
else a
|
||||
)
|
||||
for a in result.get("arguments", [])
|
||||
],
|
||||
)
|
||||
|
@ -12,11 +12,20 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
||||
PY36 = sys.version_info[0:2] == (3, 6)
|
||||
from platformio.compat import PY36, is_proxy_set
|
||||
|
||||
|
||||
def get_core_dependencies():
|
||||
return {
|
||||
"contrib-piohome": "~3.4.2",
|
||||
"contrib-pioremote": "~1.0.0",
|
||||
"tool-scons": "~4.40700.0",
|
||||
"tool-cppcheck": "~1.21100.0",
|
||||
"tool-clangtidy": "~1.150005.0",
|
||||
"tool-pvs-studio": "~7.18.0",
|
||||
}
|
||||
|
||||
|
||||
def get_pip_dependencies():
|
||||
@ -25,7 +34,7 @@ def get_pip_dependencies():
|
||||
"click >=8.0.4, <9",
|
||||
"colorama",
|
||||
"marshmallow == 3.*",
|
||||
"pyelftools == 0.30",
|
||||
"pyelftools >=0.27, <1",
|
||||
"pyserial == 3.5.*", # keep in sync "device/monitor/terminal.py"
|
||||
"requests%s == 2.*" % ("[socks]" if is_proxy_set(socks=True) else ""),
|
||||
"semantic_version == 2.10.*",
|
||||
@ -35,8 +44,8 @@ def get_pip_dependencies():
|
||||
home = [
|
||||
# PIO Home requirements
|
||||
"ajsonrpc == 1.2.*",
|
||||
"starlette >=0.19, <0.36",
|
||||
"uvicorn %s" % ("== 0.16.0" if PY36 else ">=0.16, <0.26"),
|
||||
"starlette >=0.19, <0.38",
|
||||
"uvicorn %s" % ("== 0.16.0" if PY36 else ">=0.16, <0.30"),
|
||||
"wsproto == 1.*",
|
||||
]
|
||||
|
||||
@ -60,12 +69,3 @@ def get_pip_dependencies():
|
||||
pass
|
||||
|
||||
return core + home + extra
|
||||
|
||||
|
||||
def is_proxy_set(socks=False):
|
||||
for var in ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY"):
|
||||
value = os.getenv(var, os.getenv(var.lower()))
|
||||
if not value or (socks and not value.startswith("socks5://")):
|
||||
continue
|
||||
return True
|
||||
return False
|
@ -144,9 +144,9 @@ def list_mdns_services():
|
||||
if service.properties:
|
||||
try:
|
||||
properties = {
|
||||
k.decode("utf8"): v.decode("utf8")
|
||||
if isinstance(v, bytes)
|
||||
else v
|
||||
k.decode("utf8"): (
|
||||
v.decode("utf8") if isinstance(v, bytes) else v
|
||||
)
|
||||
for k, v in service.properties.items()
|
||||
}
|
||||
json.dumps(properties)
|
||||
|
@ -58,7 +58,7 @@ from platformio.project.options import ProjectOptions
|
||||
"--encoding",
|
||||
help=(
|
||||
"Set the encoding for the serial port "
|
||||
"(e.g. hexlify, Latin1, UTF-8) [default=%s]"
|
||||
"(e.g. hexlify, Latin-1, UTF-8) [default=%s]"
|
||||
% ProjectOptions["env.monitor_encoding"].default
|
||||
),
|
||||
)
|
||||
@ -125,9 +125,11 @@ def device_monitor_cmd(**options):
|
||||
options = apply_project_monitor_options(options, project_options)
|
||||
register_filters(platform=platform, options=options)
|
||||
options["port"] = SerialPortFinder(
|
||||
board_config=platform.board_config(project_options.get("board"))
|
||||
if platform and project_options.get("board")
|
||||
else None,
|
||||
board_config=(
|
||||
platform.board_config(project_options.get("board"))
|
||||
if platform and project_options.get("board")
|
||||
else None
|
||||
),
|
||||
upload_protocol=project_options.get("upload_protocol"),
|
||||
ensure_ready=True,
|
||||
).find(initial_port=options["port"])
|
||||
|
@ -25,11 +25,12 @@ from platformio.project.config import ProjectConfig
|
||||
class DeviceMonitorFilterBase(miniterm.Transform):
|
||||
def __init__(self, options=None):
|
||||
"""Called by PlatformIO to pass context"""
|
||||
miniterm.Transform.__init__(self)
|
||||
super().__init__()
|
||||
|
||||
self.options = options or {}
|
||||
self.project_dir = self.options.get("project_dir")
|
||||
self.environment = self.options.get("environment")
|
||||
self._running_terminal = None
|
||||
|
||||
self.config = ProjectConfig.get_instance()
|
||||
if not self.environment:
|
||||
@ -47,6 +48,12 @@ class DeviceMonitorFilterBase(miniterm.Transform):
|
||||
def NAME(self):
|
||||
raise NotImplementedError("Please declare NAME attribute for the filter class")
|
||||
|
||||
def set_running_terminal(self, terminal):
|
||||
self._running_terminal = terminal
|
||||
|
||||
def get_running_terminal(self):
|
||||
return self._running_terminal
|
||||
|
||||
|
||||
def register_filters(platform=None, options=None):
|
||||
# project filters
|
||||
|
@ -24,12 +24,18 @@ class Hexlify(DeviceMonitorFilterBase):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._counter = 0
|
||||
|
||||
def set_running_terminal(self, terminal):
|
||||
# force to Latin-1, issue #4732
|
||||
if terminal.input_encoding == "UTF-8":
|
||||
terminal.set_rx_encoding("Latin-1")
|
||||
super().set_running_terminal(terminal)
|
||||
|
||||
def rx(self, text):
|
||||
result = ""
|
||||
for b in serial.iterbytes(text):
|
||||
for c in serial.iterbytes(text):
|
||||
if (self._counter % 16) == 0:
|
||||
result += "\n{:04X} | ".format(self._counter)
|
||||
asciicode = ord(b)
|
||||
asciicode = ord(c)
|
||||
if asciicode <= 255:
|
||||
result += "{:02X} ".format(asciicode)
|
||||
else:
|
||||
|
@ -110,6 +110,12 @@ def new_terminal(options):
|
||||
term.raw = options["raw"]
|
||||
term.set_rx_encoding(options["encoding"])
|
||||
term.set_tx_encoding(options["encoding"])
|
||||
for ts in (term.tx_transformations, term.rx_transformations):
|
||||
for t in ts:
|
||||
try:
|
||||
t.set_running_terminal(term)
|
||||
except AttributeError:
|
||||
pass
|
||||
return term
|
||||
|
||||
|
||||
|
@ -372,15 +372,19 @@ class ProjectRPC(BaseRPCHandler):
|
||||
|
||||
return dict(
|
||||
platform=dict(
|
||||
ownername=platform_pkg.metadata.spec.owner
|
||||
if platform_pkg.metadata.spec
|
||||
else None,
|
||||
ownername=(
|
||||
platform_pkg.metadata.spec.owner
|
||||
if platform_pkg.metadata.spec
|
||||
else None
|
||||
),
|
||||
name=platform.name,
|
||||
title=platform.title,
|
||||
version=str(platform_pkg.metadata.version),
|
||||
),
|
||||
board=platform.board_config(board_id).get_brief_data()
|
||||
if board_id
|
||||
else None,
|
||||
board=(
|
||||
platform.board_config(board_id).get_brief_data()
|
||||
if board_id
|
||||
else None
|
||||
),
|
||||
frameworks=frameworks or None,
|
||||
)
|
||||
|
@ -21,8 +21,8 @@ from urllib3.util.retry import Retry
|
||||
|
||||
from platformio import __check_internet_hosts__, app, util
|
||||
from platformio.cache import ContentCache, cleanup_content_cache
|
||||
from platformio.compat import is_proxy_set
|
||||
from platformio.exception import PlatformioException, UserSideException
|
||||
from platformio.pipdeps import is_proxy_set
|
||||
|
||||
__default_requests_timeout__ = (10, None) # (connect, read)
|
||||
|
||||
@ -63,9 +63,11 @@ class HTTPSession(requests.Session):
|
||||
kwargs["timeout"] = __default_requests_timeout__
|
||||
return super().request(
|
||||
method,
|
||||
url
|
||||
if url.startswith("http") or not self._x_base_url
|
||||
else urljoin(self._x_base_url, url),
|
||||
(
|
||||
url
|
||||
if url.startswith("http") or not self._x_base_url
|
||||
else urljoin(self._x_base_url, url)
|
||||
),
|
||||
*args,
|
||||
**kwargs
|
||||
)
|
||||
|
@ -222,9 +222,11 @@ def _install_project_env_libraries(project_env, options):
|
||||
|
||||
env_lm = LibraryPackageManager(
|
||||
os.path.join(config.get("platformio", "libdeps_dir"), project_env),
|
||||
compatibility=PackageCompatibility(**compatibility_qualifiers)
|
||||
if compatibility_qualifiers
|
||||
else None,
|
||||
compatibility=(
|
||||
PackageCompatibility(**compatibility_qualifiers)
|
||||
if compatibility_qualifiers
|
||||
else None
|
||||
),
|
||||
)
|
||||
private_lm = LibraryPackageManager(
|
||||
os.path.join(config.get("platformio", "lib_dir"))
|
||||
|
@ -86,6 +86,7 @@ def package_publish_cmd( # pylint: disable=too-many-arguments, too-many-locals
|
||||
package, owner, typex, released_at, private, notify, no_interactive, non_interactive
|
||||
):
|
||||
click.secho("Preparing a package...", fg="cyan")
|
||||
package = os.path.abspath(package)
|
||||
no_interactive = no_interactive or non_interactive
|
||||
owner = owner or AccountClient().get_logged_username()
|
||||
do_not_pack = (
|
||||
|
@ -65,10 +65,12 @@ def print_search_item(item):
|
||||
click.echo(
|
||||
"%s • %s • Published on %s"
|
||||
% (
|
||||
item["type"].capitalize()
|
||||
if item["tier"] == "community"
|
||||
else click.style(
|
||||
("%s %s" % (item["tier"], item["type"])).title(), bold=True
|
||||
(
|
||||
item["type"].capitalize()
|
||||
if item["tier"] == "community"
|
||||
else click.style(
|
||||
("%s %s" % (item["tier"], item["type"])).title(), bold=True
|
||||
)
|
||||
),
|
||||
item["version"]["name"],
|
||||
util.parse_datetime(item["version"]["released_at"]).strftime("%c"),
|
||||
|
@ -98,9 +98,13 @@ class PackageManagerInstallMixin:
|
||||
else:
|
||||
pkg = self.install_from_registry(
|
||||
spec,
|
||||
search_qualifiers=compatibility.to_search_qualifiers()
|
||||
if compatibility
|
||||
else None,
|
||||
search_qualifiers=(
|
||||
compatibility.to_search_qualifiers(
|
||||
["platforms", "frameworks", "authors"]
|
||||
)
|
||||
if compatibility
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
if not pkg or not pkg.metadata:
|
||||
|
@ -280,11 +280,15 @@ class BasePackageManager( # pylint: disable=too-many-public-methods,too-many-in
|
||||
|
||||
# external "URL" mismatch
|
||||
if spec.external:
|
||||
# local folder mismatch
|
||||
if os.path.abspath(spec.uri) == os.path.abspath(pkg.path) or (
|
||||
# local/symlinked folder mismatch
|
||||
check_conds = [
|
||||
os.path.abspath(spec.uri) == os.path.abspath(pkg.path),
|
||||
spec.uri.startswith("file://")
|
||||
and os.path.abspath(pkg.path) == os.path.abspath(spec.uri[7:])
|
||||
):
|
||||
and os.path.abspath(pkg.path) == os.path.abspath(spec.uri[7:]),
|
||||
spec.uri.startswith("symlink://")
|
||||
and os.path.abspath(pkg.path) == os.path.abspath(spec.uri[10:]),
|
||||
]
|
||||
if any(check_conds):
|
||||
return True
|
||||
if spec.uri != pkg.metadata.spec.uri:
|
||||
return False
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
import os
|
||||
|
||||
from platformio import __core_packages__, exception
|
||||
from platformio import exception
|
||||
from platformio.dependencies import get_core_dependencies
|
||||
from platformio.package.exception import UnknownPackageError
|
||||
from platformio.package.manager.tool import ToolPackageManager
|
||||
from platformio.package.meta import PackageSpec
|
||||
@ -23,7 +24,7 @@ from platformio.package.meta import PackageSpec
|
||||
def get_installed_core_packages():
|
||||
result = []
|
||||
pm = ToolPackageManager()
|
||||
for name, requirements in __core_packages__.items():
|
||||
for name, requirements in get_core_dependencies().items():
|
||||
spec = PackageSpec(owner="platformio", name=name, requirements=requirements)
|
||||
pkg = pm.get_package(spec)
|
||||
if pkg:
|
||||
@ -32,11 +33,11 @@ def get_installed_core_packages():
|
||||
|
||||
|
||||
def get_core_package_dir(name, spec=None, auto_install=True):
|
||||
if name not in __core_packages__:
|
||||
if name not in get_core_dependencies():
|
||||
raise exception.PlatformioException("Please upgrade PlatformIO Core")
|
||||
pm = ToolPackageManager()
|
||||
spec = spec or PackageSpec(
|
||||
owner="platformio", name=name, requirements=__core_packages__[name]
|
||||
owner="platformio", name=name, requirements=get_core_dependencies()[name]
|
||||
)
|
||||
pkg = pm.get_package(spec)
|
||||
if pkg:
|
||||
@ -50,7 +51,7 @@ def get_core_package_dir(name, spec=None, auto_install=True):
|
||||
|
||||
def update_core_packages():
|
||||
pm = ToolPackageManager()
|
||||
for name, requirements in __core_packages__.items():
|
||||
for name, requirements in get_core_dependencies().items():
|
||||
spec = PackageSpec(owner="platformio", name=name, requirements=requirements)
|
||||
try:
|
||||
pm.update(spec, spec)
|
||||
@ -65,7 +66,7 @@ def remove_unnecessary_core_packages(dry_run=False):
|
||||
pm = ToolPackageManager()
|
||||
best_pkg_versions = {}
|
||||
|
||||
for name, requirements in __core_packages__.items():
|
||||
for name, requirements in get_core_dependencies().items():
|
||||
spec = PackageSpec(owner="platformio", name=name, requirements=requirements)
|
||||
pkg = pm.get_package(spec)
|
||||
if not pkg:
|
||||
|
@ -294,9 +294,11 @@ class BaseManifestParser:
|
||||
if not matched_files:
|
||||
continue
|
||||
result[root] = dict(
|
||||
name="Examples"
|
||||
if root == examples_dir
|
||||
else os.path.relpath(root, examples_dir),
|
||||
name=(
|
||||
"Examples"
|
||||
if root == examples_dir
|
||||
else os.path.relpath(root, examples_dir)
|
||||
),
|
||||
base=os.path.relpath(root, package_dir),
|
||||
files=matched_files,
|
||||
)
|
||||
|
@ -276,7 +276,7 @@ class ManifestSchema(BaseSchema):
|
||||
@staticmethod
|
||||
@memoized(expire="1h")
|
||||
def load_spdx_licenses():
|
||||
version = "3.22"
|
||||
version = "3.23"
|
||||
spdx_data_url = (
|
||||
"https://raw.githubusercontent.com/spdx/license-list-data/"
|
||||
f"v{version}/json/licenses.json"
|
||||
|
@ -65,7 +65,14 @@ class PackageType:
|
||||
|
||||
|
||||
class PackageCompatibility:
|
||||
KNOWN_QUALIFIERS = ("platforms", "frameworks", "authors")
|
||||
KNOWN_QUALIFIERS = (
|
||||
"owner",
|
||||
"name",
|
||||
"version",
|
||||
"platforms",
|
||||
"frameworks",
|
||||
"authors",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def from_dependency(cls, dependency):
|
||||
@ -89,19 +96,45 @@ class PackageCompatibility:
|
||||
def __repr__(self):
|
||||
return "PackageCompatibility <%s>" % self.qualifiers
|
||||
|
||||
def to_search_qualifiers(self):
|
||||
return self.qualifiers
|
||||
def to_search_qualifiers(self, fields=None):
|
||||
result = {}
|
||||
for name, value in self.qualifiers.items():
|
||||
if not fields or name in fields:
|
||||
result[name] = value
|
||||
return result
|
||||
|
||||
def is_compatible(self, other):
|
||||
assert isinstance(other, PackageCompatibility)
|
||||
for key, value in self.qualifiers.items():
|
||||
for key, current_value in self.qualifiers.items():
|
||||
other_value = other.qualifiers.get(key)
|
||||
if not value or not other_value:
|
||||
if not current_value or not other_value:
|
||||
continue
|
||||
if not items_in_list(value, other_value):
|
||||
if any(isinstance(v, list) for v in (current_value, other_value)):
|
||||
if not items_in_list(current_value, other_value):
|
||||
return False
|
||||
continue
|
||||
if key == "version":
|
||||
if not self._compare_versions(current_value, other_value):
|
||||
return False
|
||||
continue
|
||||
if current_value != other_value:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _compare_versions(self, current, other):
|
||||
if current == other:
|
||||
return True
|
||||
try:
|
||||
version = (
|
||||
other
|
||||
if isinstance(other, semantic_version.Version)
|
||||
else cast_version_to_semver(other)
|
||||
)
|
||||
return version in semantic_version.SimpleSpec(current)
|
||||
except ValueError:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
class PackageOutdatedResult:
|
||||
UPDATE_INCREMENT_MAJOR = "major"
|
||||
@ -485,9 +518,11 @@ class PackageItem:
|
||||
|
||||
def __eq__(self, other):
|
||||
conds = [
|
||||
os.path.realpath(self.path) == os.path.realpath(other.path)
|
||||
if self.path and other.path
|
||||
else self.path == other.path,
|
||||
(
|
||||
os.path.realpath(self.path) == os.path.realpath(other.path)
|
||||
if self.path and other.path
|
||||
else self.path == other.path
|
||||
),
|
||||
self.metadata == other.metadata,
|
||||
]
|
||||
return all(conds)
|
||||
|
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import sys
|
||||
from tarfile import open as tarfile_open
|
||||
from time import mktime
|
||||
from zipfile import ZipFile
|
||||
@ -82,19 +83,23 @@ class TARArchiver(BaseArchiver):
|
||||
).startswith(base)
|
||||
|
||||
def extract_item(self, item, dest_dir):
|
||||
if sys.version_info >= (3, 12):
|
||||
self._afo.extract(item, dest_dir, filter="data")
|
||||
return self.after_extract(item, dest_dir)
|
||||
|
||||
# apply custom security logic
|
||||
dest_dir = self.resolve_path(dest_dir)
|
||||
bad_conds = [
|
||||
self.is_bad_path(item.name, dest_dir),
|
||||
self.is_link(item) and self.is_bad_link(item, dest_dir),
|
||||
]
|
||||
if not any(bad_conds):
|
||||
super().extract_item(item, dest_dir)
|
||||
else:
|
||||
click.secho(
|
||||
if any(bad_conds):
|
||||
return click.secho(
|
||||
"Blocked insecure item `%s` from TAR archive" % item.name,
|
||||
fg="red",
|
||||
err=True,
|
||||
)
|
||||
return super().extract_item(item, dest_dir)
|
||||
|
||||
|
||||
class ZIPArchiver(BaseArchiver):
|
||||
|
@ -116,9 +116,9 @@ class PlatformRunMixin:
|
||||
args,
|
||||
stdout=proc.BuildAsyncPipe(
|
||||
line_callback=self._on_stdout_line,
|
||||
data_callback=lambda data: None
|
||||
if self.silent
|
||||
else _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,
|
||||
|
@ -82,9 +82,11 @@ def lint_configuration(json_output=False):
|
||||
(
|
||||
click.style(error["type"], fg="red"),
|
||||
error["message"],
|
||||
error.get("source", "") + (f":{error.get('lineno')}")
|
||||
if "lineno" in error
|
||||
else "",
|
||||
(
|
||||
error.get("source", "") + (f":{error.get('lineno')}")
|
||||
if "lineno" in error
|
||||
else ""
|
||||
),
|
||||
)
|
||||
for error in errors
|
||||
],
|
||||
|
@ -79,6 +79,7 @@ def project_init_cmd(
|
||||
env_prefix,
|
||||
silent,
|
||||
):
|
||||
project_dir = os.path.abspath(project_dir)
|
||||
is_new_project = not is_platformio_project(project_dir)
|
||||
if is_new_project:
|
||||
if not silent:
|
||||
@ -223,7 +224,7 @@ def init_lib_readme(lib_dir):
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
@ -131,27 +131,27 @@ def compute_project_checksum(config):
|
||||
return checksum.hexdigest()
|
||||
|
||||
|
||||
def load_build_metadata(project_dir, env_or_envs, cache=False, debug=False):
|
||||
def load_build_metadata(project_dir, env_or_envs, cache=False, build_type=None):
|
||||
assert env_or_envs
|
||||
env_names = env_or_envs
|
||||
if not isinstance(env_names, list):
|
||||
env_names = [env_names]
|
||||
|
||||
with fs.cd(project_dir):
|
||||
result = _get_cached_build_metadata(project_dir, env_names) if cache else {}
|
||||
result = _get_cached_build_metadata(env_names) if cache else {}
|
||||
# incompatible build-type data
|
||||
for name in list(result.keys()):
|
||||
build_type = result[name].get("build_type", "")
|
||||
outdated_conds = [
|
||||
not build_type,
|
||||
debug and "debug" not in build_type,
|
||||
not debug and "debug" in build_type,
|
||||
]
|
||||
if any(outdated_conds):
|
||||
del result[name]
|
||||
for env_name in list(result.keys()):
|
||||
if build_type is None:
|
||||
build_type = ProjectConfig.get_instance().get(
|
||||
f"env:{env_name}", "build_type"
|
||||
)
|
||||
if result[env_name].get("build_type", "") != build_type:
|
||||
del result[env_name]
|
||||
missed_env_names = set(env_names) - set(result.keys())
|
||||
if missed_env_names:
|
||||
result.update(_load_build_metadata(project_dir, missed_env_names, debug))
|
||||
result.update(
|
||||
_load_build_metadata(project_dir, missed_env_names, build_type)
|
||||
)
|
||||
|
||||
if not isinstance(env_or_envs, list) and env_or_envs in result:
|
||||
return result[env_or_envs]
|
||||
@ -162,14 +162,16 @@ def load_build_metadata(project_dir, env_or_envs, cache=False, debug=False):
|
||||
load_project_ide_data = load_build_metadata
|
||||
|
||||
|
||||
def _load_build_metadata(project_dir, env_names, debug=False):
|
||||
def _load_build_metadata(project_dir, env_names, build_type=None):
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from platformio import app
|
||||
from platformio.run.cli import cli as cmd_run
|
||||
|
||||
args = ["--project-dir", project_dir, "--target", "__idedata"]
|
||||
if debug:
|
||||
if build_type == "debug":
|
||||
args.extend(["--target", "__debug"])
|
||||
# if build_type == "test":
|
||||
# args.extend(["--target", "__test"])
|
||||
for name in env_names:
|
||||
args.extend(["-e", name])
|
||||
app.set_session_var("pause_telemetry", True)
|
||||
@ -181,16 +183,16 @@ def _load_build_metadata(project_dir, env_names, debug=False):
|
||||
raise result.exception
|
||||
if '"includes":' not in result.output:
|
||||
raise exception.UserSideException(result.output)
|
||||
return _get_cached_build_metadata(project_dir, env_names)
|
||||
return _get_cached_build_metadata(env_names)
|
||||
|
||||
|
||||
def _get_cached_build_metadata(project_dir, env_names):
|
||||
build_dir = ProjectConfig.get_instance(
|
||||
os.path.join(project_dir, "platformio.ini")
|
||||
).get("platformio", "build_dir")
|
||||
def _get_cached_build_metadata(env_names):
|
||||
build_dir = ProjectConfig.get_instance().get("platformio", "build_dir")
|
||||
result = {}
|
||||
for name in env_names:
|
||||
if not os.path.isfile(os.path.join(build_dir, name, "idedata.json")):
|
||||
for env_name in env_names:
|
||||
if not os.path.isfile(os.path.join(build_dir, env_name, "idedata.json")):
|
||||
continue
|
||||
result[name] = fs.load_json(os.path.join(build_dir, name, "idedata.json"))
|
||||
result[env_name] = fs.load_json(
|
||||
os.path.join(build_dir, env_name, "idedata.json")
|
||||
)
|
||||
return result
|
||||
|
@ -91,9 +91,11 @@ class ProjectGenerator:
|
||||
"default_debug_env_name": get_default_debug_env(self.config),
|
||||
"env_name": self.env_name,
|
||||
"user_home_dir": os.path.abspath(fs.expanduser("~")),
|
||||
"platformio_path": sys.argv[0]
|
||||
if os.path.isfile(sys.argv[0])
|
||||
else where_is_program("platformio"),
|
||||
"platformio_path": (
|
||||
sys.argv[0]
|
||||
if os.path.isfile(sys.argv[0])
|
||||
else where_is_program("platformio")
|
||||
),
|
||||
"env_path": os.getenv("PATH"),
|
||||
"env_pathsep": os.pathsep,
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ ProjectOptions = OrderedDict(
|
||||
ConfigEnvOption(
|
||||
group="monitor",
|
||||
name="monitor_encoding",
|
||||
description="Custom encoding (e.g. hexlify, Latin1, UTF-8)",
|
||||
description="Custom encoding (e.g. hexlify, Latin-1, UTF-8)",
|
||||
default="UTF-8",
|
||||
),
|
||||
# Library
|
||||
|
@ -41,9 +41,11 @@ def access_list_cmd(owner, urn_type, json_output): # pylint: disable=unused-arg
|
||||
table_data.append(
|
||||
(
|
||||
"Access:",
|
||||
click.style("Private", fg="red")
|
||||
if resource.get("private", False)
|
||||
else "Public",
|
||||
(
|
||||
click.style("Private", fg="red")
|
||||
if resource.get("private", False)
|
||||
else "Public"
|
||||
),
|
||||
)
|
||||
)
|
||||
table_data.append(
|
||||
|
@ -54,9 +54,11 @@ class RegistryFileMirrorIterator:
|
||||
"head",
|
||||
self._url_parts.path,
|
||||
allow_redirects=False,
|
||||
params=dict(bypass=",".join(self._visited_mirrors))
|
||||
if self._visited_mirrors
|
||||
else None,
|
||||
params=(
|
||||
dict(bypass=",".join(self._visited_mirrors))
|
||||
if self._visited_mirrors
|
||||
else None
|
||||
),
|
||||
x_with_authorization=RegistryClient.allowed_private_packages(),
|
||||
)
|
||||
stop_conditions = [
|
||||
|
@ -123,9 +123,11 @@ class DeviceMonitorClient( # pylint: disable=too-many-instance-attributes
|
||||
index=i + 1,
|
||||
host=device[0] + ":" if len(result) > 1 else "",
|
||||
port=device[1]["port"],
|
||||
description=device[1]["description"]
|
||||
if device[1]["description"] != "n/a"
|
||||
else "",
|
||||
description=(
|
||||
device[1]["description"]
|
||||
if device[1]["description"] != "n/a"
|
||||
else ""
|
||||
),
|
||||
)
|
||||
)
|
||||
device_index = click.prompt(
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
|
||||
@ -79,6 +80,7 @@ from platformio.test.runners.factory import TestRunnerFactory
|
||||
help="A program argument (multiple are allowed)",
|
||||
)
|
||||
@click.option("--list-tests", is_flag=True)
|
||||
@click.option("--json-output", is_flag=True)
|
||||
@click.option("--json-output-path", type=click.Path())
|
||||
@click.option("--junit-output-path", type=click.Path())
|
||||
@click.option(
|
||||
@ -105,6 +107,7 @@ def cli( # pylint: disable=too-many-arguments,too-many-locals,redefined-builtin
|
||||
monitor_dtr,
|
||||
program_args,
|
||||
list_tests,
|
||||
json_output,
|
||||
json_output_path,
|
||||
junit_output_path,
|
||||
verbose,
|
||||
@ -156,6 +159,7 @@ def cli( # pylint: disable=too-many-arguments,too-many-locals,redefined-builtin
|
||||
stdout_report.generate(verbose=verbose or list_tests)
|
||||
|
||||
for output_format, output_path in [
|
||||
("json", subprocess.STDOUT if json_output else None),
|
||||
("json", json_output_path),
|
||||
("junit", junit_output_path),
|
||||
]:
|
||||
|
@ -15,6 +15,7 @@
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import click
|
||||
|
||||
@ -24,6 +25,9 @@ from platformio.test.result import TestStatus
|
||||
|
||||
class JsonTestReport(TestReportBase):
|
||||
def generate(self, output_path, verbose=False):
|
||||
if output_path == subprocess.STDOUT:
|
||||
return click.echo("\n\n" + json.dumps(self.to_json()))
|
||||
|
||||
if os.path.isdir(output_path):
|
||||
output_path = os.path.join(
|
||||
output_path,
|
||||
@ -40,6 +44,8 @@ class JsonTestReport(TestReportBase):
|
||||
if verbose:
|
||||
click.secho(f"Saved JSON report to the {output_path}", fg="green")
|
||||
|
||||
return True
|
||||
|
||||
def to_json(self):
|
||||
result = dict(
|
||||
version="1.0",
|
||||
@ -62,11 +68,13 @@ class JsonTestReport(TestReportBase):
|
||||
test_dir=test_suite.test_dir,
|
||||
status=test_suite.status.name,
|
||||
duration=test_suite.duration,
|
||||
timestamp=datetime.datetime.fromtimestamp(test_suite.timestamp).strftime(
|
||||
"%Y-%m-%dT%H:%M:%S"
|
||||
)
|
||||
if test_suite.timestamp
|
||||
else None,
|
||||
timestamp=(
|
||||
datetime.datetime.fromtimestamp(test_suite.timestamp).strftime(
|
||||
"%Y-%m-%dT%H:%M:%S"
|
||||
)
|
||||
if test_suite.timestamp
|
||||
else None
|
||||
),
|
||||
testcase_nums=len(test_suite.cases),
|
||||
error_nums=test_suite.get_status_nums(TestStatus.ERRORED),
|
||||
failure_nums=test_suite.get_status_nums(TestStatus.FAILED),
|
||||
|
@ -184,10 +184,6 @@ void unityOutputComplete(void) { unittest_uart_end(); }
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Delete when Unity > 2.5.2 is released"""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def get_unity_framework_config(self):
|
||||
if not self.platform.is_embedded():
|
||||
return self.UNITY_FRAMEWORK_CONFIG["native"]
|
||||
|
2
setup.py
2
setup.py
@ -23,7 +23,7 @@ from platformio import (
|
||||
__url__,
|
||||
__version__,
|
||||
)
|
||||
from platformio.pipdeps import get_pip_dependencies
|
||||
from platformio.dependencies import get_pip_dependencies
|
||||
|
||||
setup(
|
||||
name=__title__,
|
||||
|
@ -18,7 +18,8 @@ import os
|
||||
|
||||
import pytest
|
||||
|
||||
from platformio import __core_packages__, fs
|
||||
from platformio import fs
|
||||
from platformio.dependencies import get_core_dependencies
|
||||
from platformio.package.commands.install import package_install_cmd
|
||||
from platformio.package.manager.library import LibraryPackageManager
|
||||
from platformio.package.manager.platform import PlatformPackageManager
|
||||
@ -177,7 +178,7 @@ def test_baremetal_project(
|
||||
),
|
||||
]
|
||||
assert pkgs_to_specs(ToolPackageManager().get_installed()) == [
|
||||
PackageSpec("tool-scons@%s" % __core_packages__["tool-scons"][1:]),
|
||||
PackageSpec("tool-scons@%s" % get_core_dependencies()["tool-scons"][1:]),
|
||||
PackageSpec("toolchain-atmelavr@1.70300.191015"),
|
||||
]
|
||||
|
||||
@ -210,7 +211,7 @@ def test_project(
|
||||
]
|
||||
assert pkgs_to_specs(ToolPackageManager().get_installed()) == [
|
||||
PackageSpec("framework-arduino-avr-attiny@1.5.2"),
|
||||
PackageSpec("tool-scons@%s" % __core_packages__["tool-scons"][1:]),
|
||||
PackageSpec("tool-scons@%s" % get_core_dependencies()["tool-scons"][1:]),
|
||||
PackageSpec("toolchain-atmelavr@1.70300.191015"),
|
||||
]
|
||||
assert config.get("env:devkit", "lib_deps") == [
|
||||
|
@ -24,7 +24,7 @@ PROJECT_OUTDATED_CONFIG_TPL = """
|
||||
platform = platformio/atmelavr@^2
|
||||
framework = arduino
|
||||
board = attiny88
|
||||
lib_deps = milesburton/DallasTemperature@~3.8.0
|
||||
lib_deps = milesburton/DallasTemperature@~3.9.0
|
||||
"""
|
||||
|
||||
PROJECT_UPDATED_CONFIG_TPL = """
|
||||
@ -32,7 +32,7 @@ PROJECT_UPDATED_CONFIG_TPL = """
|
||||
platform = platformio/atmelavr@<4
|
||||
framework = arduino
|
||||
board = attiny88
|
||||
lib_deps = milesburton/DallasTemperature@^3.8.0
|
||||
lib_deps = milesburton/DallasTemperature@^3.9.0
|
||||
"""
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ def test_project(clirunner, validate_cliresult, isolated_pio_core, tmp_path):
|
||||
re.MULTILINE,
|
||||
)
|
||||
assert re.search(
|
||||
r"^DallasTemperature\s+3\.8\.1\s+3\.\d+\.\d+\s+3\.\d+\.\d+\s+Library\s+devkit",
|
||||
r"^DallasTemperature\s+3\.\d\.1\s+3\.\d+\.\d+\s+3\.\d+\.\d+\s+Library\s+devkit",
|
||||
result.output,
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
import os
|
||||
|
||||
from platformio import __core_packages__, fs
|
||||
from platformio import fs
|
||||
from platformio.dependencies import get_core_dependencies
|
||||
from platformio.package.commands.install import package_install_cmd
|
||||
from platformio.package.commands.update import package_update_cmd
|
||||
from platformio.package.exception import UnknownPackageError
|
||||
@ -26,12 +27,14 @@ from platformio.package.manager.tool import ToolPackageManager
|
||||
from platformio.package.meta import PackageSpec
|
||||
from platformio.project.config import ProjectConfig
|
||||
|
||||
DALLASTEMPERATURE_LATEST_VERSION = "3.11.0"
|
||||
|
||||
PROJECT_OUTDATED_CONFIG_TPL = """
|
||||
[env:devkit]
|
||||
platform = platformio/atmelavr@^2
|
||||
framework = arduino
|
||||
board = attiny88
|
||||
lib_deps = milesburton/DallasTemperature@~3.8.0
|
||||
lib_deps = milesburton/DallasTemperature@^3.8.0
|
||||
"""
|
||||
|
||||
PROJECT_UPDATED_CONFIG_TPL = """
|
||||
@ -162,7 +165,7 @@ def test_project(
|
||||
os.path.join(config.get("platformio", "libdeps_dir"), "devkit")
|
||||
)
|
||||
assert pkgs_to_specs(lm.get_installed()) == [
|
||||
PackageSpec("DallasTemperature@3.8.1"),
|
||||
PackageSpec(f"DallasTemperature@{DALLASTEMPERATURE_LATEST_VERSION}"),
|
||||
PackageSpec(
|
||||
"OneWire@%s" % get_pkg_latest_version("paulstoffregen/OneWire")
|
||||
),
|
||||
@ -172,11 +175,11 @@ def test_project(
|
||||
]
|
||||
assert pkgs_to_specs(ToolPackageManager().get_installed()) == [
|
||||
PackageSpec("framework-arduino-avr-attiny@1.3.2"),
|
||||
PackageSpec("tool-scons@%s" % __core_packages__["tool-scons"][1:]),
|
||||
PackageSpec("tool-scons@%s" % get_core_dependencies()["tool-scons"][1:]),
|
||||
PackageSpec("toolchain-atmelavr@1.50400.190710"),
|
||||
]
|
||||
assert config.get("env:devkit", "lib_deps") == [
|
||||
"milesburton/DallasTemperature@~3.8.0"
|
||||
"milesburton/DallasTemperature@^3.8.0"
|
||||
]
|
||||
|
||||
# update packages
|
||||
@ -202,7 +205,7 @@ def test_project(
|
||||
]
|
||||
assert pkgs_to_specs(ToolPackageManager().get_installed()) == [
|
||||
PackageSpec("framework-arduino-avr-attiny@1.3.2"),
|
||||
PackageSpec("tool-scons@%s" % __core_packages__["tool-scons"][1:]),
|
||||
PackageSpec("tool-scons@%s" % get_core_dependencies()["tool-scons"][1:]),
|
||||
PackageSpec("toolchain-atmelavr@1.70300.191015"),
|
||||
PackageSpec("toolchain-atmelavr@1.50400.190710"),
|
||||
]
|
||||
@ -227,7 +230,7 @@ def test_custom_project_libraries(
|
||||
project_dir = tmp_path / "project"
|
||||
project_dir.mkdir()
|
||||
(project_dir / "platformio.ini").write_text(PROJECT_OUTDATED_CONFIG_TPL)
|
||||
spec = "milesburton/DallasTemperature@~3.8.0"
|
||||
spec = "milesburton/DallasTemperature@^3.8.0"
|
||||
result = clirunner.invoke(
|
||||
package_install_cmd,
|
||||
["-d", str(project_dir), "-e", "devkit", "-l", spec],
|
||||
@ -240,7 +243,7 @@ def test_custom_project_libraries(
|
||||
os.path.join(config.get("platformio", "libdeps_dir"), "devkit")
|
||||
)
|
||||
assert pkgs_to_specs(lm.get_installed()) == [
|
||||
PackageSpec("DallasTemperature@3.8.1"),
|
||||
PackageSpec(f"DallasTemperature@{DALLASTEMPERATURE_LATEST_VERSION}"),
|
||||
PackageSpec(
|
||||
"OneWire@%s" % get_pkg_latest_version("paulstoffregen/OneWire")
|
||||
),
|
||||
|
@ -803,3 +803,49 @@ check_src_filters =
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS
|
||||
assert "test.cpp" in result.output
|
||||
assert "main.cpp" not in result.output
|
||||
|
||||
|
||||
def test_check_sources_in_project_root(clirunner, validate_cliresult, tmpdir_factory):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
|
||||
config = (
|
||||
"""
|
||||
[platformio]
|
||||
src_dir = ./
|
||||
"""
|
||||
+ DEFAULT_CONFIG
|
||||
)
|
||||
tmpdir.join("platformio.ini").write(config)
|
||||
tmpdir.join("main.cpp").write(TEST_CODE)
|
||||
tmpdir.mkdir("spi").join("uart.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * 2
|
||||
|
||||
|
||||
def test_check_sources_in_external_dir(clirunner, validate_cliresult, tmpdir_factory):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
external_src_dir = tmpdir_factory.mktemp("external_src_dir")
|
||||
|
||||
config = (
|
||||
f"""
|
||||
[platformio]
|
||||
src_dir = {external_src_dir}
|
||||
"""
|
||||
+ DEFAULT_CONFIG
|
||||
)
|
||||
tmpdir.join("platformio.ini").write(config)
|
||||
external_src_dir.join("main.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS
|
||||
|
@ -15,6 +15,7 @@
|
||||
import json
|
||||
import os
|
||||
|
||||
from platformio import fs
|
||||
from platformio.commands.boards import cli as cmd_boards
|
||||
from platformio.project.commands.init import project_init_cmd
|
||||
from platformio.project.config import ProjectConfig
|
||||
@ -36,27 +37,28 @@ def test_init_default(clirunner, validate_cliresult):
|
||||
validate_pioproject(os.getcwd())
|
||||
|
||||
|
||||
def test_init_ext_folder(clirunner, validate_cliresult):
|
||||
with clirunner.isolated_filesystem():
|
||||
ext_folder_name = "ext_folder"
|
||||
os.makedirs(ext_folder_name)
|
||||
result = clirunner.invoke(project_init_cmd, ["-d", ext_folder_name])
|
||||
validate_cliresult(result)
|
||||
validate_pioproject(os.path.join(os.getcwd(), ext_folder_name))
|
||||
|
||||
|
||||
def test_init_duplicated_boards(clirunner, validate_cliresult, tmpdir):
|
||||
with tmpdir.as_cwd():
|
||||
for _ in range(2):
|
||||
result = clirunner.invoke(
|
||||
project_init_cmd,
|
||||
["-b", "uno", "-b", "uno", "--no-install-dependencies"],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
validate_pioproject(str(tmpdir))
|
||||
config = ProjectConfig(os.path.join(os.getcwd(), "platformio.ini"))
|
||||
config.validate()
|
||||
assert set(config.sections()) == set(["env:uno"])
|
||||
project_dir = str(tmpdir.join("ext_folder"))
|
||||
os.makedirs(project_dir)
|
||||
|
||||
with fs.cd(os.path.dirname(project_dir)):
|
||||
result = clirunner.invoke(
|
||||
project_init_cmd,
|
||||
[
|
||||
"-d",
|
||||
os.path.basename(project_dir),
|
||||
"-b",
|
||||
"uno",
|
||||
"-b",
|
||||
"uno",
|
||||
"--no-install-dependencies",
|
||||
],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
validate_pioproject(project_dir)
|
||||
config = ProjectConfig(os.path.join(project_dir, "platformio.ini"))
|
||||
config.validate()
|
||||
assert set(config.sections()) == set(["env:uno"])
|
||||
|
||||
|
||||
def test_init_ide_without_board(clirunner, tmpdir):
|
||||
|
@ -42,7 +42,7 @@ board = devkit
|
||||
framework = foo
|
||||
lib_deps =
|
||||
CustomLib
|
||||
ArduinoJson @ 5.10.1
|
||||
ArduinoJson @ 6.18.5
|
||||
"""
|
||||
)
|
||||
result = clirunner.invoke(
|
||||
@ -163,7 +163,7 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core, tmpdir_factory
|
||||
storage_dir = tmpdir_factory.mktemp("test-updates")
|
||||
result = clirunner.invoke(
|
||||
cmd_lib,
|
||||
["-d", str(storage_dir), "install", "ArduinoJson @ 5.10.1", "Blynk @ ~0.5.0"],
|
||||
["-d", str(storage_dir), "install", "ArduinoJson @ 6.18.5", "Blynk @ ~1.2"],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
result = clirunner.invoke(
|
||||
@ -173,17 +173,17 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core, tmpdir_factory
|
||||
outdated = json.loads(result.stdout)
|
||||
assert len(outdated) == 2
|
||||
# ArduinoJson
|
||||
assert outdated[0]["version"] == "5.10.1"
|
||||
assert outdated[0]["version"] == "6.18.5"
|
||||
assert outdated[0]["versionWanted"] is None
|
||||
assert semantic_version.Version(
|
||||
outdated[0]["versionLatest"]
|
||||
) > semantic_version.Version("6.16.0")
|
||||
) > semantic_version.Version("6.18.5")
|
||||
# Blynk
|
||||
assert outdated[1]["version"] == "0.5.4"
|
||||
assert outdated[1]["version"] == "1.2.0"
|
||||
assert outdated[1]["versionWanted"] is None
|
||||
assert semantic_version.Version(
|
||||
outdated[1]["versionLatest"]
|
||||
) > semantic_version.Version("0.6.0")
|
||||
) > semantic_version.Version("1.2.0")
|
||||
|
||||
# check with spec
|
||||
result = clirunner.invoke(
|
||||
@ -194,19 +194,19 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core, tmpdir_factory
|
||||
"update",
|
||||
"--dry-run",
|
||||
"--json-output",
|
||||
"ArduinoJson @ ^5",
|
||||
"ArduinoJson @ ^6",
|
||||
],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
outdated = json.loads(result.stdout)
|
||||
assert outdated[0]["version"] == "5.10.1"
|
||||
assert outdated[0]["versionWanted"] == "5.13.4"
|
||||
assert outdated[0]["version"] == "6.18.5"
|
||||
assert outdated[0]["versionWanted"] == "6.21.5"
|
||||
assert semantic_version.Version(
|
||||
outdated[0]["versionLatest"]
|
||||
) > semantic_version.Version("6.16.0")
|
||||
# update with spec
|
||||
result = clirunner.invoke(
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "--silent", "ArduinoJson @ ^5.10.1"]
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "--silent", "ArduinoJson @ ^6.18.5"]
|
||||
)
|
||||
validate_cliresult(result)
|
||||
result = clirunner.invoke(
|
||||
@ -215,12 +215,12 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core, tmpdir_factory
|
||||
validate_cliresult(result)
|
||||
items = json.loads(result.stdout)
|
||||
assert len(items) == 2
|
||||
assert items[0]["version"] == "5.13.4"
|
||||
assert items[1]["version"] == "0.5.4"
|
||||
assert items[0]["version"] == "6.21.5"
|
||||
assert items[1]["version"] == "1.2.0"
|
||||
|
||||
# Check incompatible
|
||||
result = clirunner.invoke(
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "--dry-run", "ArduinoJson @ ^5"]
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "--dry-run", "ArduinoJson @ ^6"]
|
||||
)
|
||||
with pytest.raises(
|
||||
AssertionError,
|
||||
@ -228,7 +228,7 @@ def test_update(clirunner, validate_cliresult, isolated_pio_core, tmpdir_factory
|
||||
):
|
||||
validate_cliresult(result)
|
||||
result = clirunner.invoke(
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "ArduinoJson @ ^5"]
|
||||
cmd_lib, ["-d", str(storage_dir), "update", "ArduinoJson @ ^6"]
|
||||
)
|
||||
validate_cliresult(result)
|
||||
assert "ArduinoJson@5.13.4 is already up-to-date" in result.stdout
|
||||
assert "ArduinoJson@6.21.5 is already up-to-date" in result.stdout
|
||||
|
@ -23,6 +23,7 @@ from platformio.package.exception import UnknownPackageError
|
||||
from platformio.util import strip_ansi_codes
|
||||
|
||||
PlatformioCLI.leftover_args = ["--json-output"] # hook for click
|
||||
ARDUINO_JSON_VERSION = "6.21.5"
|
||||
|
||||
|
||||
def test_search(clirunner, validate_cliresult):
|
||||
@ -44,10 +45,10 @@ def test_global_install_registry(clirunner, validate_cliresult, isolated_pio_cor
|
||||
"-g",
|
||||
"install",
|
||||
"64",
|
||||
"ArduinoJson@~5.10.0",
|
||||
"547@2.2.4",
|
||||
"ArduinoJson@~6",
|
||||
"547@2.7.3",
|
||||
"AsyncMqttClient@<=0.8.2",
|
||||
"Adafruit PN532@1.2.0",
|
||||
"Adafruit PN532@1.3.2",
|
||||
],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
@ -60,7 +61,7 @@ def test_global_install_registry(clirunner, validate_cliresult, isolated_pio_cor
|
||||
items1 = [d.basename for d in isolated_pio_core.join("lib").listdir()]
|
||||
items2 = [
|
||||
"ArduinoJson",
|
||||
"ArduinoJson@5.10.1",
|
||||
f"ArduinoJson@{ARDUINO_JSON_VERSION}",
|
||||
"NeoPixelBus",
|
||||
"AsyncMqttClient",
|
||||
"ESPAsyncTCP",
|
||||
@ -79,7 +80,7 @@ def test_global_install_archive(clirunner, validate_cliresult, isolated_pio_core
|
||||
"install",
|
||||
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip",
|
||||
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip@5.8.2",
|
||||
"SomeLib=https://dl.registry.platformio.org/download/milesburton/library/DallasTemperature/3.8.1/DallasTemperature-3.8.1.tar.gz",
|
||||
"SomeLib=https://dl.registry.platformio.org/download/milesburton/library/DallasTemperature/3.11.0/DallasTemperature-3.11.0.tar.gz",
|
||||
"https://github.com/Pedroalbuquerque/ESP32WebServer/archive/master.zip",
|
||||
],
|
||||
)
|
||||
@ -142,7 +143,7 @@ def test_install_duplicates( # pylint: disable=unused-argument
|
||||
[
|
||||
"-g",
|
||||
"install",
|
||||
"https://dl.registry.platformio.org/download/milesburton/library/DallasTemperature/3.8.1/DallasTemperature-3.8.1.tar.gz",
|
||||
"https://dl.registry.platformio.org/download/milesburton/library/DallasTemperature/3.11.0/DallasTemperature-3.11.0.tar.gz",
|
||||
],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
@ -176,11 +177,11 @@ def test_global_lib_list(clirunner, validate_cliresult):
|
||||
n in result.output
|
||||
for n in (
|
||||
"required: https://github.com/Pedroalbuquerque/ESP32WebServer/archive/master.zip",
|
||||
"ArduinoJson @ 5.10.1",
|
||||
f"ArduinoJson @ {ARDUINO_JSON_VERSION}",
|
||||
"required: git+https://github.com/gioblu/PJON.git#3.0",
|
||||
"PJON @ 3.0.0+sha.1fb26f",
|
||||
)
|
||||
)
|
||||
), result.output
|
||||
|
||||
result = clirunner.invoke(cmd_lib, ["-g", "list", "--json-output"])
|
||||
assert all(
|
||||
@ -188,7 +189,7 @@ def test_global_lib_list(clirunner, validate_cliresult):
|
||||
for n in (
|
||||
"__pkg_dir",
|
||||
'"__src_url": "git+https://github.com/gioblu/PJON.git#6.2"',
|
||||
'"version": "5.10.1"',
|
||||
f'"version": "{ARDUINO_JSON_VERSION}"',
|
||||
)
|
||||
)
|
||||
items1 = [i["name"] for i in json.loads(result.output)]
|
||||
@ -218,13 +219,13 @@ def test_global_lib_list(clirunner, validate_cliresult):
|
||||
]
|
||||
versions2 = [
|
||||
"ArduinoJson@5.8.2",
|
||||
"ArduinoJson@5.10.1",
|
||||
f"ArduinoJson@{ARDUINO_JSON_VERSION}",
|
||||
"AsyncMqttClient@0.8.2",
|
||||
"NeoPixelBus@2.2.4",
|
||||
"NeoPixelBus@2.7.3",
|
||||
"PJON@6.2.0+sha.07fe9aa",
|
||||
"PJON@3.0.0+sha.1fb26fd",
|
||||
"PubSubClient@2.6.0+sha.bef5814",
|
||||
"Adafruit PN532@1.2.0",
|
||||
"Adafruit PN532@1.3.2",
|
||||
]
|
||||
assert set(versions1) >= set(versions2)
|
||||
|
||||
@ -249,7 +250,7 @@ def test_global_lib_update(clirunner, validate_cliresult):
|
||||
assert "__pkg_dir" in oudated[0]
|
||||
result = clirunner.invoke(cmd_lib, ["-g", "update", oudated[0]["__pkg_dir"]])
|
||||
validate_cliresult(result)
|
||||
assert "Removing NeoPixelBus @ 2.2.4" in strip_ansi_codes(result.output)
|
||||
assert "Removing NeoPixelBus @ 2.7.3" in strip_ansi_codes(result.output)
|
||||
|
||||
# update all libraries
|
||||
result = clirunner.invoke(
|
||||
|
@ -63,7 +63,7 @@ def test_install_unknown_from_registry(clirunner):
|
||||
def test_install_core_3_dev_platform(clirunner, validate_cliresult, isolated_pio_core):
|
||||
result = clirunner.invoke(
|
||||
cli_platform.platform_install,
|
||||
["atmelavr@1.2.0", "--skip-default-package"],
|
||||
["atmelavr@2.2.0", "--skip-default-package"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
@ -71,11 +71,11 @@ def test_install_core_3_dev_platform(clirunner, validate_cliresult, isolated_pio
|
||||
def test_install_known_version(clirunner, validate_cliresult, isolated_pio_core):
|
||||
result = clirunner.invoke(
|
||||
cli_platform.platform_install,
|
||||
["atmelavr@2.0.0", "--skip-default-package", "--with-package", "tool-avrdude"],
|
||||
["atmelavr@4.2.0", "--skip-default-package", "--with-package", "tool-avrdude"],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
output = strip_ansi_codes(result.output)
|
||||
assert "atmelavr @ 2.0.0" in output
|
||||
assert "atmelavr@4.2.0" in output
|
||||
assert not os.path.isdir(str(isolated_pio_core.join("packages")))
|
||||
|
||||
|
||||
@ -128,14 +128,14 @@ def test_update_raw(clirunner, validate_cliresult, isolated_pio_core):
|
||||
result = clirunner.invoke(cli_platform.platform_update, ["atmelavr"])
|
||||
validate_cliresult(result)
|
||||
output = strip_ansi_codes(result.output)
|
||||
assert "Removing atmelavr @ 2.0.0" in output
|
||||
assert "Removing atmelavr @ 4.2.0" in output
|
||||
assert "Platform Manager: Installing platformio/atmelavr @" in output
|
||||
assert len(isolated_pio_core.join("packages").listdir()) == 2
|
||||
|
||||
|
||||
def test_uninstall(clirunner, validate_cliresult, isolated_pio_core):
|
||||
result = clirunner.invoke(
|
||||
cli_platform.platform_uninstall, ["atmelavr@1.2.0", "atmelavr", "espressif8266"]
|
||||
cli_platform.platform_uninstall, ["atmelavr@2.2.0", "atmelavr", "espressif8266"]
|
||||
)
|
||||
validate_cliresult(result)
|
||||
assert not isolated_pio_core.join("platforms").listdir()
|
||||
|
@ -219,7 +219,7 @@ def test_install_from_registry(isolated_pio_core, tmpdir_factory):
|
||||
# test conflicted names
|
||||
lm = LibraryPackageManager(str(tmpdir_factory.mktemp("conflicted-storage")))
|
||||
lm.set_log_level(logging.ERROR)
|
||||
lm.install("z3t0/IRremote@2.6.1")
|
||||
lm.install("z3t0/IRremote")
|
||||
lm.install("mbed-yuhki50/IRremote")
|
||||
assert len(lm.get_installed()) == 2
|
||||
|
||||
@ -554,14 +554,14 @@ def test_uninstall(isolated_pio_core, tmpdir_factory):
|
||||
assert not lm.get_installed()
|
||||
|
||||
# test uninstall dependencies
|
||||
assert lm.install("AsyncMqttClient-esphome @ 0.8.4")
|
||||
assert lm.install("AsyncMqttClient-esphome")
|
||||
assert len(lm.get_installed()) == 3
|
||||
assert lm.uninstall("AsyncMqttClient-esphome", skip_dependencies=True)
|
||||
assert len(lm.get_installed()) == 2
|
||||
|
||||
lm = LibraryPackageManager(str(storage_dir))
|
||||
lm.set_log_level(logging.ERROR)
|
||||
assert lm.install("AsyncMqttClient-esphome @ 0.8.4")
|
||||
assert lm.install("AsyncMqttClient-esphome")
|
||||
assert lm.uninstall("AsyncMqttClient-esphome")
|
||||
assert not lm.get_installed()
|
||||
|
||||
@ -604,23 +604,23 @@ def test_update_with_metadata(isolated_pio_core, tmpdir_factory):
|
||||
assert str(outdated.current) == "1.8.7"
|
||||
assert outdated.latest > semantic_version.Version("1.10.0")
|
||||
|
||||
pkg = lm.install("ArduinoJson @ 5.10.1")
|
||||
pkg = lm.install("ArduinoJson @ 6.19.4")
|
||||
# test latest
|
||||
outdated = lm.outdated(pkg)
|
||||
assert str(outdated.current) == "5.10.1"
|
||||
assert str(outdated.current) == "6.19.4"
|
||||
assert outdated.wanted is None
|
||||
assert outdated.latest > outdated.current
|
||||
assert outdated.latest > semantic_version.Version("5.99.99")
|
||||
|
||||
# test wanted
|
||||
outdated = lm.outdated(pkg, PackageSpec("ArduinoJson@~5"))
|
||||
assert str(outdated.current) == "5.10.1"
|
||||
assert str(outdated.wanted) == "5.13.4"
|
||||
outdated = lm.outdated(pkg, PackageSpec("ArduinoJson@~6"))
|
||||
assert str(outdated.current) == "6.19.4"
|
||||
assert str(outdated.wanted) == "6.21.5"
|
||||
assert outdated.latest > semantic_version.Version("6.16.0")
|
||||
|
||||
# update to the wanted 5.x
|
||||
new_pkg = lm.update("ArduinoJson@^5", PackageSpec("ArduinoJson@^5"))
|
||||
assert str(new_pkg.metadata.version) == "5.13.4"
|
||||
# update to the wanted 6.x
|
||||
new_pkg = lm.update("ArduinoJson@^6", PackageSpec("ArduinoJson@^6"))
|
||||
assert str(new_pkg.metadata.version) == "6.21.5"
|
||||
# check that old version is removed
|
||||
assert len(lm.get_installed()) == 2
|
||||
|
||||
|
Reference in New Issue
Block a user