From 75f68c8be1e86cc27ed30ea8aac93a6f982f185e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 15 Dec 2021 12:46:28 +0200 Subject: [PATCH 01/53] Bump version to 5.2.5a1 --- HISTORY.rst | 4 ++++ platformio/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index 9274b86b..78f1603c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -8,6 +8,10 @@ PlatformIO Core 5 **A professional collaborative platform for embedded development** +5.2.5 (2021-12-??) +~~~~~~~~~~~~~~~~~~ + + 5.2.4 (2021-12-15) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/__init__.py b/platformio/__init__.py index 075823ca..07baf97f 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, 4) +VERSION = (5, 2, "5a1") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 949b4562c764668c436f1f3c694b3fdc10fe7e7e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 15 Dec 2021 13:46:30 +0200 Subject: [PATCH 02/53] Packaging: exclude extras from Arduino libraries --- platformio/package/manifest/parser.py | 2 +- platformio/package/pack.py | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/platformio/package/manifest/parser.py b/platformio/package/manifest/parser.py index 54417c0c..47e9025d 100644 --- a/platformio/package/manifest/parser.py +++ b/platformio/package/manifest/parser.py @@ -608,7 +608,7 @@ class LibraryPropertiesManifestParser(BaseManifestParser): return None def _parse_export(self): - result = {"exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"]} + result = {} include = None if self.remote_url: url_attrs = urlparse(self.remote_url) diff --git a/platformio/package/pack.py b/platformio/package/pack.py index 2d1eea46..df5b23c1 100644 --- a/platformio/package/pack.py +++ b/platformio/package/pack.py @@ -22,7 +22,11 @@ import tempfile from platformio import fs from platformio.compat import IS_WINDOWS from platformio.package.exception import PackageException, UserSideException -from platformio.package.manifest.parser import ManifestFileType, ManifestParserFactory +from platformio.package.manifest.parser import ( + LibraryPropertiesManifestParser, + ManifestFileType, + ManifestParserFactory, +) from platformio.package.manifest.schema import ManifestSchema from platformio.package.meta import PackageItem from platformio.package.unpack import FileUnpacker @@ -55,6 +59,10 @@ class PackagePacker(object): "doc", "docs", "mkdocs", + "doxygen", + "*.doxyfile", + "html", + "media", "**/*.[pP][dD][fF]", "**/*.[dD][oO][cC]?", "**/*.[pP][pP][tT]?", @@ -79,10 +87,8 @@ class PackagePacker(object): EXCLUDE_LIBRARY_EXTRA = [ "assets", "extra", + "extras", "resources", - "html", - "media", - "doxygen", "**/build/", "**/*.flat", "**/*.[jJ][aA][rR]", @@ -97,6 +103,7 @@ class PackagePacker(object): def __init__(self, package, manifest_uri=None): self.package = package self.manifest_uri = manifest_uri + self.manifest_parser = None @staticmethod def get_archive_name(name, version, system=None): @@ -128,7 +135,8 @@ class PackagePacker(object): src = tmp_dir src = self.find_source_root(src) - manifest = self.load_manifest(src) + self.manifest_parser = ManifestParserFactory.new_from_dir(src) + manifest = ManifestSchema().load_manifest(self.manifest_parser.as_dict()) filename = self.get_archive_name( manifest["name"], manifest["version"], @@ -144,11 +152,6 @@ class PackagePacker(object): finally: shutil.rmtree(tmp_dir) - @staticmethod - def load_manifest(src): - mp = ManifestParserFactory.new_from_dir(src) - return ManifestSchema().load_manifest(mp.as_dict()) - def find_source_root(self, src): if self.manifest_uri: mp = ( @@ -214,7 +217,9 @@ class PackagePacker(object): # exclude items declared in manifest result += ["-<%s>" % p for p in exclude or []] # apply extra excludes if no custom "export" field in manifest - if not include and not exclude: + if (not include and not exclude) or isinstance( + self.manifest_parser, LibraryPropertiesManifestParser + ): result += ["-<%s>" % p for p in exclude_extra] # automatically include manifests result += ["+<%s>" % p for p in self.INCLUDE_DEFAULT] From 449722f08c070919738319285199cf08b203d7a6 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 18 Dec 2021 13:45:26 +0200 Subject: [PATCH 03/53] Improved support for private packages in PlatformIO Registry --- HISTORY.rst | 1 + platformio/clients/http.py | 4 +++- platformio/clients/registry.py | 32 +++++++++++++++++++++++++++++--- platformio/commands/access.py | 8 ++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 78f1603c..9fbfda97 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -11,6 +11,7 @@ PlatformIO Core 5 5.2.5 (2021-12-??) ~~~~~~~~~~~~~~~~~~ +- Improved support for private packages in `PlatformIO Registry `__ 5.2.4 (2021-12-15) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/clients/http.py b/platformio/clients/http.py index 0f3e3860..a2b92776 100644 --- a/platformio/clients/http.py +++ b/platformio/clients/http.py @@ -21,7 +21,7 @@ import requests.adapters from requests.packages.urllib3.util.retry import Retry # pylint:disable=import-error from platformio import __check_internet_hosts__, __default_requests_timeout__, app, util -from platformio.cache import ContentCache +from platformio.cache import ContentCache, cleanup_content_cache from platformio.exception import PlatformioException, UserSideException try: @@ -134,6 +134,8 @@ class HTTPClient(object): raise HTTPClientError(str(e)) def fetch_json_data(self, method, path, **kwargs): + if method != "get": + cleanup_content_cache("http") cache_valid = kwargs.pop("cache_valid") if "cache_valid" in kwargs else None if not cache_valid: return self._parse_json_response(self.send_request(method, path, **kwargs)) diff --git a/platformio/clients/registry.py b/platformio/clients/registry.py index 3a45a48e..be25736b 100644 --- a/platformio/clients/registry.py +++ b/platformio/clients/registry.py @@ -23,6 +23,21 @@ class RegistryClient(HTTPClient): def __init__(self): super(RegistryClient, self).__init__(__registry_api__) + @staticmethod + def allowed_private_packages(): + private_permissions = set( + [ + "service.registry.publish-private-tool", + "service.registry.publish-private-platform", + "service.registry.publish-private-library", + ] + ) + info = AccountClient().get_account_info() or {} + for item in info.get("packages", []): + if set(item.keys()) & private_permissions: + return True + return False + def send_auth_request(self, *args, **kwargs): headers = kwargs.get("headers", {}) if "Authorization" not in headers: @@ -116,13 +131,24 @@ class RegistryClient(HTTPClient): params = dict(query=" ".join(search_query)) if page: params["page"] = int(page) - return self.fetch_json_data( - "get", "/v3/search", params=params, cache_valid="1h" + return ( + self.send_auth_request + if self.allowed_private_packages() + else self.fetch_json_data + )( + "get", + "/v3/search", + params=params, + cache_valid="1h", ) def get_package(self, type_, owner, name, version=None): try: - return self.fetch_json_data( + return ( + self.send_auth_request + if self.allowed_private_packages() + else self.fetch_json_data + )( "get", "/v3/packages/{owner}/{type}/{name}".format( type=type_, owner=owner.lower(), name=name.lower() diff --git a/platformio/commands/access.py b/platformio/commands/access.py index d9fb3970..74f48e2b 100644 --- a/platformio/commands/access.py +++ b/platformio/commands/access.py @@ -134,6 +134,14 @@ def access_list(owner, urn_type, json_output): table_data = [] table_data.append(("URN:", resource.get("urn"))) table_data.append(("Owner:", resource.get("owner"))) + table_data.append( + ( + "Access:", + click.style("Private", fg="red") + if resource.get("private", False) + else "Public", + ) + ) table_data.append( ( "Access level(s):", From 56848ece7a68aec3b2e2e2b9d4a53ffe92fab246 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 18 Dec 2021 13:45:51 +0200 Subject: [PATCH 04/53] Bump version to 5.2.5a2 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index 07baf97f..cbbb3a16 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a1") +VERSION = (5, 2, "5a2") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 63674d85e8a82ab918ac3418c1a677051db78ecb Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 18 Dec 2021 13:53:54 +0200 Subject: [PATCH 05/53] Ignore private packages if user not authorized --- platformio/clients/registry.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/platformio/clients/registry.py b/platformio/clients/registry.py index be25736b..f37d3b40 100644 --- a/platformio/clients/registry.py +++ b/platformio/clients/registry.py @@ -13,7 +13,7 @@ # limitations under the License. from platformio import __registry_api__, fs -from platformio.clients.account import AccountClient +from platformio.clients.account import AccountClient, AccountNotAuthorized from platformio.clients.http import HTTPClient, HTTPClientError # pylint: disable=too-many-arguments @@ -32,10 +32,13 @@ class RegistryClient(HTTPClient): "service.registry.publish-private-library", ] ) - info = AccountClient().get_account_info() or {} - for item in info.get("packages", []): - if set(item.keys()) & private_permissions: - return True + try: + info = AccountClient().get_account_info() or {} + for item in info.get("packages", []): + if set(item.keys()) & private_permissions: + return True + except AccountNotAuthorized: + pass return False def send_auth_request(self, *args, **kwargs): From a32997ceba5cc4c2c8bfa1596ed0ff66052e2bc8 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 18 Dec 2021 13:54:09 +0200 Subject: [PATCH 06/53] Bump version to 5.2.5a3 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index cbbb3a16..0d857226 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a2") +VERSION = (5, 2, "5a3") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 3e0b95e1e14fb2980ab9f1e9f90116f56f893698 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 18 Dec 2021 14:17:22 +0200 Subject: [PATCH 07/53] Fix tests --- platformio/package/manifest/parser.py | 5 ++--- tests/package/test_manifest.py | 10 ---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/platformio/package/manifest/parser.py b/platformio/package/manifest/parser.py index 47e9025d..556339a7 100644 --- a/platformio/package/manifest/parser.py +++ b/platformio/package/manifest/parser.py @@ -608,7 +608,6 @@ class LibraryPropertiesManifestParser(BaseManifestParser): return None def _parse_export(self): - result = {} include = None if self.remote_url: url_attrs = urlparse(self.remote_url) @@ -621,8 +620,8 @@ class LibraryPropertiesManifestParser(BaseManifestParser): or None ) if include: - result["include"] = [include] - return result + return dict(include=[include]) + return None @staticmethod def _parse_dependencies(raw): diff --git a/tests/package/test_manifest.py b/tests/package/test_manifest.py index 216adf5d..a07a035e 100644 --- a/tests/package/test_manifest.py +++ b/tests/package/test_manifest.py @@ -220,9 +220,6 @@ includes=Arduino.h, Arduino Space.hpp "description": "This is Arduino library", "sentence": "This is Arduino library", "frameworks": ["arduino"], - "export": { - "exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"] - }, "authors": [ {"name": "SomeAuthor", "email": "info@author.com"}, {"name": "Maintainer Author", "maintainer": True}, @@ -270,7 +267,6 @@ includes=Arduino.h, Arduino Space.hpp ), ).as_dict() assert data["export"] == { - "exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"], "include": ["libraries/TestPackage"], } assert data["repository"] == { @@ -465,9 +461,6 @@ depends=First Library (=2.0.0), Second Library (>=1.2.0), Third "frameworks": ["arduino"], "platforms": ["atmelavr", "atmelsam"], "version": "1.19.1", - "export": { - "exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"] - }, "authors": [ {"maintainer": True, "email": "olikraus@gmail.com", "name": "oliver"} ], @@ -538,9 +531,6 @@ includes=MozziGuts.h "platforms": ["*"], "frameworks": ["arduino"], "headers": ["MozziGuts.h"], - "export": { - "exclude": ["extras", "docs", "tests", "test", "*.doxyfile", "*.pdf"] - }, "authors": [ { "maintainer": True, From 6e03eff3038822cbe9c435a466476aeda8c7fd5b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 20 Dec 2021 19:05:12 +0200 Subject: [PATCH 08/53] Handle base AccountError --- platformio/clients/registry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio/clients/registry.py b/platformio/clients/registry.py index f37d3b40..7eeb8211 100644 --- a/platformio/clients/registry.py +++ b/platformio/clients/registry.py @@ -13,7 +13,7 @@ # limitations under the License. from platformio import __registry_api__, fs -from platformio.clients.account import AccountClient, AccountNotAuthorized +from platformio.clients.account import AccountClient, AccountError from platformio.clients.http import HTTPClient, HTTPClientError # pylint: disable=too-many-arguments @@ -37,7 +37,7 @@ class RegistryClient(HTTPClient): for item in info.get("packages", []): if set(item.keys()) & private_permissions: return True - except AccountNotAuthorized: + except AccountError: pass return False From b7f685ed628e54b80a2a45a776c96ee0c924b14b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 20 Dec 2021 19:27:56 +0200 Subject: [PATCH 09/53] Fix a bug with expired account session --- platformio/clients/account.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platformio/clients/account.py b/platformio/clients/account.py index c7c2c6fa..69c860f8 100644 --- a/platformio/clients/account.py +++ b/platformio/clients/account.py @@ -16,7 +16,7 @@ import os import time from platformio import __accounts_api__, app -from platformio.clients.http import HTTPClient +from platformio.clients.http import HTTPClient, HTTPClientError from platformio.exception import PlatformioException @@ -69,6 +69,12 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods kwargs["headers"] = headers return self.fetch_json_data(*args, **kwargs) + def fetch_json_data(self, *args, **kwargs): + try: + return super(AccountClient, self).fetch_json_data(*args, **kwargs) + except HTTPClientError as exc: + raise AccountError(str(HTTPClientError)) from exc + def login(self, username, password): try: self.fetch_authentication_token() From f6e9e152531b6a370c52eb3ae0c516ebd6135b84 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 20 Dec 2021 19:28:28 +0200 Subject: [PATCH 10/53] Bump version to 5.2.5a4 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index 0d857226..c377a38c 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a3") +VERSION = (5, 2, "5a4") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 69aff392053abf71e6a512255ca7163596af0c62 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 20 Dec 2021 20:57:18 +0200 Subject: [PATCH 11/53] Warn about package publishing time --- platformio/commands/package.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platformio/commands/package.py b/platformio/commands/package.py index 8ce79dd5..3e3bdaa6 100644 --- a/platformio/commands/package.py +++ b/platformio/commands/package.py @@ -191,6 +191,12 @@ def package_publish( # pylint: disable=too-many-arguments, too-many-locals abort=True, ) + click.secho( + "The package publishing may take some time depending " + "on your Internet connection and the package size.", + fg="yellow", + ) + click.echo("Publishing...") response = RegistryClient().publish_package( owner, type_, archive_path, released_at, private, notify ) From c9efe24959e051a29c3076a0156af761d315ea72 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 22 Dec 2021 22:36:32 +0200 Subject: [PATCH 12/53] Switch to the new registry --- README.rst | 68 ++++--------------------------------- docs | 2 +- platformio/platform/_run.py | 2 +- 3 files changed, 8 insertions(+), 64 deletions(-) diff --git a/README.rst b/README.rst index ae40bcdf..54a8279f 100644 --- a/README.rst +++ b/README.rst @@ -17,11 +17,12 @@ PlatformIO Core :target: https://pypi.python.org/pypi/platformio/ :alt: License .. image:: https://img.shields.io/badge/PlatformIO-Labs-orange.svg - :alt: Community Labs + :alt: PlatformIO Labs :target: https://piolabs.com/?utm_source=github&utm_medium=core -**Quick Links:** `Web `_ | +**Quick Links:** `Homepage `_ | `PlatformIO IDE `_ | +`Registry `_ | `Project Examples `__ | `Docs `_ | `Donate `_ | @@ -70,66 +71,9 @@ Solutions Registry -------- -* `Libraries `_ -* `Development Platforms `_ -* `Frameworks `_ -* `Embedded Boards `_ - -Development Platforms ---------------------- - -* `Aceinna IMU `_ -* `ASR Microelectronics ASR605x `_ -* `Atmel AVR `_ -* `Atmel SAM `_ -* `Espressif 32 `_ -* `Espressif 8266 `_ -* `Freescale Kinetis `_ -* `Infineon XMC `_ -* `Intel ARC32 `_ -* `Intel MCS-51 (8051) `_ -* `Kendryte K210 `_ -* `Lattice iCE40 `_ -* `Maxim 32 `_ -* `Microchip PIC32 `_ -* `Nordic nRF51 `_ -* `Nordic nRF52 `_ -* `Nuclei `_ -* `NXP LPC `_ -* `RISC-V `_ -* `RISC-V GAP `_ -* `Shakti `_ -* `Silicon Labs EFM32 `_ -* `ST STM32 `_ -* `ST STM8 `_ -* `Teensy `_ -* `TI MSP430 `_ -* `TI Tiva `_ -* `WIZNet W7500 `_ - -Frameworks ----------- - -* `Arduino `_ -* `CMSIS `_ -* `ESP-IDF `_ -* `ESP8266 Non-OS SDK `_ -* `ESP8266 RTOS SDK `_ -* `Freedom E SDK `_ -* `GigaDevice GD32V SDK `_ -* `Kendryte Standalone SDK `_ -* `Kendryte FreeRTOS SDK `_ -* `libOpenCM3 `_ -* `Mbed `_ -* `Nuclei SDK `_ -* `PULP OS `_ -* `Pumbaa `_ -* `Shakti SDK `_ -* `Simba `_ -* `SPL `_ -* `STM32Cube `_ -* `WiringPi `_ -* `Zephyr `_ +* `Libraries `_ +* `Development Platforms `_ +* `Development Tools `_ Contributing ------------ diff --git a/docs b/docs index ba3fca21..e8b27db4 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit ba3fca21eab09226c194f0a23463b3c253d2e069 +Subproject commit e8b27db402f17cda8b3a8c5bf9e4535d0ad9621a diff --git a/platformio/platform/_run.py b/platformio/platform/_run.py index bd9b687f..b82475b7 100644 --- a/platformio/platform/_run.py +++ b/platformio/platform/_run.py @@ -189,7 +189,7 @@ class PlatformRunMixin(object): filename=filename, filename_styled=click.style(filename, fg="cyan"), link=click.style( - "https://platformio.org/lib/search?query=header:%s" + "https://registry.platformio.org/search?q=header:%s" % quote(filename, safe=""), fg="blue", ), From 55e852392501e353ade899f56dae2b061f610920 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 24 Dec 2021 15:04:54 +0200 Subject: [PATCH 13/53] Improve docs for "dependencies" field of library.json --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index e8b27db4..4be19c60 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit e8b27db402f17cda8b3a8c5bf9e4535d0ad9621a +Subproject commit 4be19c60c91430ad171fc060ce953c1d1b2a5a5d From 1ee9f183cc4d94d56f1592a4aa13d0c468dc4938 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 24 Dec 2021 18:14:18 +0200 Subject: [PATCH 14/53] Fix test --- tests/package/test_manager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/package/test_manager.py b/tests/package/test_manager.py index 01bad3df..c82d3c68 100644 --- a/tests/package/test_manager.py +++ b/tests/package/test_manager.py @@ -437,10 +437,10 @@ def test_update_with_metadata(isolated_pio_core, tmpdir_factory): lm = LibraryPackageManager(str(storage_dir)) # test non SemVer in registry - pkg = lm.install("RadioHead @ <1.90", silent=True) + pkg = lm.install("adafruit/Adafruit NeoPixel @ <1.9", silent=True) outdated = lm.outdated(pkg) - assert str(outdated.current) == "1.89.0" - assert outdated.latest > semantic_version.Version("1.100.0") + assert str(outdated.current) == "1.8.7" + assert outdated.latest > semantic_version.Version("1.10.0") pkg = lm.install("ArduinoJson @ 5.10.1", silent=True) # tesy latest From 84a0a6a4184d75500a8bcbea009afe529e7ab937 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 24 Dec 2021 18:14:29 +0200 Subject: [PATCH 15/53] Update deps --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 766a1b87..2dbc6392 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ minimal_requirements = [ ] if not PY2: - minimal_requirements.append("zeroconf==0.37.*") + minimal_requirements.append("zeroconf==0.38.*") home_requirements = [ "aiofiles==0.8.*", From 5748bf954966eb4d6f179e49e950813cff77287e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 29 Dec 2021 15:03:43 +0200 Subject: [PATCH 16/53] Extend packing filters --- platformio/package/pack.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/platformio/package/pack.py b/platformio/package/pack.py index df5b23c1..84d835ed 100644 --- a/platformio/package/pack.py +++ b/platformio/package/pack.py @@ -47,6 +47,7 @@ class PackagePacker(object): ".cache", "**/.cache", "**/__pycache__", + "**/*.pyc", # VCS ".git/", ".hg/", @@ -54,7 +55,8 @@ class PackagePacker(object): ] EXCLUDE_EXTRA = [ # Tests - "tests?", + "test", + "tests", # Docs "doc", "docs", @@ -64,10 +66,15 @@ class PackagePacker(object): "html", "media", "**/*.[pP][dD][fF]", - "**/*.[dD][oO][cC]?", - "**/*.[pP][pP][tT]?", + "**/*.[dD][oO][cC]", + "**/*.[dD][oO][cC][xX]", + "**/*.[pP][pP][tT]", + "**/*.[pP][pP][tT][xX]", + "**/*.[xX][lL][sS]", + "**/*.[xX][lL][sS][xX]", "**/*.[dD][oO][xX]", - "**/*.[hH][tT][mM]?", + "**/*.[hH][tT][mM]", + "**/*.[hH][tT][mM][lL]", "**/*.[tT][eE][xX]", "**/*.[jJ][sS]", "**/*.[cC][sS][sS]", @@ -83,6 +90,7 @@ class PackagePacker(object): "**/*.[mM][pP][34]", "**/*.[pP][sS][dD]", "**/*.[wW][aA][wW]", + "**/*.sqlite", ] EXCLUDE_LIBRARY_EXTRA = [ "assets", From f3c7d71b3bca2764470a870dca8b0a07c0e2e218 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 2 Jan 2022 19:46:52 +0200 Subject: [PATCH 17/53] Sync docs --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index 4be19c60..1b50a61f 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 4be19c60c91430ad171fc060ce953c1d1b2a5a5d +Subproject commit 1b50a61f325b8a3f957e13c38bed5eb4349ee106 From 6081f9ff1b421c14635971b730a7aa42b6ed2842 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 2 Jan 2022 23:08:12 +0200 Subject: [PATCH 18/53] Switch to the universal Twisted --- platformio/package/manager/core.py | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/platformio/package/manager/core.py b/platformio/package/manager/core.py index fe479c74..50b7e34e 100644 --- a/platformio/package/manager/core.py +++ b/platformio/package/manager/core.py @@ -212,7 +212,7 @@ def build_contrib_pysite_package(target_dir, with_metadata=True): def get_contrib_pysite_deps(): - twisted_version = "20.3.0" + twisted_version = "21.7.0" result = [ # twisted[tls], see setup.py for %twisted_version% "twisted == %s" % twisted_version, @@ -221,21 +221,6 @@ def get_contrib_pysite_deps(): "pyopenssl >= 16.0.0, <= 21.0.0", "service_identity >= 18.1.0, <= 21.1.0", ] - - sys_type = util.get_systype() - py_version = "%d%d" % (sys.version_info.major, sys.version_info.minor) - if "windows" in sys_type: - result.append("pypiwin32 == 223") - # workaround for twisted wheels - twisted_wheel = ( - "https://download.lfd.uci.edu/pythonlibs/x2tqcw5k/Twisted-" - "%s-cp%s-cp%s-win%s.whl" - % ( - twisted_version, - py_version, - py_version, - "_amd64" if "amd64" in sys_type else "32", - ) - ) - result[0] = twisted_wheel + if "windows" in util.get_systype(): + result.append("pywin32 != 226") return result From c56dfda83324701f7a679a41766065a8f31d90ec Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 2 Jan 2022 23:08:21 +0200 Subject: [PATCH 19/53] Minor fixes --- platformio/clients/account.py | 2 +- pytest.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio/clients/account.py b/platformio/clients/account.py index 69c860f8..f3558c00 100644 --- a/platformio/clients/account.py +++ b/platformio/clients/account.py @@ -73,7 +73,7 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods try: return super(AccountClient, self).fetch_json_data(*args, **kwargs) except HTTPClientError as exc: - raise AccountError(str(HTTPClientError)) from exc + raise AccountError(exc) from exc def login(self, username, password): try: diff --git a/pytest.ini b/pytest.ini index 03c86580..57763ca7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,4 +2,4 @@ filterwarnings = error # Marshmallow - ignore:The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives:DeprecationWarning \ No newline at end of file + ignore:distutils Version classes are deprecated. Use packaging.version instead. \ No newline at end of file From a5a224ac6f8e0e89f20f1fc36552a5651ae995fd Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 3 Jan 2022 13:05:53 +0200 Subject: [PATCH 20/53] Sync docs --- docs | 2 +- pytest.ini | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs b/docs index 1b50a61f..ab1e44c0 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 1b50a61f325b8a3f957e13c38bed5eb4349ee106 +Subproject commit ab1e44c06099f7c61316555bd28b451214bc5c0a diff --git a/pytest.ini b/pytest.ini index 57763ca7..b3dbaa57 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,4 +2,5 @@ filterwarnings = error # Marshmallow - ignore:distutils Version classes are deprecated. Use packaging.version instead. \ No newline at end of file + ignore:distutils Version classes are deprecated. Use packaging.version instead. + ignore:The distutils package is deprecated and slated for removal in Python \ No newline at end of file From 73ddf80fc10fcf07597935d81c25a6d18ad57a93 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 14:45:14 +0200 Subject: [PATCH 21/53] Refactor authentication part for clients --- platformio/clients/account.py | 125 +++++++++++++++++++-------------- platformio/clients/http.py | 15 ++++ platformio/clients/registry.py | 47 +++++-------- 3 files changed, 107 insertions(+), 80 deletions(-) diff --git a/platformio/clients/account.py b/platformio/clients/account.py index f3558c00..60349934 100644 --- a/platformio/clients/account.py +++ b/platformio/clients/account.py @@ -61,20 +61,34 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods del account[key] app.set_state_item("account", account) - def send_auth_request(self, *args, **kwargs): - headers = kwargs.get("headers", {}) - if "Authorization" not in headers: - token = self.fetch_authentication_token() - headers["Authorization"] = "Bearer %s" % token - kwargs["headers"] = headers - return self.fetch_json_data(*args, **kwargs) - def fetch_json_data(self, *args, **kwargs): try: return super(AccountClient, self).fetch_json_data(*args, **kwargs) except HTTPClientError as exc: raise AccountError(exc) from exc + def fetch_authentication_token(self): + if os.environ.get("PLATFORMIO_AUTH_TOKEN"): + return os.environ.get("PLATFORMIO_AUTH_TOKEN") + auth = app.get_state_item("account", {}).get("auth", {}) + if auth.get("access_token") and auth.get("access_token_expire"): + if auth.get("access_token_expire") > time.time(): + return auth.get("access_token") + if auth.get("refresh_token"): + try: + data = self.fetch_json_data( + "post", + "/v1/login", + headers={ + "Authorization": "Bearer %s" % auth.get("refresh_token") + }, + ) + app.set_state_item("account", data) + return data.get("auth").get("access_token") + except AccountError: + self.delete_local_session() + raise AccountNotAuthorized() + def login(self, username, password): try: self.fetch_authentication_token() @@ -125,10 +139,11 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods return True def change_password(self, old_password, new_password): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/password", data={"old_password": old_password, "new_password": new_password}, + x_with_authorization=True, ) def registration( @@ -156,10 +171,11 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods ) def auth_token(self, password, regenerate): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/token", data={"password": password, "regenerate": 1 if regenerate else 0}, + x_with_authorization=True, ).get("auth_token") def forgot_password(self, username): @@ -170,18 +186,20 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods ) def get_profile(self): - return self.send_auth_request( + return self.fetch_json_data( "get", "/v1/profile", + x_with_authorization=True, ) def update_profile(self, profile, current_password): profile["current_password"] = current_password self.delete_local_state("summary") - response = self.send_auth_request( + response = self.fetch_json_data( "put", "/v1/profile", data=profile, + x_with_authorization=True, ) return response @@ -199,9 +217,10 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods "username": account.get("username"), } } - result = self.send_auth_request( + result = self.fetch_json_data( "get", "/v1/summary", + x_with_authorization=True, ) account["summary"] = dict( profile=result.get("profile"), @@ -217,119 +236,121 @@ class AccountClient(HTTPClient): # pylint:disable=too-many-public-methods return self.get_account_info(offline=True).get("profile").get("username") def destroy_account(self): - return self.send_auth_request("delete", "/v1/account") + return self.fetch_json_data( + "delete", + "/v1/account", + x_with_authorization=True, + ) def create_org(self, orgname, email, displayname): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/orgs", data={"orgname": orgname, "email": email, "displayname": displayname}, + x_with_authorization=True, ) def get_org(self, orgname): - return self.send_auth_request("get", "/v1/orgs/%s" % orgname) + return self.fetch_json_data( + "get", + "/v1/orgs/%s" % orgname, + x_with_authorization=True, + ) def list_orgs(self): - return self.send_auth_request( + return self.fetch_json_data( "get", "/v1/orgs", + x_with_authorization=True, ) def update_org(self, orgname, data): - return self.send_auth_request( - "put", "/v1/orgs/%s" % orgname, data={k: v for k, v in data.items() if v} + return self.fetch_json_data( + "put", + "/v1/orgs/%s" % orgname, + data={k: v for k, v in data.items() if v}, + x_with_authorization=True, ) def destroy_org(self, orgname): - return self.send_auth_request( + return self.fetch_json_data( "delete", "/v1/orgs/%s" % orgname, + x_with_authorization=True, ) def add_org_owner(self, orgname, username): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/orgs/%s/owners" % orgname, data={"username": username}, + x_with_authorization=True, ) def list_org_owners(self, orgname): - return self.send_auth_request( + return self.fetch_json_data( "get", "/v1/orgs/%s/owners" % orgname, + x_with_authorization=True, ) def remove_org_owner(self, orgname, username): - return self.send_auth_request( + return self.fetch_json_data( "delete", "/v1/orgs/%s/owners" % orgname, data={"username": username}, + x_with_authorization=True, ) def create_team(self, orgname, teamname, description): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/orgs/%s/teams" % orgname, data={"name": teamname, "description": description}, + x_with_authorization=True, ) def destroy_team(self, orgname, teamname): - return self.send_auth_request( + return self.fetch_json_data( "delete", "/v1/orgs/%s/teams/%s" % (orgname, teamname), + x_with_authorization=True, ) def get_team(self, orgname, teamname): - return self.send_auth_request( + return self.fetch_json_data( "get", "/v1/orgs/%s/teams/%s" % (orgname, teamname), + x_with_authorization=True, ) def list_teams(self, orgname): - return self.send_auth_request( + return self.fetch_json_data( "get", "/v1/orgs/%s/teams" % orgname, + x_with_authorization=True, ) def update_team(self, orgname, teamname, data): - return self.send_auth_request( + return self.fetch_json_data( "put", "/v1/orgs/%s/teams/%s" % (orgname, teamname), data={k: v for k, v in data.items() if v}, + x_with_authorization=True, ) def add_team_member(self, orgname, teamname, username): - return self.send_auth_request( + return self.fetch_json_data( "post", "/v1/orgs/%s/teams/%s/members" % (orgname, teamname), data={"username": username}, + x_with_authorization=True, ) def remove_team_member(self, orgname, teamname, username): - return self.send_auth_request( + return self.fetch_json_data( "delete", "/v1/orgs/%s/teams/%s/members" % (orgname, teamname), data={"username": username}, + x_with_authorization=True, ) - - def fetch_authentication_token(self): - if os.environ.get("PLATFORMIO_AUTH_TOKEN"): - return os.environ.get("PLATFORMIO_AUTH_TOKEN") - auth = app.get_state_item("account", {}).get("auth", {}) - if auth.get("access_token") and auth.get("access_token_expire"): - if auth.get("access_token_expire") > time.time(): - return auth.get("access_token") - if auth.get("refresh_token"): - try: - data = self.fetch_json_data( - "post", - "/v1/login", - headers={ - "Authorization": "Bearer %s" % auth.get("refresh_token") - }, - ) - app.set_state_item("account", data) - return data.get("auth").get("access_token") - except AccountError: - self.delete_local_session() - raise AccountNotAuthorized() diff --git a/platformio/clients/http.py b/platformio/clients/http.py index a2b92776..259d4934 100644 --- a/platformio/clients/http.py +++ b/platformio/clients/http.py @@ -117,6 +117,21 @@ class HTTPClient(object): # check Internet before and resolve issue with 60 seconds timeout ensure_internet_on(raise_exception=True) + headers = kwargs.get("headers", {}) + with_authorization = ( + kwargs.pop("x_with_authorization") + if "x_with_authorization" in kwargs + else False + ) + if with_authorization and "Authorization" not in headers: + # pylint: disable=import-outside-toplevel + from platformio.clients.account import AccountClient + + headers["Authorization"] = ( + "Bearer %s" % AccountClient().fetch_authentication_token() + ) + kwargs["headers"] = headers + # set default timeout if "timeout" not in kwargs: kwargs["timeout"] = __default_requests_timeout__ diff --git a/platformio/clients/registry.py b/platformio/clients/registry.py index 7eeb8211..f344d1d1 100644 --- a/platformio/clients/registry.py +++ b/platformio/clients/registry.py @@ -41,19 +41,11 @@ class RegistryClient(HTTPClient): pass return False - def send_auth_request(self, *args, **kwargs): - headers = kwargs.get("headers", {}) - if "Authorization" not in headers: - token = AccountClient().fetch_authentication_token() - headers["Authorization"] = "Bearer %s" % token - kwargs["headers"] = headers - return self.fetch_json_data(*args, **kwargs) - def publish_package( # pylint: disable=redefined-builtin self, owner, type, archive_path, released_at=None, private=False, notify=True ): with open(archive_path, "rb") as fp: - return self.send_auth_request( + return self.fetch_json_data( "post", "/v3/packages/%s/%s" % (owner, type), params={ @@ -68,6 +60,7 @@ class RegistryClient(HTTPClient): ), }, data=fp, + x_with_authorization=True, ) def unpublish_package( # pylint: disable=redefined-builtin @@ -76,36 +69,40 @@ class RegistryClient(HTTPClient): path = "/v3/packages/%s/%s/%s" % (owner, type, name) if version: path += "/" + version - return self.send_auth_request( - "delete", - path, - params={"undo": 1 if undo else 0}, + return self.fetch_json_data( + "delete", path, params={"undo": 1 if undo else 0}, x_with_authorization=True ) def update_resource(self, urn, private): - return self.send_auth_request( + return self.fetch_json_data( "put", "/v3/resources/%s" % urn, data={"private": int(private)}, + x_with_authorization=True, ) def grant_access_for_resource(self, urn, client, level): - return self.send_auth_request( + return self.fetch_json_data( "put", "/v3/resources/%s/access" % urn, data={"client": client, "level": level}, + x_with_authorization=True, ) def revoke_access_from_resource(self, urn, client): - return self.send_auth_request( + return self.fetch_json_data( "delete", "/v3/resources/%s/access" % urn, data={"client": client}, + x_with_authorization=True, ) def list_resources(self, owner): - return self.send_auth_request( - "get", "/v3/resources", params={"owner": owner} if owner else None + return self.fetch_json_data( + "get", + "/v3/resources", + params={"owner": owner} if owner else None, + x_with_authorization=True, ) def list_packages(self, query=None, filters=None, page=None): @@ -134,30 +131,24 @@ class RegistryClient(HTTPClient): params = dict(query=" ".join(search_query)) if page: params["page"] = int(page) - return ( - self.send_auth_request - if self.allowed_private_packages() - else self.fetch_json_data - )( + return self.fetch_json_data( "get", "/v3/search", params=params, cache_valid="1h", + x_with_authorization=self.allowed_private_packages(), ) def get_package(self, type_, owner, name, version=None): try: - return ( - self.send_auth_request - if self.allowed_private_packages() - else self.fetch_json_data - )( + return self.fetch_json_data( "get", "/v3/packages/{owner}/{type}/{name}".format( type=type_, owner=owner.lower(), name=name.lower() ), params=dict(version=version) if version else None, cache_valid="1h", + x_with_authorization=self.allowed_private_packages(), ) except HTTPClientError as e: if e.response is not None and e.response.status_code == 404: From fb046c43eac85eafc2ebaa2296f1afa24328a9d9 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 14:46:51 +0200 Subject: [PATCH 22/53] Require authorization for package downloading --- platformio/package/manager/_registry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/platformio/package/manager/_registry.py b/platformio/package/manager/_registry.py index 80d42889..e488b5b3 100644 --- a/platformio/package/manager/_registry.py +++ b/platformio/package/manager/_registry.py @@ -54,6 +54,7 @@ class RegistryFileMirrorIterator(object): params=dict(bypass=",".join(self._visited_mirrors)) if self._visited_mirrors else None, + x_with_authorization=RegistryClient.allowed_private_packages(), ) stop_conditions = [ response.status_code not in (302, 307), From 7cdcc9099b39f567d40706c75b18bf970989a62b Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 14:53:34 +0200 Subject: [PATCH 23/53] Escape custom request arguments --- platformio/clients/http.py | 2 +- platformio/clients/registry.py | 4 ++-- platformio/commands/platform.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platformio/clients/http.py b/platformio/clients/http.py index 259d4934..7c20ba50 100644 --- a/platformio/clients/http.py +++ b/platformio/clients/http.py @@ -151,7 +151,7 @@ class HTTPClient(object): def fetch_json_data(self, method, path, **kwargs): if method != "get": cleanup_content_cache("http") - cache_valid = kwargs.pop("cache_valid") if "cache_valid" in kwargs else None + cache_valid = kwargs.pop("x_cache_valid") if "x_cache_valid" in kwargs else None if not cache_valid: return self._parse_json_response(self.send_request(method, path, **kwargs)) cache_key = ContentCache.key_from_args( diff --git a/platformio/clients/registry.py b/platformio/clients/registry.py index f344d1d1..aba734ff 100644 --- a/platformio/clients/registry.py +++ b/platformio/clients/registry.py @@ -135,7 +135,7 @@ class RegistryClient(HTTPClient): "get", "/v3/search", params=params, - cache_valid="1h", + x_cache_valid="1h", x_with_authorization=self.allowed_private_packages(), ) @@ -147,7 +147,7 @@ class RegistryClient(HTTPClient): type=type_, owner=owner.lower(), name=name.lower() ), params=dict(version=version) if version else None, - cache_valid="1h", + x_cache_valid="1h", x_with_authorization=self.allowed_private_packages(), ) except HTTPClientError as e: diff --git a/platformio/commands/platform.py b/platformio/commands/platform.py index 84945e39..287f5760 100644 --- a/platformio/commands/platform.py +++ b/platformio/commands/platform.py @@ -61,7 +61,7 @@ def platform_frameworks(query, json_output): regclient = PlatformPackageManager().get_registry_client_instance() frameworks = [] for framework in regclient.fetch_json_data( - "get", "/v2/frameworks", cache_valid="1d" + "get", "/v2/frameworks", x_cache_valid="1d" ): if query == "all": query = "" @@ -354,7 +354,7 @@ def _print_platforms(platforms): def _get_registry_platforms(): regclient = PlatformPackageManager().get_registry_client_instance() - return regclient.fetch_json_data("get", "/v2/platforms", cache_valid="1d") + return regclient.fetch_json_data("get", "/v2/platforms", x_cache_valid="1d") def _get_platform_data(*args, **kwargs): From 254507c3a326c60c18dff3e8c6a40d18d90a1413 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 15:02:48 +0200 Subject: [PATCH 24/53] Escape custom request arguments --- platformio/commands/lib/command.py | 10 ++++++---- platformio/package/manager/platform.py | 2 +- tests/test_misc.py | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/platformio/commands/lib/command.py b/platformio/commands/lib/command.py index 7b6c7bb7..d29b7388 100644 --- a/platformio/commands/lib/command.py +++ b/platformio/commands/lib/command.py @@ -355,7 +355,7 @@ def lib_search(query, json_output, page, noninteractive, **filters): "get", "/v2/lib/search", params=dict(query=" ".join(query), page=page), - cache_valid="1d", + x_cache_valid="1d", ) if json_output: @@ -408,7 +408,7 @@ def lib_search(query, json_output, page, noninteractive, **filters): "get", "/v2/lib/search", params=dict(query=" ".join(query), page=int(result["page"]) + 1), - cache_valid="1d", + x_cache_valid="1d", ) @@ -440,7 +440,9 @@ def lib_show(library, json_output): lm = LibraryPackageManager() lib_id = lm.reveal_registry_package_id(library, silent=json_output) regclient = lm.get_registry_client_instance() - lib = regclient.fetch_json_data("get", "/v2/lib/info/%d" % lib_id, cache_valid="1h") + lib = regclient.fetch_json_data( + "get", "/v2/lib/info/%d" % lib_id, x_cache_valid="1h" + ) if json_output: return click.echo(json.dumps(lib)) @@ -535,7 +537,7 @@ def lib_register(config_url): # pylint: disable=unused-argument @click.option("--json-output", is_flag=True) def lib_stats(json_output): regclient = LibraryPackageManager().get_registry_client_instance() - result = regclient.fetch_json_data("get", "/v2/lib/stats", cache_valid="1h") + result = regclient.fetch_json_data("get", "/v2/lib/stats", x_cache_valid="1h") if json_output: return click.echo(json.dumps(result)) diff --git a/platformio/package/manager/platform.py b/platformio/package/manager/platform.py index ecce6a22..0b438018 100644 --- a/platformio/package/manager/platform.py +++ b/platformio/package/manager/platform.py @@ -140,7 +140,7 @@ class PlatformPackageManager(BasePackageManager): # pylint: disable=too-many-an def get_registered_boards(self): return self.get_registry_client_instance().fetch_json_data( - "get", "/v2/boards", cache_valid="1d" + "get", "/v2/boards", x_cache_valid="1d" ) def get_all_boards(self): diff --git a/tests/test_misc.py b/tests/test_misc.py index 36574ee4..9b8fc5d4 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -42,7 +42,7 @@ def test_api_internet_offline(without_internet, isolated_pio_core): def test_api_cache(monkeypatch, isolated_pio_core): regclient = RegistryClient() - api_kwargs = {"method": "get", "path": "/v2/stats", "cache_valid": "10s"} + api_kwargs = {"method": "get", "path": "/v2/stats", "x_cache_valid": "10s"} result = regclient.fetch_json_data(**api_kwargs) assert result and "boards" in result monkeypatch.setattr(http, "_internet_on", lambda: False) From 38cc493eb7d0aa79d283f57685336c5c3ea96c1e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 17:17:51 +0200 Subject: [PATCH 25/53] Minor improvements --- platformio/builder/tools/piolib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platformio/builder/tools/piolib.py b/platformio/builder/tools/piolib.py index bd6f35f4..3b57c1e7 100644 --- a/platformio/builder/tools/piolib.py +++ b/platformio/builder/tools/piolib.py @@ -32,7 +32,7 @@ from SCons.Script import DefaultEnvironment # pylint: disable=import-error from platformio import exception, fs, util from platformio.builder.tools import platformio as piotool -from platformio.clients.http import InternetIsOffline +from platformio.clients.http import HTTPClientError, InternetIsOffline from platformio.compat import IS_WINDOWS, hashlib_encode_data, string_types from platformio.package.exception import UnknownPackageError from platformio.package.manager.library import LibraryPackageManager @@ -939,7 +939,7 @@ class ProjectAsLibBuilder(LibBuilderBase): try: lm.install(spec) did_install = True - except (UnknownPackageError, InternetIsOffline) as e: + except (HTTPClientError, UnknownPackageError, InternetIsOffline) as e: click.secho("Warning! %s" % e, fg="yellow") # reset cache From 0630ec55035ce0fb905d955db95e3793c1819958 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 4 Jan 2022 17:18:14 +0200 Subject: [PATCH 26/53] Bump version to 5.2.5a5 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index c377a38c..b9418dd0 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a4") +VERSION = (5, 2, "5a5") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 111eb55a9fe94f940e82e2067243cb5af898a229 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 5 Jan 2022 15:00:41 +0200 Subject: [PATCH 27/53] Docs: Update "platformio.ini" examples --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index ab1e44c0..3a7407ad 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit ab1e44c06099f7c61316555bd28b451214bc5c0a +Subproject commit 3a7407adaaab363cc05ea301c4647cdcefa53507 From 5658e7f71888a29a268b5c71af6019377b048b9b Mon Sep 17 00:00:00 2001 From: Alexey Vazhnov Date: Sat, 8 Jan 2022 15:59:47 +0300 Subject: [PATCH 28/53] =?UTF-8?q?=5Finternet=5Fon:=20try=20IPv4,=20if=20no?= =?UTF-8?q?t=20acceptable=20=E2=80=94=20try=20IPv6=20(#4151)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * _internet_on: try IPv4, if not acceptable — try IPv6 * _internet_on: replace IPv4 `socket.socket` + IPv6 `socket.socket` with one universal `socket.create_connection` --- platformio/clients/http.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platformio/clients/http.py b/platformio/clients/http.py index 7c20ba50..3cf247b4 100644 --- a/platformio/clients/http.py +++ b/platformio/clients/http.py @@ -196,8 +196,9 @@ def _internet_on(): continue requests.get("http://%s" % host, allow_redirects=False, timeout=timeout) return True - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, 80)) + # try to resolve `host` for both AF_INET and AF_INET6, and then try to connect + # to all possible addresses (IPv4 and IPv6) in turn until a connection succeeds: + s = socket.create_connection((host, 80)) s.close() return True except: # pylint: disable=bare-except From 9e078ff4d7a0192a14f80768a2578ca18a959094 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 8 Jan 2022 15:00:35 +0200 Subject: [PATCH 29/53] Sync docs --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index 3a7407ad..c41beac9 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 3a7407adaaab363cc05ea301c4647cdcefa53507 +Subproject commit c41beac9185aa3a0435272fcdff9d49829b608b9 From fc907c568da17311db3fa0d8518ecd53e5c35ae0 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 8 Jan 2022 15:08:39 +0200 Subject: [PATCH 30/53] Improved checking of available Internet connection for IPv6-only workstations // Issue #4151 --- HISTORY.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.rst b/HISTORY.rst index 9fbfda97..759e36dc 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -12,6 +12,7 @@ PlatformIO Core 5 ~~~~~~~~~~~~~~~~~~ - Improved support for private packages in `PlatformIO Registry `__ +- Improved checking of available Internet connection for IPv6-only workstations (`pull #4151 `_) 5.2.4 (2021-12-15) ~~~~~~~~~~~~~~~~~~ From 72561027854b517fd304df4d6172a34fb790ba2e Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Sun, 9 Jan 2022 05:58:39 -0600 Subject: [PATCH 31/53] Unix line-endings for extensions.json (#4153) --- .../tpls/vscode/.vscode/extensions.json.tpl | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/platformio/project/tpls/vscode/.vscode/extensions.json.tpl b/platformio/project/tpls/vscode/.vscode/extensions.json.tpl index 1b2dfdd9..126d45d8 100644 --- a/platformio/project/tpls/vscode/.vscode/extensions.json.tpl +++ b/platformio/project/tpls/vscode/.vscode/extensions.json.tpl @@ -1,23 +1,23 @@ -% import json -% import os -% import re -% -% recommendations = set(["platformio.platformio-ide"]) -% previous_json = os.path.join(project_dir, ".vscode", "extensions.json") -% if os.path.isfile(previous_json): -% fp = open(previous_json) -% contents = re.sub(r"^\s*//.*$", "", fp.read(), flags=re.M).strip() -% fp.close() -% if contents: -% recommendations |= set(json.loads(contents).get("recommendations", [])) -% end -% end -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ -% for i, item in enumerate(sorted(recommendations)): - "{{ item }}"{{ ("," if (i + 1) < len(recommendations) else "") }} -% end - ] -} +% import json +% import os +% import re +% +% recommendations = set(["platformio.platformio-ide"]) +% previous_json = os.path.join(project_dir, ".vscode", "extensions.json") +% if os.path.isfile(previous_json): +% fp = open(previous_json) +% contents = re.sub(r"^\s*//.*$", "", fp.read(), flags=re.M).strip() +% fp.close() +% if contents: +% recommendations |= set(json.loads(contents).get("recommendations", [])) +% end +% end +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ +% for i, item in enumerate(sorted(recommendations)): + "{{ item }}"{{ ("," if (i + 1) < len(recommendations) else "") }} +% end + ] +} From c78bb1f572f4b4a3d8ddbe907c729c445524f586 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 11 Jan 2022 14:11:32 +0200 Subject: [PATCH 32/53] Docs: Remove icons from navbar --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index c41beac9..e4e01d4e 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit c41beac9185aa3a0435272fcdff9d49829b608b9 +Subproject commit e4e01d4e3c598d9456ef556b56f0b4903feda1ca From 93bbe8f2a3cad426f36ae3daa2c75cb2bb1c5090 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 15 Jan 2022 15:00:55 +0200 Subject: [PATCH 33/53] Update deps --- docs | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs b/docs index e4e01d4e..3567dbd9 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit e4e01d4e3c598d9456ef556b56f0b4903feda1ca +Subproject commit 3567dbd90929ff9b42f63295920c945fb145f924 diff --git a/setup.py b/setup.py index 2dbc6392..f86fd248 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ home_requirements = [ "aiofiles==0.8.*", "ajsonrpc==1.*", "starlette==0.17.*", - "uvicorn==0.16.*", + "uvicorn==0.17.*", "wsproto==1.0.*", ] From e8c0b8504ab9dad03cdc41dfbac66d51a99e79f6 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 15 Jan 2022 22:27:30 +0200 Subject: [PATCH 34/53] Ignore annoying "ms-vscode.cpptools-extension-pack" for VSCode and C/C++ files --- platformio/project/tpls/vscode/.vscode/extensions.json.tpl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platformio/project/tpls/vscode/.vscode/extensions.json.tpl b/platformio/project/tpls/vscode/.vscode/extensions.json.tpl index 126d45d8..26412ae7 100644 --- a/platformio/project/tpls/vscode/.vscode/extensions.json.tpl +++ b/platformio/project/tpls/vscode/.vscode/extensions.json.tpl @@ -19,5 +19,8 @@ % for i, item in enumerate(sorted(recommendations)): "{{ item }}"{{ ("," if (i + 1) < len(recommendations) else "") }} % end + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" ] } From 57c92e877c7fe122716ea8d67e884be5aa524114 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 19 Jan 2022 16:53:31 +0200 Subject: [PATCH 35/53] Respect disabling debugging server from platformio.ini --- HISTORY.rst | 1 + platformio/debug/config/base.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 759e36dc..6992470d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -13,6 +13,7 @@ PlatformIO Core 5 - Improved support for private packages in `PlatformIO Registry `__ - Improved checking of available Internet connection for IPv6-only workstations (`pull #4151 `_) +- Respect disabling debugging server from "platformio.ini" passing an empty value to the `debug_server `__ option 5.2.4 (2021-12-15) ~~~~~~~~~~~~~~~~~~ diff --git a/platformio/debug/config/base.py b/platformio/debug/config/base.py index bcafa8fd..db7ddfba 100644 --- a/platformio/debug/config/base.py +++ b/platformio/debug/config/base.py @@ -153,7 +153,14 @@ class DebugConfigBase: # pylint: disable=too-many-instance-attributes raise DebugInvalidOptionsError("Could not load a build configuration") def _configure_server(self): + # user disabled server in platformio.ini + if "debug_server" in self.env_options and not self.env_options.get( + "debug_server" + ): + return None + result = None + # specific server per a system if isinstance(self.tool_settings.get("server", {}), list): for item in self.tool_settings["server"][:]: From 698189406087d7f8d596419d35e70bfa1e5f3bad Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 19 Jan 2022 17:16:23 +0200 Subject: [PATCH 36/53] Minor updates --- platformio/app.py | 19 ++----------------- platformio/maintenance.py | 14 ++++---------- 2 files changed, 6 insertions(+), 27 deletions(-) diff --git a/platformio/app.py b/platformio/app.py index 374f4014..6c152c17 100644 --- a/platformio/app.py +++ b/platformio/app.py @@ -253,29 +253,14 @@ def is_disabled_progressbar(): def get_cid(): - # pylint: disable=import-outside-toplevel - from platformio.clients.http import fetch_remote_content - cid = get_state_item("cid") if cid: return cid uid = None - if os.getenv("C9_UID"): - uid = os.getenv("C9_UID") + if os.getenv("GITHUB_USER"): + uid = os.getenv("GITHUB_USER") elif os.getenv("GITPOD_GIT_USER_NAME"): uid = os.getenv("GITPOD_GIT_USER_NAME") - elif os.getenv("CHE_API", os.getenv("CHE_API_ENDPOINT")): - try: - uid = json.loads( - fetch_remote_content( - "{api}/user?token={token}".format( - api=os.getenv("CHE_API", os.getenv("CHE_API_ENDPOINT")), - token=os.getenv("USER_TOKEN"), - ) - ) - ).get("id") - except: # pylint: disable=bare-except - pass if not uid: uid = uuid.getnode() cid = uuid.UUID(bytes=hashlib.md5(hashlib_encode_data(uid)).digest()) diff --git a/platformio/maintenance.py b/platformio/maintenance.py index ba370032..82aa4a0f 100644 --- a/platformio/maintenance.py +++ b/platformio/maintenance.py @@ -35,7 +35,6 @@ from platformio.package.manager.tool import ToolPackageManager from platformio.package.meta import PackageSpec from platformio.package.version import pepver_to_semver from platformio.platform.factory import PlatformFactory -from platformio.proc import is_container def on_platformio_start(ctx, force, caller): @@ -78,17 +77,12 @@ def set_caller(caller=None): caller = caller or os.getenv("PLATFORMIO_CALLER") if caller: return app.set_session_var("caller_id", caller) - if os.getenv("VSCODE_PID") or os.getenv("VSCODE_NLS_CONFIG"): + if os.getenv("CODESPACES"): + caller = "codespaces" + elif os.getenv("VSCODE_PID") or os.getenv("VSCODE_NLS_CONFIG"): caller = "vscode" - elif os.getenv("GITPOD_INSTANCE_ID") or os.getenv("GITPOD_WORKSPACE_URL"): + elif os.getenv("GITPOD_WORKSPACE_ID") or os.getenv("GITPOD_WORKSPACE_URL"): caller = "gitpod" - elif is_container(): - if os.getenv("C9_UID"): - caller = "C9" - elif os.getenv("USER") == "cabox": - caller = "CA" - elif os.getenv("CHE_API", os.getenv("CHE_API_ENDPOINT")): - caller = "Che" return app.set_session_var("caller_id", caller) From 4e1ec1215a113f80e747033b7678d0b7943c7950 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 19 Jan 2022 17:16:44 +0200 Subject: [PATCH 37/53] Bump version to 5.2.5a6 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index b9418dd0..4ab2c8a0 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a5") +VERSION = (5, 2, "5a6") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" From 8c66352994c234f64dbcdae5deeb09b56e28e0f3 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Thu, 20 Jan 2022 11:19:30 +0100 Subject: [PATCH 38/53] Fixed wrong path (#4158) * Fixed wrong path On linux, "Documents" doesn't have to be the right folder. It depends on the language selected when installing the operating system. * Refactor code * Update HISTORY.rst Co-authored-by: Ivan Kravets --- HISTORY.rst | 3 ++- platformio/project/helpers.py | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index 6992470d..e463857e 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -12,7 +12,8 @@ PlatformIO Core 5 ~~~~~~~~~~~~~~~~~~ - Improved support for private packages in `PlatformIO Registry `__ -- Improved checking of available Internet connection for IPv6-only workstations (`pull #4151 `_) +- Improved checking of available Internet connection for IPv6-only workstations (`pull #4151 `_) +- Better detecting of default PlatformIO project directory on Linux OS (`pull #4158 `_) - Respect disabling debugging server from "platformio.ini" passing an empty value to the `debug_server `__ option 5.2.4 (2021-12-15) diff --git a/platformio/project/helpers.py b/platformio/project/helpers.py index 2736cae8..73945185 100644 --- a/platformio/project/helpers.py +++ b/platformio/project/helpers.py @@ -14,12 +14,13 @@ import json import os +import subprocess from hashlib import sha1 from click.testing import CliRunner from platformio import __version__, exception, fs -from platformio.compat import IS_WINDOWS, hashlib_encode_data +from platformio.compat import IS_MACOS, IS_WINDOWS, hashlib_encode_data from platformio.project.config import ProjectConfig @@ -75,7 +76,13 @@ def get_default_projects_dir(): ctypes.windll.shell32.SHGetFolderPathW(None, 5, None, 0, buf) docs_dir = buf.value except: # pylint: disable=bare-except - pass + if not IS_MACOS: + try: + docs_dir = subprocess.check_output( + ["xdg-user-dir", "DOCUMENTS"] + ).decode("utf-8") + except FileNotFoundError: # command not found + pass return os.path.join(docs_dir, "PlatformIO", "Projects") From 681b91a6a4992a0b19942d90c60665c833559a0f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sun, 23 Jan 2022 14:17:22 +0200 Subject: [PATCH 39/53] Update deps --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f86fd248..1b1cb8f8 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ if not PY2: home_requirements = [ "aiofiles==0.8.*", "ajsonrpc==1.*", - "starlette==0.17.*", + "starlette==0.18.*", "uvicorn==0.17.*", "wsproto==1.0.*", ] From d5373a62f4ef75c261237c4485c73498d9f075e6 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Fri, 28 Jan 2022 14:24:25 +0200 Subject: [PATCH 40/53] Docs: Sync dev-platforms --- docs | 2 +- examples | 2 +- scripts/docspregen.py | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs b/docs index 3567dbd9..920ac922 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 3567dbd90929ff9b42f63295920c945fb145f924 +Subproject commit 920ac922028b140ebe9a91b1c8e07c7d838c5069 diff --git a/examples b/examples index d722c23d..fe5a503b 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit d722c23da47639dcc92e3c9b997df61b9ee1bfe3 +Subproject commit fe5a503b442ee7346a03ac86374657769a5ae1a4 diff --git a/scripts/docspregen.py b/scripts/docspregen.py index c4291cc0..0e945d18 100644 --- a/scripts/docspregen.py +++ b/scripts/docspregen.py @@ -531,12 +531,13 @@ def generate_framework(type_, data, rst_dir=None): lines.append(" :ref:`projectconf_env_framework` = ``%s``" % type_) lines.append("") lines.append(data["description"]) - lines.append( - """ + if data["url"]: + lines.append( + """ For more detailed information please visit `vendor site <%s>`_. """ - % campaign_url(data["url"]) - ) + % campaign_url(data["url"]) + ) lines.append( """ From ebbac6b4830dad2118a522bfccf267ad67def0cd Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Feb 2022 15:00:47 +0200 Subject: [PATCH 41/53] Use "black" profile --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 5d38aa33..0ee9c0ec 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,7 @@ envlist = py36,py37,py38,py39 [isort] -line_length = 88 +profile = black known_third_party=OpenSSL, SCons, jsonrpc, twisted, zope [testenv] From 0064d4b2c59885f0b0a324384e5a61d8af211c2f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Feb 2022 15:01:58 +0200 Subject: [PATCH 42/53] Docs: remove deprecated links to "boards" page --- docs | 2 +- scripts/docspregen.py | 60 +++++++++++++++++++------------------------ 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/docs b/docs index 920ac922..f4169a1c 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 920ac922028b140ebe9a91b1c8e07c7d838c5069 +Subproject commit f4169a1cebcf94694e96b2b9085118ada7fd21ec diff --git a/scripts/docspregen.py b/scripts/docspregen.py index 0e945d18..113bfa93 100644 --- a/scripts/docspregen.py +++ b/scripts/docspregen.py @@ -42,12 +42,12 @@ RST_COPYRIGHT = """.. Copyright (c) 2014-present PlatformIO `_ + * You can list pre-configured boards by :ref:`cmd_boards` command * For more detailed ``board`` information please scroll the tables below by horizontally. """ @@ -500,21 +499,20 @@ Boards def update_platform_docs(): - for manifest in PLATFORM_MANIFESTS: - name = manifest["name"] - platforms_dir = join(DOCS_ROOT_DIR, "platforms") - rst_path = join(platforms_dir, "%s.rst" % name) + platforms_dir = join(DOCS_ROOT_DIR, "platforms") + for pkg in PlatformPackageManager().get_installed(): + rst_path = join(platforms_dir, "%s.rst" % pkg.metadata.name) with open(rst_path, "w") as f: - f.write(generate_platform(name, platforms_dir)) + f.write(generate_platform(pkg.metadata.name, platforms_dir)) -def generate_framework(type_, data, rst_dir=None): +def generate_framework(type_, framework, rst_dir=None): print("Processing framework: %s" % type_) compatible_platforms = [ - m - for m in PLATFORM_MANIFESTS - if is_compat_platform_and_framework(m["name"], type_) + pkg + for pkg in PlatformPackageManager().get_installed() + if is_compat_platform_and_framework(pkg.metadata.name, type_) ] compatible_boards = [board for board in BOARDS if type_ in board["frameworks"]] @@ -524,19 +522,19 @@ def generate_framework(type_, data, rst_dir=None): lines.append(".. _framework_%s:" % type_) lines.append("") - lines.append(data["title"]) - lines.append("=" * len(data["title"])) + lines.append(framework["title"]) + lines.append("=" * len(framework["title"])) lines.append("") lines.append(":Configuration:") lines.append(" :ref:`projectconf_env_framework` = ``%s``" % type_) lines.append("") - lines.append(data["description"]) - if data["url"]: + lines.append(framework["description"]) + if framework["url"]: lines.append( """ For more detailed information please visit `vendor site <%s>`_. """ - % campaign_url(data["url"]) + % campaign_url(framework["url"]) ) lines.append( @@ -571,13 +569,13 @@ Examples -------- """ ) - for manifest in compatible_platforms: - p = PlatformFactory.new(manifest["name"]) + for pkg in compatible_platforms: + p = PlatformFactory.new(pkg) lines.append( "* `%s for %s <%s>`_" % ( - data["title"], - manifest["title"], + framework["title"], + p.title, campaign_url("%s/tree/master/examples" % p.repository_url[:-4]), ) ) @@ -585,7 +583,7 @@ Examples # Platforms lines.extend( generate_platforms_contents( - [manifest["name"] for manifest in compatible_platforms] + [pkg.metadata.name for pkg in compatible_platforms] ) ) @@ -604,8 +602,7 @@ Boards ------ .. note:: - * You can list pre-configured boards by :ref:`cmd_boards` command or - `PlatformIO Boards Explorer `_ + * You can list pre-configured boards by :ref:`cmd_boards` command * For more detailed ``board`` information please scroll the tables below by horizontally. """ ) @@ -640,11 +637,10 @@ def update_boards(): """ Rapid Embedded Development, Continuous and IDE integration in a few steps with PlatformIO thanks to built-in project generator for the most -popular embedded boards and IDE. +popular embedded boards and IDEs. .. note:: - * You can list pre-configured boards by :ref:`cmd_boards` command or - `PlatformIO Boards Explorer `_ + * You can list pre-configured boards by :ref:`cmd_boards` command * For more detailed ``board`` information please scroll tables below by horizontal. """ ) @@ -677,8 +673,6 @@ popular embedded boards and IDE. # individual board page for data in BOARDS: - # if data['id'] != "m5stack-core-esp32": - # continue rst_path = join( DOCS_ROOT_DIR, "boards", data["platform"], "%s.rst" % data["id"] ) @@ -1018,8 +1012,8 @@ def update_project_examples(): embedded = [] desktop = [] - for manifest in PLATFORM_MANIFESTS: - p = PlatformFactory.new(manifest["name"]) + for pkg in PlatformPackageManager().get_installed(): + p = PlatformFactory.new(pkg) github_url = p.repository_url[:-4] # Platform README @@ -1054,7 +1048,7 @@ def update_project_examples(): framework_examples_md_lines[framework["name"]] = [] lines = [] lines.append("- [%s](%s)" % (p.title, github_url)) - lines.extend(" %s" % l for l in examples_md_lines) + lines.extend(" %s" % line for line in examples_md_lines) lines.append("") framework_examples_md_lines[framework["name"]].extend(lines) From 251a2c9fa483d57a321af2cd57bf2b234c72cc46 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Feb 2022 15:38:15 +0200 Subject: [PATCH 43/53] Docs: link packages with the registry --- docs | 2 +- scripts/docspregen.py | 149 +++++++++++++++++++++++------------------- 2 files changed, 82 insertions(+), 69 deletions(-) diff --git a/docs b/docs index f4169a1c..06c82f4d 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit f4169a1cebcf94694e96b2b9085118ada7fd21ec +Subproject commit 06c82f4d4e422e1d472961d4b4d477cb6fffb5ea diff --git a/scripts/docspregen.py b/scripts/docspregen.py index 113bfa93..c2e9564f 100644 --- a/scripts/docspregen.py +++ b/scripts/docspregen.py @@ -13,7 +13,6 @@ # limitations under the License. import os -from os.path import dirname, isdir, isfile, join, realpath from sys import exit as sys_exit from sys import path @@ -42,17 +41,19 @@ RST_COPYRIGHT = """.. Copyright (c) 2014-present PlatformIO `__ - {description}""".format( - name=name, - url=campaign_url(API_PACKAGES[name]["url"]), - description=API_PACKAGES[name]["description"], - ) + name=package["name"], + url=reg_package_url( + "tool", package["owner"]["username"], package["name"] + ), + description=package["description"], ) + ) if is_embedded: lines.append( @@ -339,7 +339,11 @@ Packages def generate_platform(name, rst_dir): print("Processing platform: %s" % name) - compatible_boards = [board for board in BOARDS if name == board["platform"]] + compatible_boards = [ + board + for board in PlatformPackageManager().get_installed_boards() + if name == board["platform"] + ] lines = [] @@ -374,7 +378,7 @@ For more detailed information please visit `vendor site <%s>`_.""" # # Extra # - if isfile(join(rst_dir, "%s_extra.rst" % name)): + if os.path.isfile(os.path.join(rst_dir, "%s_extra.rst" % name)): lines.append(".. include:: %s_extra.rst" % p.name) # @@ -389,11 +393,11 @@ Examples are listed from `%s development platform repository <%s>`_: """ % (p.title, campaign_url("%s/tree/master/examples" % github_url)) ) - examples_dir = join(p.get_dir(), "examples") - if isdir(examples_dir): + examples_dir = os.path.join(p.get_dir(), "examples") + if os.path.isdir(examples_dir): for eitem in os.listdir(examples_dir): - example_dir = join(examples_dir, eitem) - if not isdir(example_dir) or not os.listdir(example_dir): + example_dir = os.path.join(examples_dir, eitem) + if not os.path.isdir(example_dir) or not os.listdir(example_dir): continue url = "%s/tree/master/examples/%s" % (github_url, eitem) lines.append("* `%s <%s>`_" % (eitem, campaign_url(url))) @@ -407,7 +411,7 @@ Examples are listed from `%s development platform repository <%s>`_: compatible_boards, skip_board_columns=["Platform"], extra_rst="%s_debug.rst" % name - if isfile(join(rst_dir, "%s_debug.rst" % name)) + if os.path.isfile(os.path.join(rst_dir, "%s_debug.rst" % name)) else None, ) ) @@ -455,7 +459,7 @@ Upstream # # Packages # - _packages_content = generate_packages(name, p.packages.keys(), p.is_embedded()) + _packages_content = generate_packages(name, p.packages, p.is_embedded()) if _packages_content: lines.append(_packages_content) @@ -499,9 +503,9 @@ Boards def update_platform_docs(): - platforms_dir = join(DOCS_ROOT_DIR, "platforms") + platforms_dir = os.path.join(DOCS_ROOT_DIR, "platforms") for pkg in PlatformPackageManager().get_installed(): - rst_path = join(platforms_dir, "%s.rst" % pkg.metadata.name) + rst_path = os.path.join(platforms_dir, "%s.rst" % pkg.metadata.name) with open(rst_path, "w") as f: f.write(generate_platform(pkg.metadata.name, platforms_dir)) @@ -514,7 +518,11 @@ def generate_framework(type_, framework, rst_dir=None): for pkg in PlatformPackageManager().get_installed() if is_compat_platform_and_framework(pkg.metadata.name, type_) ] - compatible_boards = [board for board in BOARDS if type_ in board["frameworks"]] + compatible_boards = [ + board + for board in PlatformPackageManager().get_installed_boards() + if type_ in board["frameworks"] + ] lines = [] @@ -545,7 +553,7 @@ For more detailed information please visit `vendor site <%s>`_. ) # Extra - if isfile(join(rst_dir, "%s_extra.rst" % type_)): + if os.path.isfile(os.path.join(rst_dir, "%s_extra.rst" % type_)): lines.append(".. include:: %s_extra.rst" % type_) # @@ -556,7 +564,7 @@ For more detailed information please visit `vendor site <%s>`_. generate_debug_contents( compatible_boards, extra_rst="%s_debug.rst" % type_ - if isfile(join(rst_dir, "%s_debug.rst" % type_)) + if os.path.isfile(os.path.join(rst_dir, "%s_debug.rst" % type_)) else None, ) ) @@ -616,8 +624,8 @@ Boards def update_framework_docs(): for framework in API_FRAMEWORKS: name = framework["name"] - frameworks_dir = join(DOCS_ROOT_DIR, "frameworks") - rst_path = join(frameworks_dir, "%s.rst" % name) + frameworks_dir = os.path.join(DOCS_ROOT_DIR, "frameworks") + rst_path = os.path.join(frameworks_dir, "%s.rst" % name) with open(rst_path, "w") as f: f.write(generate_framework(name, framework, frameworks_dir)) @@ -646,7 +654,8 @@ popular embedded boards and IDEs. ) platforms = {} - for data in BOARDS: + installed_boards = PlatformPackageManager().get_installed_boards() + for data in installed_boards: platform = data["platform"] if platform in platforms: platforms[platform].append(data) @@ -667,17 +676,17 @@ popular embedded boards and IDEs. lines.append(" %s/%s" % (platform, board["id"])) lines.append("") - emboards_rst = join(DOCS_ROOT_DIR, "boards", "index.rst") + emboards_rst = os.path.join(DOCS_ROOT_DIR, "boards", "index.rst") with open(emboards_rst, "w") as f: f.write("\n".join(lines)) # individual board page - for data in BOARDS: - rst_path = join( + for data in installed_boards: + rst_path = os.path.join( DOCS_ROOT_DIR, "boards", data["platform"], "%s.rst" % data["id"] ) - if not isdir(dirname(rst_path)): - os.makedirs(dirname(rst_path)) + if not os.path.isdir(os.path.dirname(rst_path)): + os.makedirs(os.path.dirname(rst_path)) update_embedded_board(rst_path, data) @@ -887,7 +896,7 @@ def update_debugging(): vendors = {} platforms = [] frameworks = [] - for data in BOARDS: + for data in PlatformPackageManager().get_installed_boards(): if not data.get("debug"): continue @@ -932,7 +941,7 @@ Boards # save with open( - join(fs.get_source_dir(), "..", "docs", "plus", "debugging.rst"), "r+" + os.path.join(fs.get_source_dir(), "..", "docs", "plus", "debugging.rst"), "r+" ) as fp: content = fp.read() fp.seek(0) @@ -943,8 +952,8 @@ Boards # Debug tools for tool, platforms in tool_to_platforms.items(): - tool_path = join(DOCS_ROOT_DIR, "plus", "debug-tools", "%s.rst" % tool) - if not isfile(tool_path): + tool_path = os.path.join(DOCS_ROOT_DIR, "plus", "debug-tools", "%s.rst" % tool) + if not os.path.isfile(tool_path): click.secho("Unknown debug tool `%s`" % tool, fg="red") continue platforms = sorted(set(platforms)) @@ -969,7 +978,11 @@ Boards ) lines.extend( generate_boards_table( - [b for b in BOARDS if b["id"] in tool_to_boards[tool]], + [ + b + for b in PlatformPackageManager().get_installed_boards() + if b["id"] in tool_to_boards[tool] + ], skip_columns=None, ) ) @@ -1007,7 +1020,7 @@ def update_project_examples(): {examples} """ - project_examples_dir = join(fs.get_source_dir(), "..", "examples") + project_examples_dir = os.path.join(fs.get_source_dir(), "..", "examples") framework_examples_md_lines = {} embedded = [] desktop = [] @@ -1017,20 +1030,20 @@ def update_project_examples(): github_url = p.repository_url[:-4] # Platform README - platform_examples_dir = join(p.get_dir(), "examples") + platform_examples_dir = os.path.join(p.get_dir(), "examples") examples_md_lines = [] - if isdir(platform_examples_dir): + if os.path.isdir(platform_examples_dir): for item in sorted(os.listdir(platform_examples_dir)): - example_dir = join(platform_examples_dir, item) - if not isdir(example_dir) or not os.listdir(example_dir): + example_dir = os.path.join(platform_examples_dir, item) + if not os.path.isdir(example_dir) or not os.listdir(example_dir): continue url = "%s/tree/master/examples/%s" % (github_url, item) examples_md_lines.append("* [%s](%s)" % (item, url)) - readme_dir = join(project_examples_dir, "platforms", p.name) - if not isdir(readme_dir): + readme_dir = os.path.join(project_examples_dir, "platforms", p.name) + if not os.path.isdir(readme_dir): os.makedirs(readme_dir) - with open(join(readme_dir, "README.md"), "w") as fp: + with open(os.path.join(readme_dir, "README.md"), "w") as fp: fp.write( platform_readme_tpl.format( name=p.name, @@ -1064,10 +1077,10 @@ def update_project_examples(): for framework in API_FRAMEWORKS: if framework["name"] not in framework_examples_md_lines: continue - readme_dir = join(project_examples_dir, "frameworks", framework["name"]) - if not isdir(readme_dir): + readme_dir = os.path.join(project_examples_dir, "frameworks", framework["name"]) + if not os.path.isdir(readme_dir): os.makedirs(readme_dir) - with open(join(readme_dir, "README.md"), "w") as fp: + with open(os.path.join(readme_dir, "README.md"), "w") as fp: fp.write( framework_readme_tpl.format( name=framework["name"], @@ -1084,7 +1097,7 @@ def update_project_examples(): ) frameworks.append("* [%s](%s)" % (framework["title"], url)) - with open(join(project_examples_dir, "README.md"), "w") as fp: + with open(os.path.join(project_examples_dir, "README.md"), "w") as fp: fp.write( """# PlatformIO Project Examples From ac2b358f87c3c70c59ae3b731cf6864df2d098b2 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 1 Feb 2022 21:56:53 +0200 Subject: [PATCH 44/53] Docs: generate docs from the registry --- docs | 2 +- examples | 2 +- scripts/docspregen.py | 126 +++++++++++++++++++++++++++--------------- 3 files changed, 84 insertions(+), 46 deletions(-) diff --git a/docs b/docs index 06c82f4d..4de1b83a 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 06c82f4d4e422e1d472961d4b4d477cb6fffb5ea +Subproject commit 4de1b83a71aeb6870ceb2ecd8ec4c2e38939f361 diff --git a/examples b/examples index fe5a503b..dcafbd19 160000 --- a/examples +++ b/examples @@ -1 +1 @@ -Subproject commit fe5a503b442ee7346a03ac86374657769a5ae1a4 +Subproject commit dcafbd192ee19fdb310136fa62335a3ce13ec517 diff --git a/scripts/docspregen.py b/scripts/docspregen.py index c2e9564f..d05cef91 100644 --- a/scripts/docspregen.py +++ b/scripts/docspregen.py @@ -12,17 +12,19 @@ # See the License for the specific language governing permissions and # limitations under the License. +import functools +import json import os -from sys import exit as sys_exit -from sys import path +import sys +import tempfile -path.append("..") +sys.path.append("..") -import click +import click # noqa: E402 -from platformio import fs, util -from platformio.package.manager.platform import PlatformPackageManager -from platformio.platform.factory import PlatformFactory +from platformio import fs, util # noqa: E402 +from platformio.package.manager.platform import PlatformPackageManager # noqa: E402 +from platformio.platform.factory import PlatformFactory # noqa: E402 try: from urlparse import ParseResult, urlparse, urlunparse @@ -45,7 +47,6 @@ DOCS_ROOT_DIR = os.path.realpath( os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "docs") ) REGCLIENT = PlatformPackageManager().get_registry_client_instance() -API_FRAMEWORKS = REGCLIENT.fetch_json_data("get", "/v2/frameworks") def reg_package_url(type_, owner, name): @@ -69,6 +70,43 @@ def campaign_url(url, source="platformio.org", medium="docs"): ) +def install_platforms(): + print("Installing platforms...") + page = 1 + pm = PlatformPackageManager() + while True: + result = REGCLIENT.list_packages(filters=dict(types=["platform"]), page=page) + for item in result["items"]: + spec = "%s/%s" % (item["owner"]["username"], item["name"]) + skip_conds = [ + item["owner"]["username"] != "platformio", + item["tier"] == "community", + ] + if all(skip_conds): + click.secho("Skip community platform: %s" % spec, fg="yellow") + continue + pm.install(spec, skip_default_package=True) + page += 1 + if not result["items"] or result["page"] * result["limit"] >= result["total"]: + break + + +@functools.cache +def get_frameworks(): + items = {} + for pkg in PlatformPackageManager().get_installed(): + p = PlatformFactory.new(pkg) + for name, options in (p.frameworks or {}).items(): + if name in items or not set(options.keys()).issuperset( + set(["title", "description"]) + ): + continue + items[name] = dict( + name=name, title=options["title"], description=options["description"] + ) + return sorted(items.values(), key=lambda item: item["name"]) + + def is_compat_platform_and_framework(platform, framework): p = PlatformFactory.new(platform) return framework in (p.frameworks or {}).keys() @@ -147,7 +185,7 @@ Frameworks - Description""" ) known = set() - for framework in API_FRAMEWORKS: + for framework in get_frameworks(): known.add(framework["name"]) if framework["name"] not in frameworks: continue @@ -336,7 +374,8 @@ Packages return "\n".join(lines) -def generate_platform(name, rst_dir): +def generate_platform(pkg, rst_dir): + name = pkg.metadata.name print("Processing platform: %s" % name) compatible_boards = [ @@ -346,11 +385,12 @@ def generate_platform(name, rst_dir): ] lines = [] - lines.append(RST_COPYRIGHT) + p = PlatformFactory.new(name) assert p.repository_url.endswith(".git") github_url = p.repository_url[:-4] + registry_url = reg_package_url("platform", pkg.metadata.spec.owner, name) lines.append(".. _platform_%s:" % p.name) lines.append("") @@ -358,6 +398,8 @@ def generate_platform(name, rst_dir): lines.append(p.title) lines.append("=" * len(p.title)) lines.append("") + lines.append(":Registry:") + lines.append(" `%s <%s>`__" % (registry_url, registry_url)) lines.append(":Configuration:") lines.append(" :ref:`projectconf_env_platform` = ``%s``" % p.name) lines.append("") @@ -467,7 +509,7 @@ Upstream # Frameworks # compatible_frameworks = [] - for framework in API_FRAMEWORKS: + for framework in get_frameworks(): if is_compat_platform_and_framework(name, framework["name"]): compatible_frameworks.append(framework["name"]) lines.extend(generate_frameworks_contents(compatible_frameworks)) @@ -507,7 +549,7 @@ def update_platform_docs(): for pkg in PlatformPackageManager().get_installed(): rst_path = os.path.join(platforms_dir, "%s.rst" % pkg.metadata.name) with open(rst_path, "w") as f: - f.write(generate_platform(pkg.metadata.name, platforms_dir)) + f.write(generate_platform(pkg, platforms_dir)) def generate_framework(type_, framework, rst_dir=None): @@ -537,14 +579,6 @@ def generate_framework(type_, framework, rst_dir=None): lines.append(" :ref:`projectconf_env_framework` = ``%s``" % type_) lines.append("") lines.append(framework["description"]) - if framework["url"]: - lines.append( - """ -For more detailed information please visit `vendor site <%s>`_. -""" - % campaign_url(framework["url"]) - ) - lines.append( """ .. contents:: Contents @@ -556,20 +590,14 @@ For more detailed information please visit `vendor site <%s>`_. if os.path.isfile(os.path.join(rst_dir, "%s_extra.rst" % type_)): lines.append(".. include:: %s_extra.rst" % type_) - # - # Debugging - # - if compatible_boards: + if compatible_platforms: + # Platforms lines.extend( - generate_debug_contents( - compatible_boards, - extra_rst="%s_debug.rst" % type_ - if os.path.isfile(os.path.join(rst_dir, "%s_debug.rst" % type_)) - else None, + generate_platforms_contents( + [pkg.metadata.name for pkg in compatible_platforms] ) ) - if compatible_platforms: # examples lines.append( """ @@ -588,10 +616,16 @@ Examples ) ) - # Platforms + # + # Debugging + # + if compatible_boards: lines.extend( - generate_platforms_contents( - [pkg.metadata.name for pkg in compatible_platforms] + generate_debug_contents( + compatible_boards, + extra_rst="%s_debug.rst" % type_ + if os.path.isfile(os.path.join(rst_dir, "%s_debug.rst" % type_)) + else None, ) ) @@ -622,9 +656,9 @@ Boards def update_framework_docs(): - for framework in API_FRAMEWORKS: + frameworks_dir = os.path.join(DOCS_ROOT_DIR, "frameworks") + for framework in get_frameworks(): name = framework["name"] - frameworks_dir = os.path.join(DOCS_ROOT_DIR, "frameworks") rst_path = os.path.join(frameworks_dir, "%s.rst" % name) with open(rst_path, "w") as f: f.write(generate_framework(name, framework, frameworks_dir)) @@ -1054,7 +1088,7 @@ def update_project_examples(): ) # Framework README - for framework in API_FRAMEWORKS: + for framework in get_frameworks(): if not is_compat_platform_and_framework(p.name, framework["name"]): continue if framework["name"] not in framework_examples_md_lines: @@ -1074,7 +1108,7 @@ def update_project_examples(): # Frameworks frameworks = [] - for framework in API_FRAMEWORKS: + for framework in get_frameworks(): if framework["name"] not in framework_examples_md_lines: continue readme_dir = os.path.join(project_examples_dir, "frameworks", framework["name"]) @@ -1125,12 +1159,16 @@ def update_project_examples(): def main(): - update_platform_docs() - update_framework_docs() - update_boards() - update_debugging() - update_project_examples() + with tempfile.TemporaryDirectory() as tmp_dir: + print("Core directory: %s" % tmp_dir) + os.environ["PLATFORMIO_CORE_DIR"] = tmp_dir + install_platforms() + update_platform_docs() + update_framework_docs() + update_boards() + update_debugging() + update_project_examples() if __name__ == "__main__": - sys_exit(main()) + sys.exit(main()) From 2e0688db5fd2daa2c2d115e25de8c3f03f40358e Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 2 Feb 2022 12:42:31 +0200 Subject: [PATCH 45/53] Fix test --- tests/commands/test_ci.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/commands/test_ci.py b/tests/commands/test_ci.py index 95b31a8f..01ac9c37 100644 --- a/tests/commands/test_ci.py +++ b/tests/commands/test_ci.py @@ -119,6 +119,7 @@ def test_ci_keep_build_dir_nested_src_dirs( src_dir1 = tmpdir_factory.mktemp("src_1") src_dir1.join("src1.cpp").write( """ +#include void setup() {} """ ) @@ -126,6 +127,7 @@ void setup() {} src_dir2 = tmpdir_factory.mktemp("src_2") src_dir2.join("src2.cpp").write( """ +#include void loop() {} """ ) From f4c692eed23407b7134f0f3536ac38829d6e5430 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Wed, 2 Feb 2022 17:42:28 +0200 Subject: [PATCH 46/53] Bump PIO Home to 3.4.1 --- platformio/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/__init__.py b/platformio/__init__.py index 4ab2c8a0..a57d1159 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -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.4.0", + "contrib-piohome": "~3.4.1", "contrib-pysite": "~2.%d%d.0" % (sys.version_info.major, sys.version_info.minor), "tool-unity": "~1.20500.0", "tool-scons": "~4.40300.0", From 9b85ed86a9b4c8440e08abc8eac733a21b2c1949 Mon Sep 17 00:00:00 2001 From: Maciej Augustyniak Date: Sat, 5 Feb 2022 12:13:43 +0100 Subject: [PATCH 47/53] fix: Added udev rule for FireBeetle-ESP32. (#4168) --- scripts/99-platformio-udev.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/99-platformio-udev.rules b/scripts/99-platformio-udev.rules index 043ce11a..6fd87d00 100644 --- a/scripts/99-platformio-udev.rules +++ b/scripts/99-platformio-udev.rules @@ -70,6 +70,9 @@ ATTRS{idVendor}=="0451", ATTRS{idProduct}=="f432", MODE="0666", ENV{ID_MM_DEVICE #GD32V DFU Bootloader ATTRS{idVendor}=="28e9", ATTRS{idProduct}=="0189", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" +# FireBeetle-ESP32 +ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7522", MODE="0666", ENV{ID_MM_DEVICE_IGNORE}="1", ENV{ID_MM_PORT_IGNORE}="1" + # # Debuggers # From 1d72a96654ac29a252f52521da0687f325dee6ab Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Sat, 5 Feb 2022 20:00:37 +0200 Subject: [PATCH 48/53] Merge tag 'v5.2.5' into develop Bump version to 5.2.5 # Conflicts: # docs # platformio/__init__.py --- HISTORY.rst | 1 + setup.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/HISTORY.rst b/HISTORY.rst index e463857e..566842af 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -15,6 +15,7 @@ PlatformIO Core 5 - Improved checking of available Internet connection for IPv6-only workstations (`pull #4151 `_) - Better detecting of default PlatformIO project directory on Linux OS (`pull #4158 `_) - Respect disabling debugging server from "platformio.ini" passing an empty value to the `debug_server `__ option +- Fixed a "module 'asyncio' has no attribute 'run'" error when launching PIO Home using Python 3.6 (`issue #4169 `_) 5.2.4 (2021-12-15) ~~~~~~~~~~~~~~~~~~ diff --git a/setup.py b/setup.py index 1b1cb8f8..6b645300 100644 --- a/setup.py +++ b/setup.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys from setuptools import find_packages, setup from platformio import ( @@ -45,7 +46,7 @@ home_requirements = [ "aiofiles==0.8.*", "ajsonrpc==1.*", "starlette==0.18.*", - "uvicorn==0.17.*", + "uvicorn==%s" % ("0.17.*" if sys.version_info >= (3, 7) else "0.16.0"), "wsproto==1.0.*", ] From a4b414010d6d1a93d5698660c4944ca513136ed3 Mon Sep 17 00:00:00 2001 From: Kalle Bracht Date: Mon, 7 Feb 2022 12:45:56 +0100 Subject: [PATCH 49/53] Removing inconsistent dot at README.rst, HISTORY.rst and CONTRIBUTING.md (#4172) * Removing inconsistent dot at README list * Removing inconsistent dot at HISTORY file * Removing inconsistent dot at CONTRIBUTING file --- CONTRIBUTING.md | 4 ++-- HISTORY.rst | 2 +- README.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec53bebb..5f2f4188 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,7 +3,7 @@ Contributing To get started, sign the Contributor License Agreement. -1. Fork the repository on GitHub. +1. Fork the repository on GitHub 2. Clone repository `git clone --recursive https://github.com/YourGithubUsername/platformio-core.git` 3. Run `pip install tox` 4. Go to the root of project where is located `tox.ini` and run `tox -e py37` @@ -18,4 +18,4 @@ To get started, si 8. Run the tests `make test` 9. Build documentation `tox -e docs` (creates a directory _build under docs where you can find the html) 10. Commit changes to your forked repository -11. Submit a Pull Request on GitHub. +11. Submit a Pull Request on GitHub diff --git a/HISTORY.rst b/HISTORY.rst index 566842af..a4d41019 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -295,7 +295,7 @@ Please check `Migration guide from 4.x to 5.0 `__ command (`issue #3522 `_) - Show ignored project environments only in the verbose mode (`issue #3641 `_) - Do not escape compiler arguments in VSCode template on Windows - - Drop support for Python 2 and 3.5. + - Drop support for Python 2 and 3.5 .. _release_notes_4: diff --git a/README.rst b/README.rst index 54a8279f..061c0142 100644 --- a/README.rst +++ b/README.rst @@ -44,7 +44,7 @@ PlatformIO Core * Cross-platform IDE and Unified Debugger * Static Code Analyzer and Remote Unit Testing * Multi-platform and Multi-architecture Build System -* Firmware File Explorer and Memory Inspection. +* Firmware File Explorer and Memory Inspection Get Started ----------- From bb1e5902226303f9f449660927b43038c30b0f34 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Mon, 7 Feb 2022 13:46:47 +0200 Subject: [PATCH 50/53] Update SPDX License List to 3.16 --- platformio/package/manifest/schema.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio/package/manifest/schema.py b/platformio/package/manifest/schema.py index 60d0d60c..78bf43a7 100644 --- a/platformio/package/manifest/schema.py +++ b/platformio/package/manifest/schema.py @@ -259,7 +259,7 @@ class ManifestSchema(BaseSchema): @staticmethod @memoized(expire="1h") def load_spdx_licenses(): - version = "3.15" + version = "3.16" spdx_data_url = ( "https://raw.githubusercontent.com/spdx/license-list-data/" "v%s/json/licenses.json" % version From 27400f66a979dc623bea7f5a2fc20af47d6bc415 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 8 Feb 2022 17:21:13 +0200 Subject: [PATCH 51/53] Strip the path to userhome dir on Linux // Resolve #4173 Issue #4158 --- platformio/project/helpers.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platformio/project/helpers.py b/platformio/project/helpers.py index 73945185..2aab20b7 100644 --- a/platformio/project/helpers.py +++ b/platformio/project/helpers.py @@ -78,9 +78,11 @@ def get_default_projects_dir(): except: # pylint: disable=bare-except if not IS_MACOS: try: - docs_dir = subprocess.check_output( - ["xdg-user-dir", "DOCUMENTS"] - ).decode("utf-8") + docs_dir = ( + subprocess.check_output(["xdg-user-dir", "DOCUMENTS"]) + .decode("utf-8") + .strip() + ) except FileNotFoundError: # command not found pass return os.path.join(docs_dir, "PlatformIO", "Projects") From 8594012fa1b4b8d204da5e978571625886154af5 Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Tue, 8 Feb 2022 17:40:50 +0200 Subject: [PATCH 52/53] Update deps --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6b645300..02b947e0 100644 --- a/setup.py +++ b/setup.py @@ -29,13 +29,13 @@ from platformio.compat import PY2 minimal_requirements = [ "bottle==0.12.*", - "click>=8,<9,!=8.0.2", + "click>=8.0.3,<9", "colorama", "marshmallow%s" % (">=2,<3" if PY2 else ">=2,<4"), "pyelftools>=0.27,<1", "pyserial==3.*", "requests==2.*", - "semantic_version==2.8.*", + "semantic_version==2.9.*", "tabulate==0.8.*", ] From 100def76096a7ae49bc7f1c8e67d61306209644f Mon Sep 17 00:00:00 2001 From: Ivan Kravets Date: Thu, 10 Feb 2022 20:59:16 +0200 Subject: [PATCH 53/53] Bump version to 5.2.5 --- HISTORY.rst | 2 +- docs | 2 +- platformio/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/HISTORY.rst b/HISTORY.rst index a4d41019..c6cd902b 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -8,7 +8,7 @@ PlatformIO Core 5 **A professional collaborative platform for embedded development** -5.2.5 (2021-12-??) +5.2.5 (2022-02-10) ~~~~~~~~~~~~~~~~~~ - Improved support for private packages in `PlatformIO Registry `__ diff --git a/docs b/docs index 4de1b83a..bbf4d275 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 4de1b83a71aeb6870ceb2ecd8ec4c2e38939f361 +Subproject commit bbf4d27508f4fe600dfb5706641bdccf6b2a762e diff --git a/platformio/__init__.py b/platformio/__init__.py index a57d1159..0c9e9bd5 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (5, 2, "5a6") +VERSION = (5, 2, 5) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio"