Compare commits

...

53 Commits

Author SHA1 Message Date
3f3c8cabb8 Merge branch 'release/v5.0.4' 2020-12-30 13:23:11 +02:00
34e12e575b Bump version to 5.0.4 2020-12-30 13:23:04 +02:00
4c8c261ab4 Raise an exception when trying to pack a package from tar.gz on Windows // Resolve #3776 2020-12-28 20:12:53 +02:00
099bb3b9ff Sync dev-platforms: docs + examples 2020-12-28 13:51:34 +02:00
c623a6aacc Fixed an issue with package publishing on Windows when Unix permissions are not preserved // Resolve // #3776 2020-12-28 13:08:12 +02:00
ce7356794d Test examples from the official dev-platforms 2020-12-26 21:43:41 +02:00
523494f9cf Ignore CI tests from tokisaki dev-platform 2020-12-26 20:18:15 +02:00
0edc867d45 Bump version to 5.0.4rc1 2020-12-26 16:10:44 +02:00
ce4c45a075 Show a warning message about deprecated support for Python 2 and Python 3.5 2020-12-26 16:10:07 +02:00
e29941e3eb Update release notes with check tools updates 2020-12-22 21:30:01 +02:00
86ce3595f6 Update check tools packages // Resolve #3758
Updated tools: Cppcheck v2.3, PVS-Studio v7.11
2020-12-22 00:44:09 +02:00
6e958b8415 Handle possible issues when check tool cannot be executed // Resolve #3753
Now, each tool individually decides under what conditions the check is considered failed.
2020-12-22 00:21:32 +02:00
d485703768 Use "Updating to X.Y.Z" instead of "Outdated" when doing a real package updating 2020-12-11 17:53:48 +02:00
109e2107d1 Sync docs 2020-12-11 16:14:08 +02:00
3469905365 Decode subprocess output only for byte-strings 2020-12-02 15:15:17 +02:00
75b3846f8f Sync docs & examples 2020-12-02 15:15:02 +02:00
a9ec38208c Bump version to 5.0.4b1 2020-11-30 20:24:45 +02:00
c38b9a4144 Fixed a "git-sh-setup: file not found" error when installing project dependencies from Git VCS // Resolve #3740 2020-11-30 20:23:30 +02:00
b6128aeaa1 Apply formatting 2020-11-22 22:32:03 +02:00
881782be05 Allow spaces and dots in example's name ([package manifest) 2020-11-22 21:42:25 +02:00
0c05930501 Sync docs 2020-11-22 21:41:47 +02:00
b96f2a19b5 Bump version to 5.0.4a2 2020-11-14 20:10:45 +02:00
c1906714ee Give a constant "PlatformIO" name for the C/C++ configuration 2020-11-14 20:10:22 +02:00
32181d1bd2 Improved `.ccls` configuration file for Emacs, Vim, and Sublime Text integrations // Issue #3735 2020-11-14 19:55:24 +02:00
7dfb413d87 Typo fix 2020-11-12 21:42:53 +02:00
7934a96ad1 Added "Core" suffix when showing PlatformIO Core version using `pio --version` command 2020-11-12 20:42:27 +02:00
abddbf9c7d Bump version to 5.0.4a1 2020-11-12 18:56:55 +02:00
77e66241f7 Do not provide "intelliSenseMode" option when generating configuration for VSCode C/C++ extension 2020-11-12 18:56:34 +02:00
4b3f2e19a4 Merge branch 'release/v5.0.3' 2020-11-12 17:57:30 +02:00
b29c6485a8 Merge tag 'v5.0.3' into develop
Bump version to 5.0.3
2020-11-12 17:57:30 +02:00
f4dba7a68c Bump version to 5.0.3 2020-11-12 17:56:12 +02:00
2817408db3 Fixed an issue when pio package pack ignores some folders // Resolve #3730 2020-11-12 16:06:54 +02:00
9ff3c758eb Fix tests 2020-11-12 15:35:37 +02:00
3dcc189740 Use custom Pre-Debug task only for multi-env project 2020-11-12 15:35:19 +02:00
4a12d1954e Fixed an issue when the package manager tries to install a built-in library from the registry // Resolve #3662 2020-11-12 15:27:34 +02:00
e4d645110a Merge branch 'develop' of https://github.com/platformio/platformio-core into develop
# Conflicts:
#	HISTORY.rst
2020-11-12 15:25:51 +02:00
01a32067d5 Print ignored environments and test suites in only in verbose mode
Resolve #3726
2020-11-12 15:22:47 +02:00
fc5ce4739c Added an error selector for Sublime Text build runner // Resolve #3733 2020-11-12 15:05:01 +02:00
ae7b8f9ecf Fix tests 2020-11-11 20:52:23 +02:00
0f5d2d6821 Sync docs 2020-11-11 19:44:39 +02:00
48eca22a00 Force VSCode's intelliSenseMode to "gcc-x64" when GCC toolchain is used 2020-11-11 14:19:58 +02:00
5e164493a8 Sync docs 2020-11-09 11:39:26 +02:00
ead99208f2 Increase example name in manifest to 255 chars 2020-11-09 11:38:46 +02:00
4f5ad05792 Docs: Document "Introducing Strict SSL/TLS" in migration 2020-11-04 14:07:40 +02:00
bc52e72605 Bump version to 5.0.3a2 2020-11-03 15:11:52 +02:00
038674835a Workaround for a broken locale 2020-11-02 12:27:17 +02:00
00f21c17ca Merge branch 'develop' of https://github.com/platformio/platformio-core into develop 2020-11-01 21:06:47 +02:00
818a1508a0 Docs: Use native ProjectConfig in the advanced scripting examples 2020-11-01 21:06:23 +02:00
2d9480a6a7 Support for GitPod environment 2020-11-01 21:05:03 +02:00
0bec4e25c8 Add support for C++ language standard in QtCreator template
Resolve #3719
2020-11-01 19:03:14 +02:00
950a540df4 Bump version to 5.0.3a1 2020-10-31 19:07:45 +02:00
2e66c5f807 Generate a working "projectEnvName" for PlatformIO IDE's debugger for VSCode 2020-10-31 19:07:04 +02:00
7033c2616b Docs: Add info how to access PlatformIO Core CLI in VSCode 2020-10-31 12:44:37 +02:00
39 changed files with 366 additions and 181 deletions

View File

@ -15,7 +15,7 @@ jobs:
with:
submodules: "recursive"
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
@ -26,7 +26,8 @@ jobs:
- name: Run on Linux
if: startsWith(matrix.os, 'ubuntu')
env:
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,siwigsm,intel_mcs51,aceinna_imu"
PIO_INSTALL_DEVPLATFORMS_OWNERNAMES: "platformio"
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,intel_mcs51"
run: |
# ChipKIT issue: install 32-bit support for GCC PIC32
sudo apt-get install libc6-i386
@ -40,7 +41,8 @@ jobs:
- name: Run on macOS
if: startsWith(matrix.os, 'macos')
env:
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,siwigsm,microchippic32,gd32v,nuclei,lattice_ice40"
PIO_INSTALL_DEVPLATFORMS_OWNERNAMES: "platformio"
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,microchippic32,lattice_ice40,gd32v"
run: |
df -h
tox -e testexamples
@ -50,7 +52,8 @@ jobs:
env:
PLATFORMIO_CORE_DIR: C:/pio
PLATFORMIO_WORKSPACE_DIR: C:/pio-workspace/$PROJECT_HASH
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,siwigsm,riscv_gap"
PIO_INSTALL_DEVPLATFORMS_OWNERNAMES: "platformio"
PIO_INSTALL_DEVPLATFORMS_IGNORE: "ststm8,infineonxmc,riscv_gap"
run: |
tox -e testexamples

View File

@ -8,6 +8,31 @@ PlatformIO Core 5
**A professional collaborative platform for embedded development**
5.0.4 (2020-12-30)
~~~~~~~~~~~~~~~~~~
- Added "Core" suffix when showing PlatformIO Core version using ``pio --version`` command
- Improved ``.ccls`` configuration file for Emacs, Vim, and Sublime Text integrations
- Updated analysis tools:
* `Cppcheck <https://docs.platformio.org/page/plus/check-tools/cppcheck.html>`__ v2.3 with improved C++ parser and several new MISRA rules
* `PVS-Studio <https://docs.platformio.org/page/plus/check-tools/pvs-studio.html>`__ v7.11 with new diagnostics and updated mass suppression mechanism
- Show a warning message about deprecated support for Python 2 and Python 3.5
- Do not provide "intelliSenseMode" option when generating configuration for VSCode C/C++ extension
- Fixed a "git-sh-setup: file not found" error when installing project dependencies from Git VCS (`issue #3740 <https://github.com/platformio/platformio-core/issues/3740>`_)
- Fixed an issue with package publishing on Windows when Unix permissions are not preserved (`issue #3776 <https://github.com/platformio/platformio-core/issues/3776>`_)
5.0.3 (2020-11-12)
~~~~~~~~~~~~~~~~~~
- Added an error selector for `Sublime Text <https://docs.platformio.org/page/integration/ide/sublimetext.html>`__ build runner (`issue #3733 <https://github.com/platformio/platformio-core/issues/3733>`_)
- Generate a working "projectEnvName" for PlatformIO IDE's debugger for VSCode
- Force VSCode's intelliSenseMode to "gcc-x64" when GCC toolchain is used
- Print ignored test suites and environments in the test summary report only in verbose mode (`issue #3726 <https://github.com/platformio/platformio-core/issues/3726>`_)
- Fixed an issue when the package manager tries to install a built-in library from the registry (`issue #3662 <https://github.com/platformio/platformio-core/issues/3662>`_)
- Fixed an issue when `pio package pack <https://docs.platformio.org/page/core/userguide/package/cmd_pack.html>`__ ignores some folders (`issue #3730 <https://github.com/platformio/platformio-core/issues/3730>`_)
5.0.2 (2020-10-30)
~~~~~~~~~~~~~~~~~~
@ -118,7 +143,8 @@ Please check `Migration guide from 4.x to 5.0 <https://docs.platformio.org/page/
- Display system-wide information using a new `pio system info <https://docs.platformio.org/page/core/userguide/system/cmd_info.html>`__ command (`issue #3521 <https://github.com/platformio/platformio-core/issues/3521>`_)
- Remove unused data using a new `pio system prune <https://docs.platformio.org/page/core/userguide/system/cmd_prune.html>`__ command (`issue #3522 <https://github.com/platformio/platformio-core/issues/3522>`_)
- Show ignored project environments only in the verbose mode (`issue #3641 <https://github.com/platformio/platformio-core/issues/3641>`_)
- Do not escape compiler arguments in VSCode template on Windows.
- Do not escape compiler arguments in VSCode template on Windows
- Drop support for Python 2 and 3.5.
.. _release_notes_4:

2
docs

Submodule docs updated: deae09a880...9db46dccef

View File

@ -14,7 +14,7 @@
import sys
VERSION = (5, 0, 2)
VERSION = (5, 0, 4)
__version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio"
@ -31,11 +31,11 @@ __description__ = (
)
__url__ = "https://platformio.org"
__author__ = "PlatformIO"
__email__ = "contact@platformio.org"
__author__ = "PlatformIO Labs"
__email__ = "contact@piolabs.com"
__license__ = "Apache Software License"
__copyright__ = "Copyright 2014-present PlatformIO"
__copyright__ = "Copyright 2014-present PlatformIO Labs"
__accounts_api__ = "https://api.accounts.platformio.org"
__registry_api__ = [
@ -51,9 +51,9 @@ __core_packages__ = {
"contrib-pysite": "~2.%d%d.0" % (sys.version_info.major, sys.version_info.minor),
"tool-unity": "~1.20500.0",
"tool-scons": "~2.20501.7" if sys.version_info.major == 2 else "~4.40001.0",
"tool-cppcheck": "~1.210.0",
"tool-cppcheck": "~1.230.0",
"tool-clangtidy": "~1.100000.0",
"tool-pvs-studio": "~7.9.0",
"tool-pvs-studio": "~7.11.0",
}
__check_internet_hosts__ = [

View File

@ -33,7 +33,7 @@ except: # pylint: disable=bare-except
@click.command(
cls=PlatformioCLI, context_settings=dict(help_option_names=["-h", "--help"])
)
@click.version_option(__version__, prog_name="PlatformIO")
@click.version_option(__version__, prog_name="PlatformIO Core")
@click.option("--force", "-f", is_flag=True, help="DEPRECATE")
@click.option("--caller", "-c", help="Caller ID (service)")
@click.option("--no-ansi", is_flag=True, help="Do not print ANSI control characters")

View File

@ -255,6 +255,8 @@ def get_cid():
uid = None
if os.getenv("C9_UID"):
uid = os.getenv("C9_UID")
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(

View File

@ -167,6 +167,29 @@ class CheckToolBase(object): # pylint: disable=too-many-instance-attributes
if os.path.isfile(f):
os.remove(f)
@staticmethod
def is_check_successful(cmd_result):
return cmd_result["returncode"] == 0
def execute_check_cmd(self, cmd):
result = proc.exec_command(
cmd,
stdout=proc.LineBufferedAsyncPipe(self.on_tool_output),
stderr=proc.LineBufferedAsyncPipe(self.on_tool_output),
)
if not self.is_check_successful(result):
click.echo(
"\nError: Failed to execute check command! Exited with code %d."
% result["returncode"]
)
if self.options.get("verbose"):
click.echo(result["out"])
click.echo(result["err"])
self._bad_input = True
return result
@staticmethod
def get_project_target_files(patterns):
c_extension = (".c",)
@ -200,11 +223,7 @@ class CheckToolBase(object): # pylint: disable=too-many-instance-attributes
if self.options.get("verbose"):
click.echo(" ".join(cmd))
proc.exec_command(
cmd,
stdout=proc.LineBufferedAsyncPipe(self.on_tool_output),
stderr=proc.LineBufferedAsyncPipe(self.on_tool_output),
)
self.execute_check_cmd(cmd)
else:
if self.options.get("verbose"):

View File

@ -49,6 +49,12 @@ class ClangtidyCheckTool(CheckToolBase):
return DefectItem(severity, category, message, file_, line, column, defect_id)
@staticmethod
def is_check_successful(cmd_result):
# Note: Clang-Tidy returns 1 for not critical compilation errors,
# so 0 and 1 are only acceptable values
return cmd_result["returncode"] < 2
def configure_command(self):
tool_path = join(get_core_package_dir("tool-clangtidy"), "clang-tidy")

View File

@ -109,7 +109,7 @@ class CppcheckCheckTool(CheckToolBase):
cmd = [
tool_path,
"--addon-python=%s" % proc.get_pythonexe_path(),
"--error-exitcode=1",
"--error-exitcode=3",
"--verbose" if self.options.get("verbose") else "--quiet",
]
@ -220,6 +220,11 @@ class CppcheckCheckTool(CheckToolBase):
if os.path.isfile(dump_file):
os.remove(dump_file)
@staticmethod
def is_check_successful(cmd_result):
# Cppcheck is configured to return '3' if a defect is found
return cmd_result["returncode"] in (0, 3)
def check(self, on_defect_callback=None):
self._on_defect_callback = on_defect_callback
project_files = self.get_project_target_files(self.options["patterns"])
@ -238,11 +243,7 @@ class CppcheckCheckTool(CheckToolBase):
if self.options.get("verbose"):
click.echo(" ".join(cmd))
proc.exec_command(
cmd,
stdout=proc.LineBufferedAsyncPipe(self.on_tool_output),
stderr=proc.LineBufferedAsyncPipe(self.on_tool_output),
)
self.execute_check_cmd(cmd)
self.clean_up()

View File

@ -52,6 +52,11 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
)
)
def tool_output_filter(self, line):
if "license was not entered" in line.lower():
self._bad_input = True
return line
def _process_defects(self, defects):
for defect in defects:
if not isinstance(defect, DefectItem):
@ -203,6 +208,12 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
if os.path.isdir(self._tmp_dir):
shutil.rmtree(self._tmp_dir)
@staticmethod
def is_check_successful(cmd_result):
return (
"license" not in cmd_result["err"].lower() and cmd_result["returncode"] == 0
)
def check(self, on_defect_callback=None):
self._on_defect_callback = on_defect_callback
for scope, files in self.get_project_target_files(
@ -219,11 +230,8 @@ class PvsStudioCheckTool(CheckToolBase): # pylint: disable=too-many-instance-at
self._bad_input = True
continue
result = proc.exec_command(cmd)
# pylint: disable=unsupported-membership-test
if result["returncode"] != 0 or "license" in result["err"].lower():
self._bad_input = True
click.echo(result["err"])
result = self.execute_check_cmd(cmd)
if result["returncode"] != 0:
continue
self._process_defects(self.parse_defects(self._tmp_output_file))

View File

@ -23,6 +23,7 @@ from platformio.clients.registry import RegistryClient
from platformio.compat import ensure_python3
from platformio.package.meta import PackageSpec, PackageType
from platformio.package.pack import PackagePacker
from platformio.package.unpack import FileUnpacker, TARArchiver
def validate_datetime(ctx, param, value): # pylint: disable=unused-argument
@ -81,6 +82,17 @@ def package_pack(package, output):
)
def package_publish(package, owner, released_at, private, notify):
assert ensure_python3()
# publish .tar.gz instantly without repacking
if not os.path.isdir(package) and isinstance(
FileUnpacker.new_archiver(package), TARArchiver
):
response = RegistryClient().publish_package(
package, owner, released_at, private, notify
)
click.secho(response.get("message"), fg="green")
return
with tempfile.TemporaryDirectory() as tmp_dir: # pylint: disable=no-member
with fs.cd(tmp_dir):
p = PackagePacker(package)

View File

@ -149,15 +149,19 @@ def project_init(
):
if not silent:
if project_dir == os.getcwd():
click.secho("\nThe current working directory", fg="yellow", nl=False)
click.secho(" %s " % project_dir, fg="cyan", nl=False)
click.secho("will be used for the project.", fg="yellow")
click.secho("\nThe current working directory ", fg="yellow", nl=False)
try:
click.secho(project_dir, fg="cyan", nl=False)
except UnicodeEncodeError:
click.secho(json.dumps(project_dir), fg="cyan", nl=False)
click.secho(" will be used for the project.", fg="yellow")
click.echo("")
click.echo(
"The next files/directories have been created in %s"
% click.style(project_dir, fg="cyan")
)
click.echo("The next files/directories have been created in ", nl=False)
try:
click.secho(project_dir, fg="cyan")
except UnicodeEncodeError:
click.secho(json.dumps(project_dir), fg="cyan")
click.echo(
"%s - Put project header files here" % click.style("include", fg="cyan")
)

View File

@ -177,7 +177,7 @@ def cli( # pylint: disable=redefined-builtin
if without_testing:
return
print_testing_summary(results)
print_testing_summary(results, verbose)
command_failed = any(r.get("succeeded") is False for r in results)
if command_failed:
@ -222,7 +222,7 @@ def print_processing_footer(result):
)
def print_testing_summary(results):
def print_testing_summary(results, verbose=False):
click.echo()
tabular_data = []
@ -236,6 +236,8 @@ def print_testing_summary(results):
failed_nums += 1
status_str = click.style("FAILED", fg="red")
elif result.get("succeeded") is None:
if not verbose:
continue
status_str = "IGNORED"
else:
succeeded_nums += 1

View File

@ -62,10 +62,11 @@ def ci_strings_are_equal(a, b):
def ensure_python3(raise_exception=True):
if not raise_exception or not PY2:
return not PY2
compatible = sys.version_info >= (3, 6)
if not raise_exception or compatible:
return compatible
raise UserSideException(
"Python 3.5 or later is required for this operation. \n"
"Python 3.6 or later is required for this operation. \n"
"Please install the latest Python 3 and reinstall PlatformIO Core using "
"installation script:\n"
"https://docs.platformio.org/page/core/installation.html"

View File

@ -1,22 +1,12 @@
% import re
% STD_RE = re.compile(r"\-std=[a-z\+]+(\w+)")
% cc_stds = STD_RE.findall(cc_flags)
% cxx_stds = STD_RE.findall(cxx_flags)
%
%
clang
{{ cxx_path }}
% if cc_stds:
{{"%c"}} -std=c{{ cc_stds[-1] }}
% end
% if cxx_stds:
{{"%cpp"}} -std=c++{{ cxx_stds[-1] }}
% end
{{"%c"}} {{ !cc_flags }}
{{"%cpp"}} {{ !cxx_flags }}
% for include in filter_includes(includes):
-I{{ include }}
-I{{ !include }}
% end
% for define in defines:
-D{{ define }}
-D{{ !define }}
% end

View File

@ -1,6 +0,0 @@
% for include in filter_includes(includes):
-I{{include}}
% end
% for define in defines:
-D{{!define}}
% end

View File

@ -1,3 +1,13 @@
% import re
%
% cpp_standards_remap = {
% "0x": "11",
% "1y": "14",
% "1z": "17",
% "2a": "20",
% "2b": "23"
% }
win32 {
HOMEDIR += $$(USERPROFILE)
}
@ -27,3 +37,9 @@ HEADERS += {{file}}
SOURCES += {{file}}
% end
% end
% STD_RE = re.compile(r"\-std=[a-z\+]+(\w+)")
% cxx_stds = STD_RE.findall(cxx_flags)
% if cxx_stds:
CONFIG += c++{{ cpp_standards_remap.get(cxx_stds[-1], cxx_stds[-1]) }}
% end

View File

@ -0,0 +1,12 @@
{{ cxx_path }}
{{"%c"}} {{ !cc_flags }}
{{"%cpp"}} {{ !cxx_flags }}
% for include in filter_includes(includes):
-I{{ !include }}
% end
% for define in defines:
-D{{ !define }}
% end

View File

@ -5,9 +5,10 @@
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"run"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "PlatformIO",
"variants":
[
@ -15,78 +16,73 @@
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"run"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Build"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"run",
"--target",
"upload"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Upload"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"run",
"--target",
"clean"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Clean"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"test"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Test"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"run",
"--target",
"program"
],
"name": "Upload using Programmer"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"run",
"--target",
"uploadfs"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Upload SPIFFS image"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"update"
],
"file_regex": "^(..[^:\n]*):([0-9]+):?([0-9]+)?:? (.*)$",
"name": "Update platforms and libraries"
},
{
"cmd":
[
"{{ platformio_path }}",
"-f", "-c", "sublimetext",
"-c", "sublimetext",
"upgrade"
],
"name": "Upgrade PlatformIO Core"

View File

@ -1,20 +1,10 @@
% import re
% STD_RE = re.compile(r"\-std=[a-z\+]+(\w+)")
% cc_stds = STD_RE.findall(cc_flags)
% cxx_stds = STD_RE.findall(cxx_flags)
%
%
clang
{{ cxx_path }}
% if cc_stds:
{{"%c"}} -std=c{{ cc_stds[-1] }}
% end
% if cxx_stds:
{{"%cpp"}} -std=c++{{ cxx_stds[-1] }}
% end
{{"%c"}} {{ !cc_flags }}
{{"%cpp"}} {{ !cxx_flags }}
% for include in filter_includes(includes):
-I{{ include }}
-I{{ !include }}
% end
% for define in defines:

View File

@ -1,6 +0,0 @@
% for include in filter_includes(includes):
-I"{{include}}"
% end
% for define in defines:
-D{{!define}}
% end

View File

@ -1,9 +0,0 @@
% _defines = " ".join(["-D%s" % d.replace(" ", "\\\\ ") for d in defines])
{
"execPath": "{{ cxx_path }}",
"gccDefaultCFlags": "-fsyntax-only {{! cc_flags.replace(' -MMD ', ' ').replace('"', '\\"') }} {{ !_defines.replace('"', '\\"') }}",
"gccDefaultCppFlags": "-fsyntax-only {{! cxx_flags.replace(' -MMD ', ' ').replace('"', '\\"') }} {{ !_defines.replace('"', '\\"') }}",
"gccErrorLimit": 15,
"gccIncludePaths": "{{ ','.join(filter_includes(includes)) }}",
"gccSuppressWarnings": false
}

View File

@ -83,20 +83,15 @@
% forced_includes = _find_forced_includes(
% filter_args(cc_m_flags, ["-include", "-imacros"]), cleaned_includes)
%
//
// !!! WARNING !!! AUTO-GENERATED FILE!
// PLEASE DO NOT MODIFY IT AND USE "platformio.ini":
// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
//
{
"configurations": [
{
"name": "!!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags"
},
{
% if systype == "windows":
"name": "Win32",
% elif systype == "darwin":
"name": "Mac",
"macFrameworkPath": [],
% else:
"name": "Linux",
% end
"name": "PlatformIO",
"includePath": [
% for include in cleaned_includes:
"{{ include }}",
@ -118,7 +113,6 @@
% end
""
],
"intelliSenseMode": "clang-x64",
% if cc_stds:
"cStandard": "c{{ cc_stds[-1] }}",
% end

View File

@ -19,13 +19,18 @@
"request": "launch",
"name": "PIO Debug",
"executable": "{{ _escape_path(prog_path) }}",
"projectEnvName": "{{ env_name }}",
"toolchainBinDir": "{{ _escape_path(dirname(gdb_path)) }}",
% if svd_path:
"svdPath": "{{ _escape_path(svd_path) }}",
% end
"preLaunchTask": {
"type": "PlatformIO",
% if len(config.envs()) > 1:
"task": "Pre-Debug ({{ env_name }})"
% else:
"task": "Pre-Debug"
% end
},
"internalConsoleOptions": "openOnSessionStart"
},
@ -34,6 +39,7 @@
"request": "launch",
"name": "PIO Debug (skip Pre-Debug)",
"executable": "{{ _escape_path(prog_path) }}",
"projectEnvName": "{{ env_name }}",
"toolchainBinDir": "{{ _escape_path(dirname(gdb_path)) }}",
% if svd_path:
"svdPath": "{{ _escape_path(svd_path) }}",

View File

@ -27,6 +27,7 @@ from platformio.commands.lib.command import CTX_META_STORAGE_DIRS_KEY
from platformio.commands.lib.command import lib_update as cmd_lib_update
from platformio.commands.platform import platform_update as cmd_platform_update
from platformio.commands.upgrade import get_latest_version
from platformio.compat import ensure_python3
from platformio.package.manager.core import update_core_packages
from platformio.package.manager.library import LibraryPackageManager
from platformio.package.manager.platform import PlatformPackageManager
@ -43,8 +44,25 @@ def on_platformio_start(ctx, force, caller):
set_caller(caller)
telemetry.on_command()
if not PlatformioCLI.in_silence():
after_upgrade(ctx)
if PlatformioCLI.in_silence():
return
after_upgrade(ctx)
if not ensure_python3(raise_exception=False):
click.secho(
"""
Python 2 and Python 3.5 are not compatible with PlatformIO Core 5.0.
Please check the migration guide on how to fix this warning message:
""",
fg="yellow",
)
click.secho(
"https://docs.platformio.org/en/latest/core/migration.html"
"#drop-support-for-python-2-and-3-5",
fg="blue",
)
click.echo("")
def on_platformio_end(ctx, result): # pylint: disable=unused-argument
@ -73,17 +91,20 @@ def on_platformio_exception(e):
def set_caller(caller=None):
caller = caller or getenv("PLATFORMIO_CALLER")
if not caller:
if getenv("VSCODE_PID") or getenv("VSCODE_NLS_CONFIG"):
caller = "vscode"
elif is_container():
if getenv("C9_UID"):
caller = "C9"
elif getenv("USER") == "cabox":
caller = "CA"
elif getenv("CHE_API", getenv("CHE_API_ENDPOINT")):
caller = "Che"
app.set_session_var("caller_id", caller)
if caller:
return app.set_session_var("caller_id", caller)
if getenv("VSCODE_PID") or getenv("VSCODE_NLS_CONFIG"):
caller = "vscode"
elif getenv("GITPOD_INSTANCE_ID") or getenv("GITPOD_WORKSPACE_URL"):
caller = "gitpod"
elif is_container():
if getenv("C9_UID"):
caller = "C9"
elif getenv("USER") == "cabox":
caller = "CA"
elif getenv("CHE_API", getenv("CHE_API_ENDPOINT")):
caller = "Che"
return app.set_session_var("caller_id", caller)
class Upgrader(object):

View File

@ -153,7 +153,7 @@ class PackageManagerInstallMixin(object):
finally:
if os.path.isdir(tmp_dir):
try:
shutil.rmtree(tmp_dir)
fs.rmtree(tmp_dir)
except: # pylint: disable=bare-except
pass

View File

@ -104,7 +104,7 @@ class PackageManagerUpdateMixin(object):
outdated = self.outdated(pkg, to_spec)
if not silent:
self.print_outdated_state(outdated, show_incompatible)
self.print_outdated_state(outdated, only_check, show_incompatible)
if only_check or not outdated.is_outdated(allow_incompatible=False):
return pkg
@ -116,24 +116,39 @@ class PackageManagerUpdateMixin(object):
self.unlock()
@staticmethod
def print_outdated_state(outdated, show_incompatible=True):
def print_outdated_state(outdated, only_check, show_incompatible):
if outdated.detached:
return click.echo("[%s]" % (click.style("Detached", fg="yellow")))
if (
not outdated.latest
or outdated.current == outdated.latest
or (not show_incompatible and outdated.current == outdated.wanted)
):
return click.echo("[%s]" % (click.style("Up-to-date", fg="green")))
if outdated.wanted and outdated.current == outdated.wanted:
return click.echo(
"[%s]" % (click.style("Incompatible %s" % outdated.latest, fg="yellow"))
)
if only_check:
return click.echo(
"[%s]"
% (
click.style(
"Outdated %s" % str(outdated.wanted or outdated.latest),
fg="red",
)
)
)
return click.echo(
"[%s]"
% (
click.style(
"Outdated %s" % str(outdated.wanted or outdated.latest), fg="red"
"Updating to %s" % str(outdated.wanted or outdated.latest),
fg="green",
)
)
)

View File

@ -127,7 +127,13 @@ class LibraryPackageManager(BasePackageManager): # pylint: disable=too-many-anc
for key, value in dependency.items()
if key in ("authors", "platforms", "frameworks")
}
return self._install(spec, search_filters=search_filters or None, silent=silent)
try:
return self._install(
spec, search_filters=search_filters or None, silent=silent
)
except UnknownPackageError:
pass
return None
def uninstall_dependencies(self, pkg, silent=False):
assert isinstance(pkg, PackageItem)

View File

@ -141,9 +141,10 @@ class ExampleSchema(StrictSchema):
name = fields.Str(
required=True,
validate=[
validate.Length(min=1, max=100),
validate.Length(min=1, max=255),
validate.Regexp(
r"^[a-zA-Z\d\-\_/]+$", error="Only [a-zA-Z0-9-_/] chars are allowed"
r"^[a-zA-Z\d\-\_/\. ]+$",
error="Only [a-zA-Z0-9-_/. ] chars are allowed",
),
],
)

View File

@ -20,8 +20,8 @@ import tarfile
import tempfile
from platformio import fs
from platformio.compat import ensure_python3
from platformio.package.exception import PackageException
from platformio.compat import WINDOWS, ensure_python3
from platformio.package.exception import PackageException, UserSideException
from platformio.package.manifest.parser import ManifestFileType, ManifestParserFactory
from platformio.package.manifest.schema import ManifestSchema
from platformio.package.meta import PackageItem
@ -46,6 +46,8 @@ class PackagePacker(object):
".git/",
".hg/",
".svn/",
]
EXCLUDE_EXTRA = [
# Tests
"tests?",
# Docs
@ -115,12 +117,17 @@ class PackagePacker(object):
# if zip/tar.gz -> unpack to tmp dir
if not os.path.isdir(src):
if WINDOWS:
raise UserSideException(
"Packaging from an archive does not work on Windows OS. Please "
"extract data from `%s` manually and pack a folder instead"
% src
)
with FileUnpacker(src) as fu:
assert fu.unpack(tmp_dir, silent=True)
src = tmp_dir
src = self.find_source_root(src)
manifest = self.load_manifest(src)
filename = self.get_archive_name(
manifest["name"],
@ -188,7 +195,7 @@ class PackagePacker(object):
return dst
def compute_src_filters(self, src, include, exclude):
exclude_default = self.EXCLUDE_DEFAULT[:]
exclude_extra = self.EXCLUDE_EXTRA[:]
# extend with library extra filters
if any(
os.path.isfile(os.path.join(src, name))
@ -198,11 +205,15 @@ class PackagePacker(object):
ManifestFileType.MODULE_JSON,
)
):
exclude_default.extend(self.EXCLUDE_LIBRARY_EXTRA)
exclude_extra.extend(self.EXCLUDE_LIBRARY_EXTRA)
result = ["+<%s>" % p for p in include or ["*", ".*"]]
result += ["-<%s>" % p for p in self.EXCLUDE_DEFAULT]
# exclude items declared in manifest
result += ["-<%s>" % p for p in exclude or []]
result += ["-<%s>" % p for p in exclude_default]
# apply extra excludes if no custom "export" field in manifest
if not include and not exclude:
result += ["-<%s>" % p for p in exclude_extra]
# automatically include manifests
result += ["+<%s>" % p for p in self.INCLUDE_DEFAULT]
return result

View File

@ -134,27 +134,28 @@ class FileUnpacker(object):
self.path = path
self._archiver = None
def _init_archiver(self):
def __enter__(self):
self._archiver = self.new_archiver(self.path)
return self
def __exit__(self, *args):
if self._archiver:
self._archiver.close()
@staticmethod
def new_archiver(path):
magic_map = {
b"\x1f\x8b\x08": TARArchiver,
b"\x42\x5a\x68": TARArchiver,
b"\x50\x4b\x03\x04": ZIPArchiver,
}
magic_len = max(len(k) for k in magic_map)
with open(self.path, "rb") as fp:
with open(path, "rb") as fp:
data = fp.read(magic_len)
for magic, archiver in magic_map.items():
if data.startswith(magic):
return archiver(self.path)
raise PackageException("Unknown archive type '%s'" % self.path)
def __enter__(self):
self._archiver = self._init_archiver()
return self
def __exit__(self, *args):
if self._archiver:
self._archiver.close()
return archiver(path)
raise PackageException("Unknown archive type '%s'" % path)
def unpack(
self, dest_dir=None, with_progress=True, check_unpacked=True, silent=False

View File

@ -12,17 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import re
from os.path import join
from subprocess import CalledProcessError, check_call
from sys import modules
import subprocess
import sys
from platformio import proc
from platformio.package.exception import (
PackageException,
PlatformioException,
UserSideException,
)
from platformio.proc import exec_command
try:
from urllib.parse import urlparse
@ -51,7 +51,7 @@ class VCSClientFactory(object):
if not type_:
raise VCSBaseException("VCS: Unknown repository type %s" % remote_url)
try:
obj = getattr(modules[__name__], "%sClient" % type_.title())(
obj = getattr(sys.modules[__name__], "%sClient" % type_.title())(
src_dir, remote_url, tag, silent
)
assert isinstance(obj, VCSClientBase)
@ -86,7 +86,7 @@ class VCSClientBase(object):
@property
def storage_dir(self):
return join(self.src_dir, "." + self.command)
return os.path.join(self.src_dir, "." + self.command)
def export(self):
raise NotImplementedError
@ -108,17 +108,19 @@ class VCSClientBase(object):
args = [self.command] + args
if "cwd" not in kwargs:
kwargs["cwd"] = self.src_dir
if "env" not in kwargs:
kwargs["env"] = os.environ
try:
check_call(args, **kwargs)
subprocess.check_call(args, **kwargs)
return True
except CalledProcessError as e:
except subprocess.CalledProcessError as e:
raise VCSBaseException("VCS: Could not process command %s" % e.cmd)
def get_cmd_output(self, args, **kwargs):
args = [self.command] + args
if "cwd" not in kwargs:
kwargs["cwd"] = self.src_dir
result = exec_command(args, **kwargs)
result = proc.exec_command(args, **kwargs)
if result["returncode"] == 0:
return result["out"].strip()
raise VCSBaseException(
@ -129,6 +131,28 @@ class VCSClientBase(object):
class GitClient(VCSClientBase):
command = "git"
_configured = False
def __init__(self, *args, **kwargs):
self.configure()
super(GitClient, self).__init__(*args, **kwargs)
@classmethod
def configure(cls):
if cls._configured:
return True
cls._configured = True
try:
result = proc.exec_command([cls.command, "--exec-path"])
if result["returncode"] != 0:
return False
path = result["out"].strip()
if path:
proc.append_env_path("PATH", path)
return True
except subprocess.CalledProcessError:
pass
return False
def check_client(self):
try:
@ -173,7 +197,7 @@ class GitClient(VCSClientBase):
if self.tag:
args += ["--branch", self.tag]
args += [self.remote_url, self.src_dir]
assert self.run_cmd(args)
assert self.run_cmd(args, cwd=os.getcwd())
if is_commit:
assert self.run_cmd(["reset", "--hard", self.tag])
return self.run_cmd(

View File

@ -20,6 +20,7 @@ from threading import Thread
from platformio import exception
from platformio.compat import (
PY2,
WINDOWS,
get_filesystem_encoding,
get_locale_encoding,
@ -125,7 +126,9 @@ def exec_command(*args, **kwargs):
result[s[3:]] = kwargs[s].get_buffer()
for k, v in result.items():
if isinstance(result[k], bytes):
if PY2 and isinstance(v, unicode): # pylint: disable=undefined-variable
result[k] = v.encode()
elif not PY2 and isinstance(result[k], bytes):
try:
result[k] = result[k].decode(
get_locale_encoding() or get_filesystem_encoding()
@ -203,3 +206,11 @@ def where_is_program(program, envpath=None):
return os.path.join(bin_dir, "%s.exe" % program)
return program
def append_env_path(name, value):
cur_value = os.environ.get(name) or ""
if cur_value and value in cur_value.split(os.pathsep):
return cur_value
os.environ[name] = os.pathsep.join([cur_value, value])
return os.environ[name]

View File

@ -26,15 +26,25 @@ import click
envvar="PIO_INSTALL_DEVPLATFORMS_IGNORE",
help="Ignore names split by comma",
)
def main(desktop, ignore):
@click.option(
"--ownernames",
envvar="PIO_INSTALL_DEVPLATFORMS_OWNERNAMES",
help="Filter dev-platforms by ownernames (split by comma)",
)
def main(desktop, ignore, ownernames):
platforms = json.loads(
subprocess.check_output(
["platformio", "platform", "search", "--json-output"]
).decode()
)
ignore = [n.strip() for n in (ignore or "").split(",") if n.strip()]
ownernames = [n.strip() for n in (ownernames or "").split(",") if n.strip()]
for platform in platforms:
skip = [not desktop and platform["forDesktop"], platform["name"] in ignore]
skip = [
not desktop and platform["forDesktop"],
platform["name"] in ignore,
ownernames and platform["ownername"] not in ownernames,
]
if any(skip):
continue
subprocess.check_call(["platformio", "platform", "install", platform["name"]])

View File

@ -410,6 +410,22 @@ check_tool = pvs-studio
assert style == 0
def test_check_pvs_studio_fails_without_license(clirunner, tmpdir):
config = DEFAULT_CONFIG + "\ncheck_tool = pvs-studio"
tmpdir.join("platformio.ini").write(config)
tmpdir.mkdir("src").join("main.c").write(TEST_CODE)
default_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
verbose_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir), "-v"])
assert default_result.exit_code != 0
assert "failed to perform check" in default_result.output.lower()
assert verbose_result.exit_code != 0
assert "license was not entered" in verbose_result.output.lower()
def test_check_embedded_platform_all_tools(clirunner, validate_cliresult, tmpdir):
config = """
[env:test]

View File

@ -236,7 +236,9 @@ def test_global_lib_update_check(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_lib, ["-g", "update", "--dry-run", "--json-output"])
validate_cliresult(result)
output = json.loads(result.output)
assert set(["ESPAsyncTCP", "NeoPixelBus"]) == set(lib["name"] for lib in output)
assert set(["Adafruit PN532", "ESPAsyncTCP", "NeoPixelBus"]) == set(
lib["name"] for lib in output
)
def test_global_lib_update(clirunner, validate_cliresult):
@ -256,7 +258,7 @@ def test_global_lib_update(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_lib, ["-g", "update"])
validate_cliresult(result)
assert result.output.count("[Detached]") == 1
assert result.output.count("[Up-to-date]") == 15
assert result.output.count("[Up-to-date]") == 14
# update unknown library
result = clirunner.invoke(cmd_lib, ["-g", "update", "Unknown"])

View File

@ -34,9 +34,7 @@ def test_local_env():
if result["returncode"] != 1:
pytest.fail(str(result))
# pylint: disable=unsupported-membership-test
assert all([s in result["err"] for s in ("PASSED", "IGNORED", "FAILED")]), result[
"out"
]
assert all([s in result["err"] for s in ("PASSED", "FAILED")]), result["out"]
def test_multiple_env_build(clirunner, validate_cliresult, tmpdir):

View File

@ -91,7 +91,7 @@ def test_check_and_update_libraries(clirunner, isolated_pio_core, validate_clire
assert "There are the new updates for libraries (ArduinoJson)" in result.output
assert "Please wait while updating libraries" in result.output
assert re.search(
r"Updating bblanchon/ArduinoJson\s+6\.12\.0\s+\[Outdated [\d\.]+\]",
r"Updating bblanchon/ArduinoJson\s+6\.12\.0\s+\[Updating to [\d\.]+\]",
result.output,
)
@ -143,7 +143,9 @@ def test_check_and_update_platforms(clirunner, isolated_pio_core, validate_clire
validate_cliresult(result)
assert "There are the new updates for platforms (native)" in result.output
assert "Please wait while updating platforms" in result.output
assert re.search(r"Updating native\s+0.0.0\s+\[Outdated [\d\.]+\]", result.output)
assert re.search(
r"Updating native\s+0.0.0\s+\[Updating to [\d\.]+\]", result.output
)
# check updated version
result = clirunner.invoke(cli_pio, ["platform", "list", "--json-output"])