Merge branch 'release/v3.4.0'

This commit is contained in:
Ivan Kravets
2017-06-26 19:58:30 +03:00
78 changed files with 1643 additions and 718 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -4,6 +4,133 @@ Release Notes
PlatformIO 3.0 PlatformIO 3.0
-------------- --------------
3.4.0 (2017-06-26)
~~~~~~~~~~~~~~~~~~
* `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
- "1-click" solution, zero configuration
- Support for 100+ embedded boards
- Multiple architectures and development platforms
- Windows, MacOS, Linux (+ARMv6-8)
- Built-in into `PlatformIO IDE for Atom <http://docs.platformio.org/page/ide/atom.html>`__ and `PlatformIO IDE for VScode <http://docs.platformio.org/page/ide/vscode.html>`__
- Integration with `Eclipse <http://docs.platformio.org/page/ide/eclipse.html>`__ and `Sublime Text <http://docs.platformio.org/page/ide/sublimetext.html>`__
* Filter `PIO Unit Testing <http://docs.platformio.org/page/plus/unit-testing.html>`__
tests using a new ``test_filter`` option in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__
or `platformio test --filter <http://docs.platformio.org/page/userguide/cmd_test.html#cmdoption-platformio-test-f>`__ command
(`issue #934 <https://github.com/platformio/platformio-core/issues/934>`_)
* Custom ``test_transport`` for `PIO Unit Testing <http://docs.platformio.org/page/plus/unit-testing.html>`__ Engine
* Configure Serial Port Monitor in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__
(`issue #787 <https://github.com/platformio/platformio-core/issues/787>`_)
* New `monitor <http://docs.platformio.org/page/userguide/cmd_run.html#cmdoption-platformio-run-t>`__
target which allows to launch Serial Monitor automatically after successful
"build" or "upload" operations
(`issue #788 <https://github.com/platformio/platformio-core/issues/788>`_)
* Project generator for `VIM <http://docs.platformio.org/page/ide/vim.html>`__
* Multi-line support for the different options in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__,
such as: ``build_flags``, ``build_unflags``, etc.
(`issue #889 <https://github.com/platformio/platformio-core/issues/889>`_)
* Handle dynamic ``SRC_FILTER`` environment variable from
`library.json extra script <http://docs.platformio.org/page/librarymanager/config.html#extrascript>`__
* Notify about multiple installations of PIO Core
(`issue #961 <https://github.com/platformio/platformio-core/issues/961>`_)
* Improved auto-detecting of mbed-enabled media disks
* Automatically update Git-submodules for development platforms and libraries
that were installed from repository
* Add support for ``.*cc`` extension
(`issue #939 <https://github.com/platformio/platformio-core/issues/939>`_)
* Handle ``env_default`` in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__
when re-initializing a project
(`issue #950 <https://github.com/platformio/platformio-core/issues/950>`_)
* Use root directory for PIO Home when path contains non-ascii characters
(`issue #951 <https://github.com/platformio/platformio-core/issues/951>`_,
`issue #952 <https://github.com/platformio/platformio-core/issues/952>`_)
* Don't warn about known ``boards_dir`` option
(`pull #949 <https://github.com/platformio/platformio-core/pull/949>`_)
* Escape non-valid file name characters when installing a new package (library)
(`issue #985 <https://github.com/platformio/platformio-core/issues/985>`_)
* Fixed infinite dependency installing when repository consists of multiple
libraries
(`issue #935 <https://github.com/platformio/platformio-core/issues/935>`_)
* Fixed linter error "unity.h does not exist" for Unit Testing
(`issue #947 <https://github.com/platformio/platformio-core/issues/947>`_)
* Fixed issue when `Library Dependency Finder (LDF) <http://docs.platformio.org/page/librarymanager/ldf.html>`__
does not handle custom ``src_dir``
(`issue #942 <https://github.com/platformio/platformio-core/issues/942>`_)
* Fixed cloning a package (library) from a private Git repository with
custom user name and SSH port
(`issue #925 <https://github.com/platformio/platformio-core/issues/925>`_)
-------
* Development platform `Atmel AVR <https://github.com/platformio/platform-atmelavr>`__
+ ATTiny Support (1634, x313, x4, x41, x5, x61, x7, x8)
(`issue #47 <https://github.com/platformio/platform-atmelavr/issues/47>`__)
+ New boards: Dwenguino, nicai-systems BOB3 coding bot, NIBO 2 robot,
NIBObee robot
+ AVRDude TCP upload port (``net:host:port``)
(`pull #45 <https://github.com/platformio/platform-atmelavr/pull/45>`_)
+ Fixed uploading for LowPowerLab Moteino
* Development platform `Atmel SAM <https://github.com/platformio/platform-atmelsam>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Added support for MKRFox1200 board
+ Updated Arduino SAMD Core to 1.6.14
+ Updated mbed framework to 5.4.5/142
+ Fixed firmware uploading Arduino Zero and USB-native boards
* Development platform `Espressif 32 <https://github.com/platformio/platform-espressif32>`__
+ New boards: Adafruit Feather, FireBeetle-ESP32, IntoRobot Fig, NodeMCU-32S, Onehorse ESP32 Dev Module, and Widora AIR
+ Added support for OTA (Over-The-Air) updates
+ Updated ESP-IDF framework to v2.0
+ Updated core for Arduino framework
* Development platform `Freescale Kinetis <https://github.com/platformio/platform-freescalekinetis>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Updated mbed framework to 5.4.5/142
* Development platform `Nordic nRF51 <https://github.com/platformio/platform-nordicnrf51>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Updated mbed framework to 5.4.5/142
* Development platform `NXP LPC <https://github.com/platformio/platform-nxplpc>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Updated mbed framework to 5.4.5/142
* Development platform `Silicon Labs EFM32 <https://github.com/platformio/platform-siliconlabsefm32>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Updated mbed framework to 5.4.5/142
* Development platform `ST STM32 <https://github.com/platformio/platform-ststm32>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
+ Added support for new boards: ST STM32F0308DISCOVERY
+ Updated ``tool-stlink`` to v1.3.1
+ Updated mbed framework to 5.4.5/142
* Development platform `Teensy <https://github.com/platformio/platform-teensy>`__
+ Updated Teensy Loader CLI to v21
+ Updated Arduino Core to v1.36
+ Updated mbed framework to 5.4.5/142
* Development platform `TI MSP430 <https://github.com/platformio/platform-timsp430>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
* Development platform `TI TIVA <https://github.com/platformio/platform-titiva>`__
+ Support for `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__
3.3.1 (2017-05-27) 3.3.1 (2017-05-27)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -25,11 +152,11 @@ PlatformIO 3.0
command command
(`issue #430 <https://github.com/platformio/platformio-core/issues/430>`_) (`issue #430 <https://github.com/platformio/platformio-core/issues/430>`_)
* List supported frameworks, SDKs with a new * List supported frameworks, SDKs with a new
`pio platform frameworks <http://docs.platformio.org/en/latest/userguide/platforms/cmd_frameworks.htmll>`__ command `pio platform frameworks <http://docs.platformio.org/page/userguide/platforms/cmd_frameworks.htmll>`__ command
* Visual Studio Code extension for PlatformIO * Visual Studio Code extension for PlatformIO
(`issue #619 <https://github.com/platformio/platformio-core/issues/619>`_) (`issue #619 <https://github.com/platformio/platformio-core/issues/619>`_)
* Added new options ``--no-reset``, ``--monitor-rts`` and ``--monitor-dtr`` * Added new options ``--no-reset``, ``--monitor-rts`` and ``--monitor-dtr``
to `pio test <http://docs.platformio.org/en/latest/userguide/cmd_test.html>`__ to `pio test <http://docs.platformio.org/page/userguide/cmd_test.html>`__
command (allows to avoid automatic board's auto-reset when gathering test results) command (allows to avoid automatic board's auto-reset when gathering test results)
* Added support for templated methods in ``*.ino to *.cpp`` converter * Added support for templated methods in ``*.ino to *.cpp`` converter
(`pull #858 <https://github.com/platformio/platformio-core/pull/858>`_) (`pull #858 <https://github.com/platformio/platformio-core/pull/858>`_)
@ -167,7 +294,7 @@ PlatformIO 3.0
* Custom boards per project with ``boards_dir`` option in * Custom boards per project with ``boards_dir`` option in
`Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__ `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__
(`issue #515 <https://github.com/platformio/platformio-core/issues/515>`_) (`issue #515 <https://github.com/platformio/platformio-core/issues/515>`_)
* Unix shell-style wildcards for `upload_port <http://docs.platformio.org/page/projectconf.html#upload-port>`_ * Unix shell-style wildcards for `upload_port <http://docs.platformio.org/page/projectconf/section_env_upload.html#upload-port>`_
(`issue #839 <https://github.com/platformio/platformio-core/issues/839>`_) (`issue #839 <https://github.com/platformio/platformio-core/issues/839>`_)
* Refactored `Library Dependency Finder (LDF) <http://docs.platformio.org/page/librarymanager/ldf.html>`__ * Refactored `Library Dependency Finder (LDF) <http://docs.platformio.org/page/librarymanager/ldf.html>`__
C/C++ Preprocessor for conditional syntax (``#ifdef``, ``#if``, ``#else``, C/C++ Preprocessor for conditional syntax (``#ifdef``, ``#if``, ``#else``,
@ -294,7 +421,7 @@ PlatformIO 3.0
* Improved Project Generator when custom ``--project-option`` is passed to * Improved Project Generator when custom ``--project-option`` is passed to
`platformio init <http://docs.platformio.org/page/userguide/cmd_init.html>`__ `platformio init <http://docs.platformio.org/page/userguide/cmd_init.html>`__
command command
* Deprecated ``lib_force`` option, please use `lib_deps <http://docs.platformio.org/page/projectconf.html#lib-deps>`__ instead * Deprecated ``lib_force`` option, please use `lib_deps <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps>`__ instead
* Return valid exit code from ``plaformio test`` command * Return valid exit code from ``plaformio test`` command
* Fixed Project Generator for CLion IDE using Windows OS * Fixed Project Generator for CLion IDE using Windows OS
(`issue #785 <https://github.com/platformio/platformio-core/issues/785>`_) (`issue #785 <https://github.com/platformio/platformio-core/issues/785>`_)
@ -372,7 +499,7 @@ PlatformIO 3.0
* Library Manager 3.0 * Library Manager 3.0
+ Project dependencies per build environment using `lib_deps <http://docs.platformio.org/page/projectconf.html#lib-deps>`__ option + Project dependencies per build environment using `lib_deps <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps>`__ option
(`issue #413 <https://github.com/platformio/platformio-core/issues/413>`_) (`issue #413 <https://github.com/platformio/platformio-core/issues/413>`_)
+ `Semantic Versioning <http://semver.org/>`__ for library commands and + `Semantic Versioning <http://semver.org/>`__ for library commands and
dependencies dependencies
@ -396,10 +523,10 @@ PlatformIO 3.0
+ Check library compatibility with project environment before building + Check library compatibility with project environment before building
(`issue #415 <https://github.com/platformio/platformio-core/issues/415>`_) (`issue #415 <https://github.com/platformio/platformio-core/issues/415>`_)
+ Control Library Dependency Finder for compatibility using + Control Library Dependency Finder for compatibility using
`lib_compat_mode <http://docs.platformio.org/page/projectconf.html#lib-compat-mode>`__ `lib_compat_mode <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-compat-mode>`__
option option
+ Custom library storages/directories with + Custom library storages/directories with
`lib_extra_dirs <http://docs.platformio.org/page/projectconf.html#lib-extra-dirs>`__ option `lib_extra_dirs <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-extra-dirs>`__ option
(`issue #537 <https://github.com/platformio/platformio-core/issues/537>`_) (`issue #537 <https://github.com/platformio/platformio-core/issues/537>`_)
+ Handle extra build flags, source filters and build script from + Handle extra build flags, source filters and build script from
`library.json <http://docs.platformio.org/page/librarymanager/config.html>`__ `library.json <http://docs.platformio.org/page/librarymanager/config.html>`__
@ -655,11 +782,11 @@ PlatformIO 2.0
`platformio lib search <http://docs.platformio.org/page/userguide/lib/cmd_search.html>`__ `platformio lib search <http://docs.platformio.org/page/userguide/lib/cmd_search.html>`__
command command
(`issue #604 <https://github.com/platformio/platformio-core/issues/604>`_) (`issue #604 <https://github.com/platformio/platformio-core/issues/604>`_)
* Allowed to specify default environments `env_default <http://docs.platformio.org/page/projectconf.html#env-default>`__ * Allowed to specify default environments `env_default <http://docs.platformio.org/page/projectconf/section_platformio.html#env-default>`__
which should be processed by default with ``platformio run`` command which should be processed by default with ``platformio run`` command
(`issue #576 <https://github.com/platformio/platformio-core/issues/576>`_) (`issue #576 <https://github.com/platformio/platformio-core/issues/576>`_)
* Allowed to unflag(remove) base/initial flags using * Allowed to unflag(remove) base/initial flags using
`build_unflags <http://docs.platformio.org/page/projectconf.html#build-unflags>`__ `build_unflags <http://docs.platformio.org/page/projectconf/section_env_build.html#build-unflags>`__
option option
(`issue #559 <https://github.com/platformio/platformio-core/issues/559>`_) (`issue #559 <https://github.com/platformio/platformio-core/issues/559>`_)
* Allowed multiple VID/PID pairs when detecting serial ports * Allowed multiple VID/PID pairs when detecting serial ports
@ -1107,12 +1234,12 @@ PlatformIO 2.0
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
* Allowed to exclude/include source files from build process using * Allowed to exclude/include source files from build process using
`src_filter <http://docs.platformio.org/page/projectconf.html#src-filter>`__ `src_filter <http://docs.platformio.org/page/projectconf/section_env_build.html#src-filter>`__
(`issue #240 <https://github.com/platformio/platformio-core/issues/240>`_) (`issue #240 <https://github.com/platformio/platformio-core/issues/240>`_)
* Launch own extra script before firmware building/uploading processes * Launch own extra script before firmware building/uploading processes
(`issue #239 <https://github.com/platformio/platformio-core/issues/239>`_) (`issue #239 <https://github.com/platformio/platformio-core/issues/239>`_)
* Specify own path to the linker script (ld) using * Specify own path to the linker script (ld) using
`build_flags <http://docs.platformio.org/page/projectconf.html#build-flags>`__ `build_flags <http://docs.platformio.org/page/projectconf/section_env_build.html#build-flags>`__
option option
(`issue #233 <https://github.com/platformio/platformio-core/issues/233>`_) (`issue #233 <https://github.com/platformio/platformio-core/issues/233>`_)
* Specify library compatibility with the all platforms/frameworks * Specify library compatibility with the all platforms/frameworks
@ -1216,11 +1343,11 @@ PlatformIO 2.0
(`issue #192 <https://github.com/platformio/platformio-core/issues/192>`_) (`issue #192 <https://github.com/platformio/platformio-core/issues/192>`_)
* Control verbosity of `platformio run <http://docs.platformio.org/page/userguide/cmd_run.html#cmdoption-platformio-run-v>`_ command via ``-v/--verbose`` option * Control verbosity of `platformio run <http://docs.platformio.org/page/userguide/cmd_run.html#cmdoption-platformio-run-v>`_ command via ``-v/--verbose`` option
* Add library dependencies for build environment using * Add library dependencies for build environment using
`lib_install <http://docs.platformio.org/page/projectconf.html#lib-install>`_ `lib_install <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps>`_
option in ``platformio.ini`` option in ``platformio.ini``
(`issue #134 <https://github.com/platformio/platformio-core/issues/134>`_) (`issue #134 <https://github.com/platformio/platformio-core/issues/134>`_)
* Specify libraries which are compatible with build environment using * Specify libraries which are compatible with build environment using
`lib_use <http://docs.platformio.org/page/projectconf.html#lib-use>`_ `lib_use <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-deps>`_
option in ``platformio.ini`` option in ``platformio.ini``
(`issue #148 <https://github.com/platformio/platformio-core/issues/148>`_) (`issue #148 <https://github.com/platformio/platformio-core/issues/148>`_)
* Add more boards to PlatformIO project with * Add more boards to PlatformIO project with
@ -1356,7 +1483,7 @@ PlatformIO 1.0
development platform development platform
* Added * Added
`Project Configuration <http://docs.platformio.org/page/projectconf.html>`__ `Project Configuration <http://docs.platformio.org/page/projectconf.html>`__
option named `envs_dir <http://docs.platformio.org/page/projectconf.html#envs-dir>`__ option named `envs_dir <http://docs.platformio.org/page/projectconf/section_platformio.html#envs-dir>`__
* Disabled "prompts" automatically for *Continuous Integration* systems * Disabled "prompts" automatically for *Continuous Integration* systems
(`issue #103 <https://github.com/platformio/platformio-core/issues/103>`_) (`issue #103 <https://github.com/platformio/platformio-core/issues/103>`_)
* Fixed firmware uploading for * Fixed firmware uploading for
@ -1400,7 +1527,7 @@ PlatformIO 1.0
`#48 <https://github.com/platformio/platformio-core/issues/48>`_, `#48 <https://github.com/platformio/platformio-core/issues/48>`_,
`#50 <https://github.com/platformio/platformio-core/issues/50>`_, `#50 <https://github.com/platformio/platformio-core/issues/50>`_,
`#55 <https://github.com/platformio/platformio-core/pull/55>`_) `#55 <https://github.com/platformio/platformio-core/pull/55>`_)
* Added `src_dir <http://docs.platformio.org/page/projectconf.html#src-dir>`__ * Added `src_dir <http://docs.platformio.org/page/projectconf/section_platformio.html#src-dir>`__
option to ``[platformio]`` section of option to ``[platformio]`` section of
`platformio.ini <http://docs.platformio.org/page/projectconf.html>`__ `platformio.ini <http://docs.platformio.org/page/projectconf.html>`__
which allows to redefine location to project's source directory which allows to redefine location to project's source directory
@ -1411,7 +1538,7 @@ PlatformIO 1.0
commands which allows to return the output in `JSON <http://en.wikipedia.org/wiki/JSON>`_ format commands which allows to return the output in `JSON <http://en.wikipedia.org/wiki/JSON>`_ format
(`issue #42 <https://github.com/platformio/platformio-core/issues/42>`_) (`issue #42 <https://github.com/platformio/platformio-core/issues/42>`_)
* Allowed to ignore some libs from *Library Dependency Finder* via * Allowed to ignore some libs from *Library Dependency Finder* via
`lib_ignore <http://docs.platformio.org/page/projectconf.html#lib-ignore>`_ option `lib_ignore <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-ignore>`_ option
* Improved `platformio run <http://docs.platformio.org/page/userguide/cmd_run.html>`__ * Improved `platformio run <http://docs.platformio.org/page/userguide/cmd_run.html>`__
command: asynchronous output for build process, timing and detailed command: asynchronous output for build process, timing and detailed
information about environment configuration information about environment configuration

View File

@ -37,123 +37,47 @@ PlatformIO
`Bintray <https://bintray.com/platformio>`_ | `Bintray <https://bintray.com/platformio>`_ |
`Community <https://community.platformio.org>`_ `Community <https://community.platformio.org>`_
.. image:: http://docs.platformio.org/en/stable/_static/platformio-logo.png .. image:: https://raw.githubusercontent.com/platformio/platformio-web/develop/app/images/platformio-ide-laptop.png
:target: http://platformio.org :target: http://platformio.org
`PlatformIO <http://platformio.org>`_ is an open source ecosystem for IoT `PlatformIO <http://platformio.org>`_ is an open source ecosystem for IoT
development. Cross-platform build system and library manager. Continuous and development. Cross-platform IDE and unified debugger. Remote unit testing and
IDE integration. Arduino, ESP8266 and ARM mbed compatible firmware updates.
* **PlatformIO IDE** - The next-generation integrated development environment for IoT. Get Started
C/C++ Intelligent Code Completion and Smart Code Linter for the super-fast coding. -----------
Multi-projects workflow with Multiple Panes. Themes Support with dark and light colors.
Built-in Terminal with PlatformIO Core tool and support for the powerful Serial Port Monitor.
All advanced instruments without leaving your favourite development environment.
* **Development Platforms** - Embedded and Desktop development platforms with
pre-built toolchains, debuggers, uploaders and frameworks which work under
popular host OS: Mac, Windows, Linux (+ARM)
* **Embedded Boards** - Rapid Embedded Programming, IDE and Continuous
Integration in a few steps with PlatformIO thanks to built-in project
generator for the most popular embedded boards and IDE
* **Library Manager** - Hundreds Popular Libraries are organized into single
Web 2.0 platform: list by categories, keywords, authors, compatible
platforms and frameworks; learn via examples; be up-to-date with the latest
version.
*Atmel AVR & SAM, Espressif, Freescale Kinetis, Intel ARC32, Lattice iCE40, * `What is PlatformIO? <http://docs.platformio.org/page/what-is-platformio.html>`_
Microchip PIC32, Nordic nRF51, NXP LPC, Silicon Labs EFM32, ST STM32,
TI MSP430 & Tiva, Teensy, Arduino, mbed, libOpenCM3, etc.*
.. image:: http://docs.platformio.org/en/stable/_static/platformio-demo-wiring.gif Products
:target: http://platformio.org --------
* `PlatformIO Plus and professional solutions <https://pioplus.com>`_
* `PlatformIO IDE <http://platformio.org/platformio-ide>`_ * `PlatformIO IDE <http://platformio.org/platformio-ide>`_
* `Get Started <http://platformio.org/get-started>`_ * `PlatformIO Core <http://docs.platformio.org/page/core.html>`_
* `Library Search and Registry <http://platformio.org/lib>`_ * `PIO Remote™ <http://docs.platformio.org/page/plus/pio-remote.html>`_
* `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`_
* `PIO Unit Testing <http://docs.platformio.org/page/plus/unit-testing.html>`_
* `PIO Delivery™ <http://platformio.org/pricing#solution-pio-delivery>`_
* `Cloud Builder <http://platformio.org/pricing#solution-cloud-builder>`_
Registry
--------
* `Libraries <http://platformio.org/lib>`_
* `Development Platforms <http://platformio.org/platforms>`_ * `Development Platforms <http://platformio.org/platforms>`_
* `Frameworks <http://platformio.org/frameworks>`_ * `Frameworks <http://platformio.org/frameworks>`_
* `Embedded Boards Explorer <http://platformio.org/boards>`_ * `Embedded Boards <http://platformio.org/boards>`_
* `Library Manager <http://docs.platformio.org/en/stable/librarymanager/index.html>`_
* `User Guide <http://docs.platformio.org/en/stable/userguide/index.html>`_
* `Continuous Integration <http://docs.platformio.org/en/stable/ci/index.html>`_
* `IDE Integration <http://docs.platformio.org/en/stable/ide.html>`_
* `Articles about us <http://docs.platformio.org/en/stable/articles.html>`_
* `FAQ <http://docs.platformio.org/en/stable/faq.html>`_
* `Release Notes <http://docs.platformio.org/en/stable/history.html>`_
Use whenever. *Run everywhere.* Solutions
------------------------------- ---------
*PlatformIO* is written in pure *Python* and **doesn't depend** on any
additional libraries/tools from an operating system. It allows you to use
*PlatformIO* beginning from *PC (Mac, Linux, Win)* and ending with credit-card
sized computers (`Raspberry Pi <http://www.raspberrypi.org>`_,
`BeagleBone <http://beagleboard.org>`_,
`CubieBoard <http://cubieboard.org>`_).
Embedded Development. *Easier Than Ever.* * `Library Manager <http://docs.platformio.org/page/librarymanager/index.html>`_
----------------------------------------- * `Cloud IDEs Integration <http://platformio.org/pricing#solution-cloud-ide>`_
*PlatformIO* is well suited for embedded development and has pre-configured * `Standalone IDEs Integration <http://docs.platformio.org/page/ide.html#other-ide>`_
settings for most popular `Embedded Boards <http://platformio.org/boards>`_. * `Continuous Integration <http://docs.platformio.org/page/ci/index.html>`_
* Colourful `command-line output <https://raw.githubusercontent.com/platformio/platformio/develop/examples/platformio-examples.png>`_ Development Platforms
* `IDE Integration <http://docs.platformio.org/en/stable/ide.html>`_ with ---------------------
*Cloud9, Codeanywhere, Eclipse Che, Atom, CLion, CodeBlocks, Eclipse, Emacs, NetBeans, Qt Creator, Sublime Text, Vim, Visual Studio*
* Cloud compiling and `Continuous Integration <http://docs.platformio.org/en/stable/ci/index.html>`_
with *AppVeyor, Circle CI, Drone, Shippable, Travis CI*
* Built-in `Serial Port Monitor <http://docs.platformio.org/en/stable/userguide/cmd_serialports.html#platformio-serialports-monitor>`_ and configurable
`build -flags/-options <http://docs.platformio.org/en/stable/projectconf.html#build-flags>`_
* Automatic **firmware uploading**
* Pre-built tool chains, frameworks for the popular `development platforms <http://platformio.org/platforms>`_
.. image:: https://raw.githubusercontent.com/platformio/platformio-web/develop/app/images/platformio-embedded-development.png
:target: http://platformio.org
:alt: PlatformIO Embedded Development Process
The Missing Library Manager. *It's here!*
-----------------------------------------
*PlatformIO Library Manager* is the missing library manager for development
platforms which allows you to organize and have up-to-date external libraries.
* Friendly `Command-Line Interface <http://docs.platformio.org/en/stable/librarymanager/index.html>`_
* Modern `Web 2.0 Library Portal <http://platformio.org/lib>`_
* Open Source `Library Registry API <https://github.com/platformio/platformio-api>`_
* Library Crawler based on `library.json <http://docs.platformio.org/en/stable/librarymanager/config.html>`_
specification
* Project Dependency Manager with `Semantic Versioning <http://docs.platformio.org/page/librarymanager/index.html>`_ requirements
.. image:: https://raw.githubusercontent.com/platformio/platformio-web/develop/app/images/platformio-library-manager.png
:target: http://platformio.org
:alt: PlatformIO Library Manager Architecture
Smart Build System. *Fast and Reliable.*
----------------------------------------
*PlatformIO Code Builder* is built-on a next-generation software construction
tool named `SCons <http://www.scons.org/>`_. Think of *SCons* as an improved,
cross-platform substitute for the classic *Make* utility.
* Reliable, automatic *dependency analysis*
* Reliable detection of *build changes*
* Improved support for *parallel builds*
* Ability to share *built files in a cache*
* Lookup for external libraries which are installed via `Library Manager <http://docs.platformio.org/en/stable/librarymanager/index.html>`_
.. image:: https://raw.githubusercontent.com/platformio/platformio-web/develop/app/images/platformio-scons-builder.png
:target: http://platformio.org
:alt: PlatformIO Build System Architecture
Single source code. *Multiple platforms.*
-----------------------------------------
*PlatformIO* allows the developer to compile the same code with different
development platforms using only *One Command*
`platformio run <http://docs.platformio.org/en/stable/userguide/cmd_run.html>`_.
This happens due to
`Project Configuration File (platformio.ini) <http://docs.platformio.org/en/stable/projectconf.html>`_
where you can setup different environments with specific options (platform
type, firmware uploading settings, pre-built framework, build flags and many
more).
It has support for the most popular embedded platforms:
* `Atmel AVR <http://platformio.org/platforms/atmelavr>`_ * `Atmel AVR <http://platformio.org/platforms/atmelavr>`_
* `Atmel SAM <http://platformio.org/platforms/atmelsam>`_ * `Atmel SAM <http://platformio.org/platforms/atmelsam>`_
@ -162,16 +86,20 @@ It has support for the most popular embedded platforms:
* `Freescale Kinetis <http://platformio.org/platforms/freescalekinetis>`_ * `Freescale Kinetis <http://platformio.org/platforms/freescalekinetis>`_
* `Intel ARC32 <http://platformio.org/platforms/intel_arc32>`_ * `Intel ARC32 <http://platformio.org/platforms/intel_arc32>`_
* `Lattice iCE40 <http://platformio.org/platforms/lattice_ice40>`_ * `Lattice iCE40 <http://platformio.org/platforms/lattice_ice40>`_
* `Maxim 32 <http://platformio.org/platforms/maxim32>`_
* `Microchip PIC32 <http://platformio.org/platforms/microchippic32>`_ * `Microchip PIC32 <http://platformio.org/platforms/microchippic32>`_
* `Nordic nRF51 <http://platformio.org/platforms/nordicnrf51>`_ * `Nordic nRF51 <http://platformio.org/platforms/nordicnrf51>`_
* `Nordic nRF52 <http://platformio.org/platforms/nordicnrf52>`_
* `NXP LPC <http://platformio.org/platforms/nxplpc>`_ * `NXP LPC <http://platformio.org/platforms/nxplpc>`_
* `ST STM32 <http://platformio.org/platforms/ststm32>`_
* `Silicon Labs EFM32 <http://platformio.org/platforms/siliconlabsefm32>`_ * `Silicon Labs EFM32 <http://platformio.org/platforms/siliconlabsefm32>`_
* `ST STM32 <http://platformio.org/platforms/ststm32>`_
* `Teensy <http://platformio.org/platforms/teensy>`_ * `Teensy <http://platformio.org/platforms/teensy>`_
* `TI MSP430 <http://platformio.org/platforms/timsp430>`_ * `TI MSP430 <http://platformio.org/platforms/timsp430>`_
* `TI TivaVA C <http://platformio.org/platforms/titiva>`_ * `TI TivaVA C <http://platformio.org/platforms/titiva>`_
* `WIZNet W7500 <http://platformio.org/platforms/wiznet7500>`_
Frameworks: Frameworks
----------
* `Arduino <http://platformio.org/frameworks/arduino>`_ * `Arduino <http://platformio.org/frameworks/arduino>`_
* `ARTIK SDK <http://platformio.org/frameworks/artik-sdk>`_ * `ARTIK SDK <http://platformio.org/frameworks/artik-sdk>`_
@ -183,10 +111,9 @@ Frameworks:
* `Pumbaa <http://platformio.org/frameworks/pumbaa>`_ * `Pumbaa <http://platformio.org/frameworks/pumbaa>`_
* `Simba <http://platformio.org/frameworks/simba>`_ * `Simba <http://platformio.org/frameworks/simba>`_
* `SPL <http://platformio.org/frameworks/spl>`_ * `SPL <http://platformio.org/frameworks/spl>`_
* `STM32Cube <http://platformio.org/frameworks/stm32cube>`_
* `WiringPi <http://platformio.org/frameworks/wiringpi>`_ * `WiringPi <http://platformio.org/frameworks/wiringpi>`_
For further details, please refer to `What is PlatformIO? <http://docs.platformio.org/en/stable/faq.html#what-is-platformio>`_
Contributing Contributing
------------ ------------
@ -195,7 +122,7 @@ See `contributing guidelines <https://github.com/platformio/platformio/blob/deve
License License
------- -------
Copyright 2014-present PlatformIO <contact@platformio.org> Copyright (c) 2014-present PlatformIO <contact@platformio.org>
The PlatformIO is licensed under the permissive Apache 2.0 license, The PlatformIO is licensed under the permissive Apache 2.0 license,
so you can use it in both commercial and personal projects with confidence. so you can use it in both commercial and personal projects with confidence.

2
docs

Submodule docs updated: d20acf3631...58574c0741

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
import sys import sys
VERSION = (3, 3, 1) VERSION = (3, 4, 0)
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"
@ -33,7 +33,8 @@ __copyright__ = "Copyright 2014-present PlatformIO"
__apiurl__ = "https://api.platformio.org" __apiurl__ = "https://api.platformio.org"
if sys.version_info < (2, 7, 0) or sys.version_info >= (3, 0, 0): if sys.version_info < (2, 7, 0) or sys.version_info >= (3, 0, 0):
msg = ("PlatformIO version %s does not run under Python version %s.\n" msg = ("PlatformIO Core v%s does not run under Python version %s.\n"
"Minimum supported version is 2.7, please upgrade Python.\n"
"Python 3 is not yet supported.\n") "Python 3 is not yet supported.\n")
sys.stderr.write(msg % (__version__, sys.version.split()[0])) sys.stderr.write(msg % (__version__, sys.version.split()[0]))
sys.exit(1) sys.exit(1)

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -12,14 +12,13 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from os import getenv, listdir import os
import sys
from os.path import join from os.path import join
from platform import system from platform import system
from sys import exit as sys_exit
from traceback import format_exc from traceback import format_exc
import click import click
import requests
from platformio import __version__, exception, maintenance from platformio import __version__, exception, maintenance
from platformio.util import get_source_dir from platformio.util import get_source_dir
@ -29,7 +28,7 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
def list_commands(self, ctx): def list_commands(self, ctx):
cmds = [] cmds = []
for filename in listdir(join(get_source_dir(), "commands")): for filename in os.listdir(join(get_source_dir(), "commands")):
if filename.startswith("__init__"): if filename.startswith("__init__"):
continue continue
if filename.endswith(".py"): if filename.endswith(".py"):
@ -37,16 +36,16 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
cmds.sort() cmds.sort()
return cmds return cmds
def get_command(self, ctx, name): def get_command(self, ctx, cmd_name):
mod = None mod = None
try: try:
mod = __import__("platformio.commands." + name, None, None, mod = __import__("platformio.commands." + cmd_name, None, None,
["cli"]) ["cli"])
except ImportError: except ImportError:
try: try:
return self._handle_obsolate_command(name) return self._handle_obsolate_command(cmd_name)
except AttributeError: except AttributeError:
raise click.UsageError('No such command "%s"' % name, ctx) raise click.UsageError('No such command "%s"' % cmd_name, ctx)
return mod.cli return mod.cli
@staticmethod @staticmethod
@ -95,7 +94,7 @@ def main():
pass pass
# handle PLATFORMIO_FORCE_COLOR # handle PLATFORMIO_FORCE_COLOR
if str(getenv("PLATFORMIO_FORCE_COLOR", "")).lower() == "true": if str(os.getenv("PLATFORMIO_FORCE_COLOR", "")).lower() == "true":
try: try:
# pylint: disable=protected-access # pylint: disable=protected-access
click._compat.isatty = lambda stream: True click._compat.isatty = lambda stream: True
@ -132,5 +131,10 @@ An unexpected error occurred. Further steps:
return 0 return 0
def debug_gdb_main():
sys.argv = [sys.argv[0], "debug", "--interface", "gdb"] + sys.argv[1:]
return main()
if __name__ == "__main__": if __name__ == "__main__":
sys_exit(main()) sys.exit(main())

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -64,7 +64,8 @@ DEFAULT_SETTINGS = {
"description": "description":
("Telemetry service <http://docs.platformio.org/page/" ("Telemetry service <http://docs.platformio.org/page/"
"userguide/cmd_settings.html?#enable-telemetry> (Yes/No)"), "userguide/cmd_settings.html?#enable-telemetry> (Yes/No)"),
"value": True "value":
True
} }
} }
@ -142,28 +143,8 @@ class ContentCache(object):
def __enter__(self): def __enter__(self):
if not self._db_path or not isfile(self._db_path): if not self._db_path or not isfile(self._db_path):
return self return self
found = False
newlines = []
with open(self._db_path) as fp:
for line in fp.readlines():
if "=" not in line:
continue
line = line.strip()
expire, path = line.split("=")
if time() < int(expire) and isfile(path):
newlines.append(line)
continue
found = True
if isfile(path):
remove(path)
if not len(listdir(dirname(path))):
util.rmtree_(dirname(path))
if found and self._lock_dbindex():
with open(self._db_path, "w") as fp:
fp.write("\n".join(newlines) + "\n")
self._unlock_dbindex()
self.delete()
return self return self
def __exit__(self, type_, value, traceback): def __exit__(self, type_, value, traceback):
@ -187,6 +168,7 @@ class ContentCache(object):
def _unlock_dbindex(self): def _unlock_dbindex(self):
if self._lockfile: if self._lockfile:
self._lockfile.release() self._lockfile.release()
return True
def get_cache_path(self, key): def get_cache_path(self, key):
assert len(key) > 3 assert len(key) > 3
@ -210,28 +192,64 @@ class ContentCache(object):
return data return data
def set(self, key, data, valid): def set(self, key, data, valid):
cache_path = self.get_cache_path(key)
if isfile(cache_path):
self.delete(key)
if not data: if not data:
return return
if not isdir(self.cache_dir): if not isdir(self.cache_dir):
os.makedirs(self.cache_dir) os.makedirs(self.cache_dir)
tdmap = {"s": 1, "m": 60, "h": 3600, "d": 86400} tdmap = {"s": 1, "m": 60, "h": 3600, "d": 86400}
assert valid.endswith(tuple(tdmap.keys())) assert valid.endswith(tuple(tdmap.keys()))
cache_path = self.get_cache_path(key)
expire_time = int(time() + tdmap[valid[-1]] * int(valid[:-1])) expire_time = int(time() + tdmap[valid[-1]] * int(valid[:-1]))
if not self._lock_dbindex(): if not self._lock_dbindex():
return False return False
with open(self._db_path, "a") as fp:
fp.write("%s=%s\n" % (str(expire_time), cache_path))
self._unlock_dbindex()
if not isdir(dirname(cache_path)): if not isdir(dirname(cache_path)):
os.makedirs(dirname(cache_path)) os.makedirs(dirname(cache_path))
with open(cache_path, "wb") as fp: with open(cache_path, "wb") as fp:
if isinstance(data, dict) or isinstance(data, list): if isinstance(data, (dict, list)):
json.dump(data, fp) json.dump(data, fp)
else: else:
fp.write(str(data)) fp.write(str(data))
with open(self._db_path, "a") as fp:
fp.write("%s=%s\n" % (str(expire_time), cache_path))
return self._unlock_dbindex()
def delete(self, keys=None):
""" Keys=None, delete expired items """
if not keys:
keys = []
if not isinstance(keys, list):
keys = [keys]
paths_for_delete = [self.get_cache_path(k) for k in keys]
found = False
newlines = []
with open(self._db_path) as fp:
for line in fp.readlines():
if "=" not in line:
continue
line = line.strip()
expire, path = line.split("=")
if time() < int(expire) and isfile(path) and \
path not in paths_for_delete:
newlines.append(line)
continue
found = True
if isfile(path):
try:
remove(path)
if not listdir(dirname(path)):
util.rmtree_(dirname(path))
except OSError:
pass
if found and self._lock_dbindex():
with open(self._db_path, "w") as fp:
fp.write("\n".join(newlines) + "\n")
self._unlock_dbindex()
return True return True
@ -274,6 +292,12 @@ def set_state_item(name, value):
data[name] = value data[name] = value
def delete_state_item(name):
with State(lock=True) as data:
if name in data:
del data[name]
def get_setting(name): def get_setting(name):
_env_name = "PLATFORMIO_SETTING_%s" % name.upper() _env_name = "PLATFORMIO_SETTING_%s" % name.upper()
if _env_name in environ: if _env_name in environ:
@ -310,7 +334,8 @@ def set_session_var(name, value):
def is_disabled_progressbar(): def is_disabled_progressbar():
return any([ return any([
get_session_var("force_option"), util.is_ci(), get_session_var("force_option"),
util.is_ci(),
getenv("PLATFORMIO_DISABLE_PROGRESSBAR") == "true" getenv("PLATFORMIO_DISABLE_PROGRESSBAR") == "true"
]) ])

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,6 +14,7 @@
import base64 import base64
import json import json
import sys
from os import environ from os import environ
from os.path import join from os.path import join
from time import time from time import time
@ -63,12 +64,13 @@ commonvars.AddVariables(
("UPLOAD_SPEED",), ("UPLOAD_SPEED",),
("UPLOAD_FLAGS",), ("UPLOAD_FLAGS",),
("UPLOAD_RESETMETHOD",) ("UPLOAD_RESETMETHOD",)
) # yapf: disable ) # yapf: disable
DEFAULT_ENV_OPTIONS = dict( DEFAULT_ENV_OPTIONS = dict(
tools=[ tools=[
"ar", "as", "gcc", "g++", "gnulink", "platformio", "pioplatform", "ar", "as", "gcc", "g++", "gnulink", "platformio", "pioplatform",
"piowinhooks", "piolib", "piotest", "pioupload", "piomisc" "piowinhooks", "piolib", "pioupload", "piomisc", "pioide"
], # yapf: disable ], # yapf: disable
toolpath=[join(util.get_source_dir(), "builder", "tools")], toolpath=[join(util.get_source_dir(), "builder", "tools")],
variables=commonvars, variables=commonvars,
@ -77,7 +79,6 @@ DEFAULT_ENV_OPTIONS = dict(
PIOVARIABLES=commonvars.keys(), PIOVARIABLES=commonvars.keys(),
ENV=environ, ENV=environ,
UNIX_TIME=int(time()), UNIX_TIME=int(time()),
PROGNAME="program",
PIOHOME_DIR=util.get_home_dir(), PIOHOME_DIR=util.get_home_dir(),
PROJECT_DIR=util.get_project_dir(), PROJECT_DIR=util.get_project_dir(),
PROJECTSRC_DIR=util.get_projectsrc_dir(), PROJECTSRC_DIR=util.get_projectsrc_dir(),
@ -88,9 +89,12 @@ DEFAULT_ENV_OPTIONS = dict(
BUILDSRC_DIR=join("$BUILD_DIR", "src"), BUILDSRC_DIR=join("$BUILD_DIR", "src"),
BUILDTEST_DIR=join("$BUILD_DIR", "test"), BUILDTEST_DIR=join("$BUILD_DIR", "test"),
LIBSOURCE_DIRS=[ LIBSOURCE_DIRS=[
util.get_projectlib_dir(), util.get_projectlibdeps_dir(), util.get_projectlib_dir(),
util.get_projectlibdeps_dir(),
join("$PIOHOME_DIR", "lib") join("$PIOHOME_DIR", "lib")
], ],
PROGNAME="program",
PROG_PATH=join("$BUILD_DIR", "$PROGNAME$PROGSUFFIX"),
PYTHONEXE=util.get_pythonexe_path()) PYTHONEXE=util.get_pythonexe_path())
if not int(ARGUMENTS.get("PIOVERBOSE", 0)): if not int(ARGUMENTS.get("PIOVERBOSE", 0)):
@ -106,6 +110,8 @@ env = DefaultEnvironment(**DEFAULT_ENV_OPTIONS)
for k in commonvars.keys(): for k in commonvars.keys():
if k in env: if k in env:
env[k] = base64.b64decode(env[k]) env[k] = base64.b64decode(env[k])
if "\n" in env[k]:
env[k] = [v.strip() for v in env[k].split("\n") if v.strip()]
if env.GetOption('clean'): if env.GetOption('clean'):
env.PioClean(env.subst("$BUILD_DIR")) env.PioClean(env.subst("$BUILD_DIR"))
@ -121,21 +127,23 @@ for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPT",
continue continue
if var in ("UPLOAD_PORT", "EXTRA_SCRIPT") or not env.get(var): if var in ("UPLOAD_PORT", "EXTRA_SCRIPT") or not env.get(var):
env[var] = environ.get(k) env[var] = environ.get(k)
elif isinstance(env[var], list):
env.Append(**{var: environ.get(k)})
else: else:
env[var] = "%s%s%s" % (environ.get(k), ", " env[var] = "%s%s%s" % (environ.get(k), ", "
if var == "LIB_EXTRA_DIRS" else " ", env[var]) if var == "LIB_EXTRA_DIRS" else " ", env[var])
# Parse comma separated items # Parse comma separated items
for opt in ("PIOFRAMEWORK", "LIB_DEPS", "LIB_IGNORE", "LIB_EXTRA_DIRS"): for opt in ("PIOFRAMEWORK", "LIB_DEPS", "LIB_IGNORE", "LIB_EXTRA_DIRS"):
if opt not in env: if opt not in env or isinstance(env[opt], list):
continue continue
env[opt] = [l.strip() for l in env[opt].split(", ") if l.strip()] env[opt] = [l.strip() for l in env[opt].split(", ") if l.strip()]
# Configure extra library source directories for LDF # Configure extra library source directories for LDF
if util.get_project_optional_dir("lib_extra_dirs"): if util.get_project_optional_dir("lib_extra_dirs"):
items = util.get_project_optional_dir("lib_extra_dirs")
env.Prepend(LIBSOURCE_DIRS=[ env.Prepend(LIBSOURCE_DIRS=[
l.strip() l.strip() for l in items.split("\n" if "\n" in items else ", ")
for l in util.get_project_optional_dir("lib_extra_dirs").split(", ")
if l.strip() if l.strip()
]) ])
env.Prepend(LIBSOURCE_DIRS=env.get("LIB_EXTRA_DIRS", [])) env.Prepend(LIBSOURCE_DIRS=env.get("LIB_EXTRA_DIRS", []))
@ -146,6 +154,7 @@ env.SConscriptChdir(0)
env.SConsignFile(join("$PROJECTPIOENVS_DIR", ".sconsign.dblite")) env.SConsignFile(join("$PROJECTPIOENVS_DIR", ".sconsign.dblite"))
env.SConscript("$BUILD_SCRIPT") env.SConscript("$BUILD_SCRIPT")
AlwaysBuild(env.Alias("__debug", DEFAULT_TARGETS + ["size"]))
AlwaysBuild(env.Alias("__test", DEFAULT_TARGETS + ["size"])) AlwaysBuild(env.Alias("__test", DEFAULT_TARGETS + ["size"]))
if "UPLOAD_FLAGS" in env: if "UPLOAD_FLAGS" in env:
@ -159,5 +168,13 @@ if "envdump" in COMMAND_LINE_TARGETS:
env.Exit(0) env.Exit(0)
if "idedata" in COMMAND_LINE_TARGETS: if "idedata" in COMMAND_LINE_TARGETS:
print "\n%s\n" % json.dumps(env.DumpIDEData()) try:
env.Exit(0) print "\n%s\n" % json.dumps(env.DumpIDEData())
env.Exit(0)
except UnicodeDecodeError:
sys.stderr.write(
"\nUnicodeDecodeError: Non-ASCII characters found in build "
"environment\n"
"See explanation in FAQ > Troubleshooting > Building\n"
"http://docs.platformio.org/page/faq.html\n\n")
env.Exit(1)

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -0,0 +1,120 @@
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from glob import glob
from os.path import join
from SCons.Defaults import processDefines
from platformio import util
from platformio.managers.core import get_core_package_dir
def dump_includes(env):
includes = []
for item in env.get("CPPPATH", []):
includes.append(env.subst(item))
# installed libs
for lb in env.GetLibBuilders():
includes.extend(lb.get_inc_dirs())
# includes from toolchains
p = env.PioPlatform()
for name in p.get_installed_packages():
if p.get_package_type(name) != "toolchain":
continue
toolchain_dir = util.glob_escape(p.get_package_dir(name))
toolchain_incglobs = [
join(toolchain_dir, "*", "include*"),
join(toolchain_dir, "lib", "gcc", "*", "*", "include*")
]
for g in toolchain_incglobs:
includes.extend(glob(g))
unity_dir = get_core_package_dir("tool-unity")
if unity_dir:
includes.append(unity_dir)
return includes
def dump_defines(env):
defines = []
# global symbols
for item in processDefines(env.get("CPPDEFINES", [])):
defines.append(env.subst(item).replace('\\', ''))
# special symbol for Atmel AVR MCU
if env['PIOPLATFORM'] == "atmelavr":
defines.append(
"__AVR_%s__" % env.BoardConfig().get("build.mcu").upper()
.replace("ATMEGA", "ATmega").replace("ATTINY", "ATtiny"))
return defines
def DumpIDEData(env):
LINTCCOM = "$CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS"
LINTCXXCOM = "$CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS"
data = {
"libsource_dirs":
[env.subst(l) for l in env.get("LIBSOURCE_DIRS", [])],
"defines":
dump_defines(env),
"includes":
dump_includes(env),
"cc_flags":
env.subst(LINTCCOM),
"cxx_flags":
env.subst(LINTCXXCOM),
"cc_path":
util.where_is_program(env.subst("$CC"), env.subst("${ENV['PATH']}")),
"cxx_path":
util.where_is_program(env.subst("$CXX"), env.subst("${ENV['PATH']}")),
"gdb_path":
util.where_is_program(env.subst("$GDB"), env.subst("${ENV['PATH']}")),
"prog_path":
env.subst("$PROG_PATH")
}
env_ = env.Clone()
# https://github.com/platformio/platformio-atom-ide/issues/34
_new_defines = []
for item in processDefines(env_.get("CPPDEFINES", [])):
item = item.replace('\\"', '"')
if " " in item:
_new_defines.append(item.replace(" ", "\\\\ "))
else:
_new_defines.append(item)
env_.Replace(CPPDEFINES=_new_defines)
data.update({
"cc_flags": env_.subst(LINTCCOM),
"cxx_flags": env_.subst(LINTCXXCOM)
})
return data
def exists(_):
return True
def generate(env):
env.AddMethod(DumpIDEData)
return env

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -39,8 +39,8 @@ class LibBuilderFactory(object):
clsname = "PlatformIOLibBuilder" clsname = "PlatformIOLibBuilder"
else: else:
used_frameworks = LibBuilderFactory.get_used_frameworks(env, path) used_frameworks = LibBuilderFactory.get_used_frameworks(env, path)
common_frameworks = (set(env.get("PIOFRAMEWORK", [])) & common_frameworks = (
set(used_frameworks)) set(env.get("PIOFRAMEWORK", [])) & set(used_frameworks))
if common_frameworks: if common_frameworks:
clsname = "%sLibBuilder" % list(common_frameworks)[0].title() clsname = "%sLibBuilder" % list(common_frameworks)[0].title()
elif used_frameworks: elif used_frameworks:
@ -65,7 +65,8 @@ class LibBuilderFactory(object):
# check source files # check source files
for root, _, files in os.walk(path, followlinks=True): for root, _, files in os.walk(path, followlinks=True):
for fname in files: for fname in files:
if not env.IsFileWithExt(fname, ("c", "cpp", "h", "hpp")): if not env.IsFileWithExt(
fname, piotool.SRC_BUILD_EXT + piotool.SRC_HEADER_EXT):
continue continue
with open(join(root, fname)) as f: with open(join(root, fname)) as f:
content = f.read() content = f.read()
@ -100,6 +101,9 @@ class LibBuilderBase(object):
self._circular_deps = list() self._circular_deps = list()
self._scanned_paths = list() self._scanned_paths = list()
# reset source filter, could be overridden with extra script
self.env['SRC_FILTER'] = ""
# process extra options and append to build environment # process extra options and append to build environment
self.process_extra_options() self.process_extra_options()
@ -130,8 +134,10 @@ class LibBuilderBase(object):
@property @property
def src_filter(self): def src_filter(self):
return piotool.SRC_FILTER_DEFAULT + [ return piotool.SRC_FILTER_DEFAULT + [
"-<example%s>" % os.sep, "-<examples%s>" % os.sep, "-<test%s>" % "-<example%s>" % os.sep,
os.sep, "-<tests%s>" % os.sep "-<examples%s>" % os.sep,
"-<test%s>" % os.sep,
"-<tests%s>" % os.sep
] ]
@property @property
@ -225,6 +231,7 @@ class LibBuilderBase(object):
self.env.ProcessUnFlags(self.build_unflags) self.env.ProcessUnFlags(self.build_unflags)
self.env.ProcessFlags(self.build_flags) self.env.ProcessFlags(self.build_flags)
if self.extra_script: if self.extra_script:
self.env.SConscriptChdir(1)
self.env.SConscript( self.env.SConscript(
realpath(self.extra_script), realpath(self.extra_script),
exports={"env": self.env, exports={"env": self.env,
@ -242,8 +249,9 @@ class LibBuilderBase(object):
if (key in item and if (key in item and
not self.items_in_list(self.env[env_key], item[key])): not self.items_in_list(self.env[env_key], item[key])):
if self.verbose: if self.verbose:
sys.stderr.write("Skip %s incompatible dependency %s\n" sys.stderr.write(
% (key[:-1], item)) "Skip %s incompatible dependency %s\n" % (key[:-1],
item))
skip = True skip = True
if skip: if skip:
continue continue
@ -332,8 +340,8 @@ class LibBuilderBase(object):
if _already_depends(lb): if _already_depends(lb):
if self.verbose: if self.verbose:
sys.stderr.write("Warning! Circular dependencies detected " sys.stderr.write("Warning! Circular dependencies detected "
"between `%s` and `%s`\n" % "between `%s` and `%s`\n" % (self.path,
(self.path, lb.path)) lb.path))
self._circular_deps.append(lb) self._circular_deps.append(lb)
elif lb not in self._depbuilders: elif lb not in self._depbuilders:
self._depbuilders.append(lb) self._depbuilders.append(lb)
@ -406,6 +414,10 @@ class ProjectAsLibBuilder(LibBuilderBase):
LibBuilderBase.__init__(self, *args, **kwargs) LibBuilderBase.__init__(self, *args, **kwargs)
self._is_built = True self._is_built = True
@property
def src_dir(self):
return self.env.subst("$PROJECTSRC_DIR")
@property @property
def lib_ldf_mode(self): def lib_ldf_mode(self):
mode = LibBuilderBase.lib_ldf_mode.fget(self) mode = LibBuilderBase.lib_ldf_mode.fget(self)
@ -513,6 +525,8 @@ class PlatformIOLibBuilder(LibBuilderBase):
def src_filter(self): def src_filter(self):
if "srcFilter" in self._manifest.get("build", {}): if "srcFilter" in self._manifest.get("build", {}):
return self._manifest.get("build").get("srcFilter") return self._manifest.get("build").get("srcFilter")
elif self.env['SRC_FILTER']:
return self.env['SRC_FILTER']
elif self._is_arduino_manifest(): elif self._is_arduino_manifest():
return ArduinoLibBuilder.src_filter.fget(self) return ArduinoLibBuilder.src_filter.fget(self)
return LibBuilderBase.src_filter.fget(self) return LibBuilderBase.src_filter.fget(self)
@ -593,14 +607,14 @@ def GetLibBuilders(env): # pylint: disable=too-many-branches
if compat_mode > 1 and not lb.is_platforms_compatible( if compat_mode > 1 and not lb.is_platforms_compatible(
env['PIOPLATFORM']): env['PIOPLATFORM']):
if verbose: if verbose:
sys.stderr.write("Platform incompatible library %s\n" % sys.stderr.write(
lb.path) "Platform incompatible library %s\n" % lb.path)
return False return False
if compat_mode > 0 and "PIOFRAMEWORK" in env and \ if compat_mode > 0 and "PIOFRAMEWORK" in env and \
not lb.is_frameworks_compatible(env.get("PIOFRAMEWORK", [])): not lb.is_frameworks_compatible(env.get("PIOFRAMEWORK", [])):
if verbose: if verbose:
sys.stderr.write("Framework incompatible library %s\n" % sys.stderr.write(
lb.path) "Framework incompatible library %s\n" % lb.path)
return False return False
return True return True

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,16 +17,15 @@ from __future__ import absolute_import
import atexit import atexit
import re import re
import sys import sys
from glob import glob
from os import environ, remove, walk from os import environ, remove, walk
from os.path import basename, isdir, isfile, join, relpath from os.path import basename, isdir, isfile, join, relpath, sep
from tempfile import mkstemp from tempfile import mkstemp
from SCons.Action import Action from SCons.Action import Action
from SCons.Defaults import processDefines
from SCons.Script import ARGUMENTS from SCons.Script import ARGUMENTS
from platformio import util from platformio import util
from platformio.managers.core import get_core_package_dir
class InoToCPPConverter(object): class InoToCPPConverter(object):
@ -90,8 +89,8 @@ class InoToCPPConverter(object):
self.env.Execute( self.env.Execute(
self.env.VerboseAction( self.env.VerboseAction(
'$CXX -o "{0}" -x c++ -fpreprocessed -dD -E "{1}"'.format( '$CXX -o "{0}" -x c++ -fpreprocessed -dD -E "{1}"'.format(
out_file, tmp_path), "Converting " + basename( out_file,
out_file[:-4]))) tmp_path), "Converting " + basename(out_file[:-4])))
atexit.register(_delete_file, tmp_path) atexit.register(_delete_file, tmp_path)
return isfile(out_file) return isfile(out_file)
@ -116,7 +115,7 @@ class InoToCPPConverter(object):
elif stropen: elif stropen:
newlines[len(newlines) - 1] += line[:-1] newlines[len(newlines) - 1] += line[:-1]
continue continue
elif stropen and line.endswith('";'): elif stropen and line.endswith(('",', '";')):
newlines[len(newlines) - 1] += line newlines[len(newlines) - 1] += line
stropen = False stropen = False
newlines.append('#line %d "%s"' % newlines.append('#line %d "%s"' %
@ -140,8 +139,8 @@ class InoToCPPConverter(object):
prototypes = [] prototypes = []
reserved_keywords = set(["if", "else", "while"]) reserved_keywords = set(["if", "else", "while"])
for match in self.PROTOTYPE_RE.finditer(contents): for match in self.PROTOTYPE_RE.finditer(contents):
if (set([match.group(2).strip(), match.group(3).strip()]) & if (set([match.group(2).strip(),
reserved_keywords): match.group(3).strip()]) & reserved_keywords):
continue continue
prototypes.append(match) prototypes.append(match)
return prototypes return prototypes
@ -200,81 +199,6 @@ def _delete_file(path):
pass pass
def DumpIDEData(env):
def get_includes(env_):
includes = []
for item in env_.get("CPPPATH", []):
includes.append(env_.subst(item))
# installed libs
for lb in env.GetLibBuilders():
includes.extend(lb.get_inc_dirs())
# includes from toolchains
p = env.PioPlatform()
for name in p.get_installed_packages():
if p.get_package_type(name) != "toolchain":
continue
toolchain_dir = util.glob_escape(p.get_package_dir(name))
toolchain_incglobs = [
join(toolchain_dir, "*", "include*"),
join(toolchain_dir, "lib", "gcc", "*", "*", "include*")
]
for g in toolchain_incglobs:
includes.extend(glob(g))
return includes
def get_defines(env_):
defines = []
# global symbols
for item in processDefines(env_.get("CPPDEFINES", [])):
defines.append(env_.subst(item).replace('\\', ''))
# special symbol for Atmel AVR MCU
if env['PIOPLATFORM'] == "atmelavr":
defines.append(
"__AVR_%s__" % env.BoardConfig().get("build.mcu").upper()
.replace("ATMEGA", "ATmega").replace("ATTINY", "ATtiny"))
return defines
LINTCCOM = "$CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS"
LINTCXXCOM = "$CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS"
env_ = env.Clone()
data = {
"libsource_dirs":
[env_.subst(l) for l in env_.get("LIBSOURCE_DIRS", [])],
"defines": get_defines(env_),
"includes": get_includes(env_),
"cc_flags": env_.subst(LINTCCOM),
"cxx_flags": env_.subst(LINTCXXCOM),
"cc_path": util.where_is_program(
env_.subst("$CC"), env_.subst("${ENV['PATH']}")),
"cxx_path": util.where_is_program(
env_.subst("$CXX"), env_.subst("${ENV['PATH']}"))
}
# https://github.com/platformio/platformio-atom-ide/issues/34
_new_defines = []
for item in processDefines(env_.get("CPPDEFINES", [])):
item = item.replace('\\"', '"')
if " " in item:
_new_defines.append(item.replace(" ", "\\\\ "))
else:
_new_defines.append(item)
env_.Replace(CPPDEFINES=_new_defines)
data.update({
"cc_flags": env_.subst(LINTCCOM),
"cxx_flags": env_.subst(LINTCXXCOM)
})
return data
def GetCompilerType(env): def GetCompilerType(env):
try: try:
sysenv = environ.copy() sysenv = environ.copy()
@ -329,8 +253,7 @@ def GetActualLDScript(env):
def VerboseAction(_, act, actstr): def VerboseAction(_, act, actstr):
if int(ARGUMENTS.get("PIOVERBOSE", 0)): if int(ARGUMENTS.get("PIOVERBOSE", 0)):
return act return act
else: return Action(act, actstr)
return Action(act, actstr)
def PioClean(env, clean_dir): def PioClean(env, clean_dir):
@ -346,15 +269,44 @@ def PioClean(env, clean_dir):
env.Exit(0) env.Exit(0)
def ProcessDebug(env):
if not env.subst("$PIODEBUGFLAGS"):
env.Replace(PIODEBUGFLAGS=["-Og", "-g3", "-ggdb"])
env.Append(
BUILD_FLAGS=env.get("PIODEBUGFLAGS", []),
BUILD_UNFLAGS=["-Os", "-O0", "-O1", "-O2", "-O3"])
def ProcessTest(env):
env.Append(
CPPDEFINES=["UNIT_TEST", "UNITY_INCLUDE_CONFIG_H"],
CPPPATH=[join("$BUILD_DIR", "UnityTestLib")])
unitylib = env.BuildLibrary(
join("$BUILD_DIR", "UnityTestLib"), get_core_package_dir("tool-unity"))
env.Prepend(LIBS=[unitylib])
src_filter = None
if "PIOTEST" in env:
src_filter = "+<output_export.cpp>"
src_filter += " +<%s%s>" % (env['PIOTEST'], sep)
return env.CollectBuildFiles(
"$BUILDTEST_DIR",
"$PROJECTTEST_DIR",
src_filter=src_filter,
duplicate=False)
def exists(_): def exists(_):
return True return True
def generate(env): def generate(env):
env.AddMethod(ConvertInoToCpp) env.AddMethod(ConvertInoToCpp)
env.AddMethod(DumpIDEData)
env.AddMethod(GetCompilerType) env.AddMethod(GetCompilerType)
env.AddMethod(GetActualLDScript) env.AddMethod(GetActualLDScript)
env.AddMethod(VerboseAction) env.AddMethod(VerboseAction)
env.AddMethod(PioClean) env.AddMethod(PioClean)
env.AddMethod(ProcessDebug)
env.AddMethod(ProcessTest)
return env return env

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -81,7 +81,8 @@ def LoadPioPlatform(env, variables):
board_config = env.BoardConfig() board_config = env.BoardConfig()
for k in variables.keys(): for k in variables.keys():
if (k in env or if (k in env or
not any([k.startswith("BOARD_"), k.startswith("UPLOAD_")])): not any([k.startswith("BOARD_"),
k.startswith("UPLOAD_")])):
continue continue
_opt, _val = k.lower().split("_", 1) _opt, _val = k.lower().split("_", 1)
if _opt == "board": if _opt == "board":

View File

@ -1,48 +0,0 @@
# Copyright 2014-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import absolute_import
from os.path import join, sep
from platformio.managers.core import get_core_package_dir
def ProcessTest(env):
env.Append(
CPPDEFINES=["UNIT_TEST", "UNITY_INCLUDE_CONFIG_H"],
CPPPATH=[join("$BUILD_DIR", "UnityTestLib")])
unitylib = env.BuildLibrary(
join("$BUILD_DIR", "UnityTestLib"), get_core_package_dir("tool-unity"))
env.Prepend(LIBS=[unitylib])
src_filter = None
if "PIOTEST" in env:
src_filter = "+<output_export.cpp>"
src_filter += " +<%s%s>" % (env['PIOTEST'], sep)
return env.CollectBuildFiles(
"$BUILDTEST_DIR",
"$PROJECTTEST_DIR",
src_filter=src_filter,
duplicate=False)
def exists(_):
return True
def generate(env):
env.AddMethod(ProcessTest)
return env

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ from shutil import copyfile
from time import sleep from time import sleep
from SCons.Node.Alias import Alias from SCons.Node.Alias import Alias
from serial import Serial from serial import Serial, SerialException
from platformio import util from platformio import util
@ -48,7 +48,6 @@ def TouchSerialPort(env, port, baudrate):
s.close() s.close()
except: # pylint: disable=W0702 except: # pylint: disable=W0702
pass pass
sleep(0.4)
def WaitForNewSerialPort(env, before): def WaitForNewSerialPort(env, before):
@ -56,12 +55,12 @@ def WaitForNewSerialPort(env, before):
prev_port = env.subst("$UPLOAD_PORT") prev_port = env.subst("$UPLOAD_PORT")
new_port = None new_port = None
elapsed = 0 elapsed = 0
sleep(1) before = [p['port'] for p in before]
while elapsed < 5 and new_port is None: while elapsed < 5 and new_port is None:
now = util.get_serialports() now = [p['port'] for p in util.get_serialports()]
for p in now: for p in now:
if p not in before: if p not in before:
new_port = p['port'] new_port = p
break break
before = now before = now
sleep(0.25) sleep(0.25)
@ -69,10 +68,16 @@ def WaitForNewSerialPort(env, before):
if not new_port: if not new_port:
for p in now: for p in now:
if prev_port == p['port']: if prev_port == p:
new_port = p['port'] new_port = p
break break
try:
s = Serial(new_port)
s.close()
except SerialException:
sleep(1)
if not new_port: if not new_port:
sys.stderr.write("Error: Couldn't find a board on the selected port. " sys.stderr.write("Error: Couldn't find a board on the selected port. "
"Check that you have the correct port selected. " "Check that you have the correct port selected. "
@ -102,13 +107,17 @@ def AutodetectUploadPort(*args, **kwargs): # pylint: disable=unused-argument
def _look_for_mbed_disk(): def _look_for_mbed_disk():
msdlabels = ("mbed", "nucleo", "frdm", "microbit") msdlabels = ("mbed", "nucleo", "frdm", "microbit")
for item in util.get_logicaldisks(): for item in util.get_logicaldisks():
if not _is_match_pattern(item['disk']): if item['disk'].startswith(
"/net") or not _is_match_pattern(item['disk']):
continue continue
mbed_pages = [
join(item['disk'], n) for n in ("mbed.htm", "mbed.html")
]
if any([isfile(p) for p in mbed_pages]):
return item['disk']
if (item['name'] and if (item['name'] and
any([l in item['name'].lower() for l in msdlabels])): any([l in item['name'].lower() for l in msdlabels])):
return item['disk'] return item['disk']
if isfile(join(item['disk'], "mbed.html")):
return item['disk']
return None return None
def _look_for_serial_port(): def _look_for_serial_port():
@ -192,8 +201,8 @@ def CheckUploadSize(_, target, source, env): # pylint: disable=W0613,W0621
if used_size > max_size: if used_size > max_size:
sys.stderr.write("Error: The program size (%d bytes) is greater " sys.stderr.write("Error: The program size (%d bytes) is greater "
"than maximum allowed (%s bytes)\n" % "than maximum allowed (%s bytes)\n" % (used_size,
(used_size, max_size)) max_size))
env.Exit(1) env.Exit(1)

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -27,7 +27,7 @@ from SCons.Util import case_sensitive_suffixes, is_Sequence
from platformio.util import glob_escape, pioversion_to_intstr from platformio.util import glob_escape, pioversion_to_intstr
SRC_BUILD_EXT = ["c", "cpp", "S", "spp", "SPP", "sx", "s", "asm", "ASM"] SRC_BUILD_EXT = ["c", "cc", "cpp", "S", "spp", "SPP", "sx", "s", "asm", "ASM"]
SRC_HEADER_EXT = ["h", "hpp"] SRC_HEADER_EXT = ["h", "hpp"]
SRC_FILTER_DEFAULT = ["+<*>", "-<.git%s>" % sep, "-<svn%s>" % sep] SRC_FILTER_DEFAULT = ["+<*>", "-<.git%s>" % sep, "-<svn%s>" % sep]
@ -35,9 +35,10 @@ SRC_FILTER_DEFAULT = ["+<*>", "-<.git%s>" % sep, "-<svn%s>" % sep]
def BuildProgram(env): def BuildProgram(env):
def _append_pio_macros(): def _append_pio_macros():
env.AppendUnique(CPPDEFINES=[( env.AppendUnique(CPPDEFINES=[
"PLATFORMIO", ("PLATFORMIO",
int("{0:02d}{1:02d}{2:02d}".format(*pioversion_to_intstr())))]) int("{0:02d}{1:02d}{2:02d}".format(*pioversion_to_intstr())))
])
_append_pio_macros() _append_pio_macros()
@ -45,6 +46,9 @@ def BuildProgram(env):
if not case_sensitive_suffixes(".s", ".S"): if not case_sensitive_suffixes(".s", ".S"):
env.Replace(AS="$CC", ASCOM="$ASPPCOM") env.Replace(AS="$CC", ASCOM="$ASPPCOM")
if "__debug" in COMMAND_LINE_TARGETS:
env.ProcessDebug()
# process extra flags from board # process extra flags from board
if "BOARD" in env and "build.extra_flags" in env.BoardConfig(): if "BOARD" in env and "build.extra_flags" in env.BoardConfig():
env.ProcessFlags(env.BoardConfig().get("build.extra_flags")) env.ProcessFlags(env.BoardConfig().get("build.extra_flags"))
@ -183,7 +187,7 @@ def MatchSourceFiles(env, src_dir, src_filter=None):
src_dir = env.subst(src_dir) src_dir = env.subst(src_dir)
src_filter = src_filter or SRC_FILTER_DEFAULT src_filter = src_filter or SRC_FILTER_DEFAULT
if isinstance(src_filter, list) or isinstance(src_filter, tuple): if isinstance(src_filter, (list, tuple)):
src_filter = " ".join(src_filter) src_filter = " ".join(src_filter)
matches = set() matches = set()

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -45,12 +45,16 @@ def account_logout():
@cli.command("password", short_help="Change password") @cli.command("password", short_help="Change password")
def account_password(): @click.option("--old-password")
@click.option("--new-password")
def account_password(**kwargs):
pioplus_call(sys.argv[1:]) pioplus_call(sys.argv[1:])
@cli.command("token", short_help="Get or regenerate Authentication Token") @cli.command("token", short_help="Get or regenerate Authentication Token")
@click.option("-p", "--password")
@click.option("--regenerate", is_flag=True) @click.option("--regenerate", is_flag=True)
@click.option("--json-output", is_flag=True)
def account_token(**kwargs): def account_token(**kwargs):
pioplus_call(sys.argv[1:]) pioplus_call(sys.argv[1:])
@ -61,7 +65,8 @@ def account_forgot(**kwargs):
pioplus_call(sys.argv[1:]) pioplus_call(sys.argv[1:])
@cli.command("show", short_help="PIO Account information: groups, permissions") @cli.command("show", short_help="PIO Account information")
@click.option("--offline", is_flag=True)
@click.option("--json-output", is_flag=True) @click.option("--json-output", is_flag=True)
def account_show(**kwargs): def account_show(**kwargs):
pioplus_call(sys.argv[1:]) pioplus_call(sys.argv[1:])

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -0,0 +1,42 @@
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import sys
from os import getcwd
import click
from platformio.managers.core import pioplus_call
@click.command(
"debug",
context_settings=dict(ignore_unknown_options=True),
short_help="PIO Unified Debugger")
@click.option(
"-d",
"--project-dir",
default=getcwd,
type=click.Path(
exists=True,
file_okay=False,
dir_okay=True,
writable=True,
resolve_path=True))
@click.option("--environment", "-e", metavar="<environment>")
@click.option("--verbose", "-v", is_flag=True)
@click.option("--interface", type=click.Choice(["gdb"]))
@click.argument("__unprocessed", nargs=-1, type=click.UNPROCESSED)
def cli(*args, **kwargs): # pylint: disable=unused-argument
pioplus_call(sys.argv[1:])

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,12 +14,12 @@
import json import json
import sys import sys
from os import getcwd
import click import click
from serial.tools import miniterm from serial.tools import miniterm
from platformio.exception import MinitermException from platformio import exception, util
from platformio.util import get_serialports
@click.group(short_help="Monitor device or list existing") @click.group(short_help="Monitor device or list existing")
@ -32,10 +32,10 @@ def cli():
def device_list(json_output): def device_list(json_output):
if json_output: if json_output:
click.echo(json.dumps(get_serialports())) click.echo(json.dumps(util.get_serialports()))
return return
for item in get_serialports(): for item in util.get_serialports():
click.secho(item['port'], fg="cyan") click.secho(item['port'], fg="cyan")
click.echo("-" * len(item['port'])) click.echo("-" * len(item['port']))
click.echo("Hardware ID: %s" % item['hwid']) click.echo("Hardware ID: %s" % item['hwid'])
@ -45,8 +45,7 @@ def device_list(json_output):
@cli.command("monitor", short_help="Monitor device (Serial)") @cli.command("monitor", short_help="Monitor device (Serial)")
@click.option("--port", "-p", help="Port, a number or a device name") @click.option("--port", "-p", help="Port, a number or a device name")
@click.option( @click.option("--baud", "-b", type=int, help="Set baud rate, default=9600")
"--baud", "-b", type=int, default=9600, help="Set baud rate, default=9600")
@click.option( @click.option(
"--parity", "--parity",
default="N", default="N",
@ -98,15 +97,39 @@ def device_list(json_output):
"--quiet", "--quiet",
is_flag=True, is_flag=True,
help="Diagnostics: suppress non-error messages, default=Off") help="Diagnostics: suppress non-error messages, default=Off")
def device_monitor(**kwargs): @click.option(
"-d",
"--project-dir",
default=getcwd,
type=click.Path(
exists=True, file_okay=False, dir_okay=True, resolve_path=True))
@click.option(
"-e",
"--environment",
help="Load configuration from `platformio.ini` and specified environment")
def device_monitor(**kwargs): # pylint: disable=too-many-branches
try:
project_options = get_project_options(kwargs['project_dir'],
kwargs['environment'])
monitor_options = {k: v for k, v in project_options or []}
if monitor_options:
for k in ("port", "baud", "rts", "dtr"):
k2 = "monitor_%s" % k
if kwargs[k] is None and k2 in monitor_options:
kwargs[k] = monitor_options[k2]
if k != "port":
kwargs[k] = int(kwargs[k])
except exception.NotPlatformIOProject:
pass
if not kwargs['port']: if not kwargs['port']:
ports = get_serialports(filter_hwid=True) ports = util.get_serialports(filter_hwid=True)
if len(ports) == 1: if len(ports) == 1:
kwargs['port'] = ports[0]['port'] kwargs['port'] = ports[0]['port']
sys.argv = ["monitor"] sys.argv = ["monitor"]
for k, v in kwargs.iteritems(): for k, v in kwargs.iteritems():
if k in ("port", "baud", "rts", "dtr"): if k in ("port", "baud", "rts", "dtr", "environment", "project_dir"):
continue continue
k = "--" + k.replace("_", "-") k = "--" + k.replace("_", "-")
if isinstance(v, bool): if isinstance(v, bool):
@ -121,8 +144,31 @@ def device_monitor(**kwargs):
try: try:
miniterm.main( miniterm.main(
default_port=kwargs['port'], default_port=kwargs['port'],
default_baudrate=kwargs['baud'], default_baudrate=kwargs['baud'] or 9600,
default_rts=kwargs['rts'], default_rts=kwargs['rts'],
default_dtr=kwargs['dtr']) default_dtr=kwargs['dtr'])
except Exception as e: except Exception as e:
raise MinitermException(e) raise exception.MinitermException(e)
def get_project_options(project_dir, environment):
config = util.load_project_config(project_dir)
if not config.sections():
return
known_envs = [s[4:] for s in config.sections() if s.startswith("env:")]
if environment:
if environment in known_envs:
return config.items("env:%s" % environment)
raise exception.UnknownEnvNames(environment, ", ".join(known_envs))
if not known_envs:
return
if config.has_option("platformio", "env_default"):
env_default = config.get("platformio",
"env_default").split(", ")[0].strip()
if env_default and env_default in known_envs:
return config.items("env:%s" % env_default)
return config.items("env:%s" % known_envs[0])

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -84,8 +84,8 @@ def cli(
click.style(project_dir, fg="cyan")) click.style(project_dir, fg="cyan"))
click.echo("%s - Project Configuration File" % click.style( click.echo("%s - Project Configuration File" % click.style(
"platformio.ini", fg="cyan")) "platformio.ini", fg="cyan"))
click.echo("%s - Put your source files here" % click.style( click.echo(
"src", fg="cyan")) "%s - Put your source files here" % click.style("src", fg="cyan"))
click.echo("%s - Put here project specific (private) libraries" % click.echo("%s - Put here project specific (private) libraries" %
click.style("lib", fg="cyan")) click.style("lib", fg="cyan"))
@ -96,21 +96,10 @@ def cli(
ide is not None) ide is not None)
if ide: if ide:
if not board: env_name = get_best_envname(project_dir, board)
board = get_first_board(project_dir) if not env_name:
if board:
board = [board]
if not board:
raise exception.BoardNotDefined() raise exception.BoardNotDefined()
if len(board) > 1: pg = ProjectGenerator(project_dir, ide, env_name)
click.secho(
"Warning! You have initialised project with more than 1 board"
" for the specified IDE.\n"
"However, the IDE features (code autocompletion, syntax "
"linter) have been configured for the first board '%s' from "
"your list '%s'." % (board[0], ", ".join(board)),
fg="yellow")
pg = ProjectGenerator(project_dir, ide, board[0])
pg.generate() pg.generate()
if not silent: if not silent:
@ -126,13 +115,20 @@ def cli(
fg="green") fg="green")
def get_first_board(project_dir): def get_best_envname(project_dir, boards=None):
config = util.load_project_config(project_dir) config = util.load_project_config(project_dir)
env_default = None
if config.has_option("platformio", "env_default"):
env_default = config.get("platformio",
"env_default").split(", ")[0].strip()
if env_default:
return env_default
for section in config.sections(): for section in config.sections():
if not section.startswith("env:"): if not section.startswith("env:"):
continue continue
elif config.has_option(section, "board"): elif config.has_option(section, "board") and (not boards or config.get(
return config.get(section, "board") section, "board") in boards):
return section[4:]
return None return None
@ -301,7 +297,8 @@ def fill_project_envs(ctx, project_dir, board_ids, project_option, env_prefix,
config = util.load_project_config(project_dir) config = util.load_project_config(project_dir)
for section in config.sections(): for section in config.sections():
cond = [ cond = [
section.startswith("env:"), config.has_option(section, "board") section.startswith("env:"),
config.has_option(section, "board")
] ]
if all(cond): if all(cond):
used_boards.append(config.get(section, "board")) used_boards.append(config.get(section, "board"))

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -295,14 +295,14 @@ def lib_builtin(storage, json_output):
if json_output: if json_output:
return click.echo(json.dumps(items)) return click.echo(json.dumps(items))
for storage in items: for storage_ in items:
if not storage['items']: if not storage_['items']:
continue continue
click.secho(storage['name'], fg="green") click.secho(storage_['name'], fg="green")
click.echo("*" * len(storage['name'])) click.echo("*" * len(storage_['name']))
click.echo() click.echo()
for item in sorted(storage['items'], key=lambda i: i['name']): for item in sorted(storage_['items'], key=lambda i: i['name']):
print_lib_item(item) print_lib_item(item)
@ -366,8 +366,9 @@ def lib_show(library, json_output):
for v in lib['versions'] for v in lib['versions']
])) ]))
blocks.append(("Unique Downloads", [ blocks.append(("Unique Downloads", [
"Today: %s" % lib['dlstats']['day'], "Week: %s" % "Today: %s" % lib['dlstats']['day'],
lib['dlstats']['week'], "Month: %s" % lib['dlstats']['month'] "Week: %s" % lib['dlstats']['week'],
"Month: %s" % lib['dlstats']['month']
])) ]))
for (title, rows) in blocks: for (title, rows) in blocks:
@ -418,16 +419,16 @@ def lib_stats(json_output):
click.echo("-" * terminal_width) click.echo("-" * terminal_width)
def _print_lib_item(item): def _print_lib_item(item):
click.echo(( click.echo((printitemdate_tpl
printitemdate_tpl if "date" in item else printitem_tpl if "date" in item else printitem_tpl).format(
).format( name=click.style(item['name'], fg="cyan"),
name=click.style(item['name'], fg="cyan"), date=str(
date=str( arrow.get(item['date']).humanize()
arrow.get(item['date']).humanize() if "date" in item else ""), if "date" in item else ""),
url=click.style( url=click.style(
"http://platformio.org/lib/show/%s/%s" % (item['id'], "http://platformio.org/lib/show/%s/%s" %
quote(item['name'])), (item['id'], quote(item['name'])),
fg="blue"))) fg="blue")))
def _print_tag_item(name): def _print_tag_item(name):
click.echo( click.echo(
@ -457,8 +458,8 @@ def lib_stats(json_output):
_print_tag_item(item) _print_tag_item(item)
click.echo() click.echo()
for key, title in (("dlday", "Today"), ("dlweek", "Week"), for key, title in (("dlday", "Today"), ("dlweek", "Week"), ("dlmonth",
("dlmonth", "Month")): "Month")):
_print_title("Featured: " + title) _print_title("Featured: " + title)
_print_header(with_date=False) _print_header(with_date=False)
for item in result.get(key, []): for item in result.get(key, []):

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -81,7 +81,7 @@ def _get_installed_platform_data(platform,
name=p.name, name=p.name,
title=p.title, title=p.title,
description=p.description, description=p.description,
version=p.version, # comment before dump version=p.version,
homepage=p.homepage, homepage=p.homepage,
repository=p.repository_url, repository=p.repository_url,
url=p.vendor_url, url=p.vendor_url,
@ -202,6 +202,7 @@ def platform_frameworks(query, json_output):
] ]
frameworks.append(framework) frameworks.append(framework)
frameworks = sorted(frameworks, key=lambda manifest: manifest['name'])
if json_output: if json_output:
click.echo(json.dumps(frameworks)) click.echo(json.dumps(frameworks))
else: else:
@ -219,6 +220,8 @@ def platform_list(json_output):
manifest['__pkg_dir'], manifest['__pkg_dir'],
with_boards=False, with_boards=False,
expose_packages=False)) expose_packages=False))
platforms = sorted(platforms, key=lambda manifest: manifest['name'])
if json_output: if json_output:
click.echo(json.dumps(platforms)) click.echo(json.dumps(platforms))
else: else:
@ -269,8 +272,8 @@ def platform_show(platform, json_output): # pylint: disable=too-many-branches
if item['type']: if item['type']:
click.echo("Type: %s" % item['type']) click.echo("Type: %s" % item['type'])
click.echo("Requirements: %s" % item['requirements']) click.echo("Requirements: %s" % item['requirements'])
click.echo("Installed: %s" % ("Yes" if item.get("version") else click.echo("Installed: %s" %
"No (optional)")) ("Yes" if item.get("version") else "No (optional)"))
if "version" in item: if "version" in item:
click.echo("Version: %s" % item['version']) click.echo("Version: %s" % item['version'])
if "originalVersion" in item: if "originalVersion" in item:

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ from time import time
import click import click
from platformio import __version__, exception, telemetry, util from platformio import __version__, exception, telemetry, util
from platformio.commands.device import device_monitor as cmd_device_monitor
from platformio.commands.lib import lib_install as cmd_lib_install from platformio.commands.lib import lib_install as cmd_lib_install
from platformio.commands.lib import get_builtin_libs from platformio.commands.lib import get_builtin_libs
from platformio.commands.platform import \ from platformio.commands.platform import \
@ -78,7 +79,7 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
if config.has_option("platformio", "env_default"): if config.has_option("platformio", "env_default"):
env_default = [ env_default = [
e.strip() e.strip()
for e in config.get("platformio", "env_default").split(",") for e in config.get("platformio", "env_default").split(", ")
] ]
results = [] results = []
@ -107,7 +108,11 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
ep = EnvironmentProcessor(ctx, envname, options, target, ep = EnvironmentProcessor(ctx, envname, options, target,
upload_port, silent, verbose) upload_port, silent, verbose)
results.append((envname, ep.process())) result = (envname, ep.process())
results.append(result)
if result[1] and "monitor" in ep.get_build_targets() and \
"nobuild" not in ep.get_build_targets():
ctx.invoke(cmd_device_monitor)
found_error = any([status is False for (_, status) in results]) found_error = any([status is False for (_, status) in results])
@ -122,14 +127,23 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
class EnvironmentProcessor(object): class EnvironmentProcessor(object):
KNOWN_OPTIONS = ( KNOWN_OPTIONS = ("platform", "framework", "board", "board_mcu",
"platform", "framework", "board", "board_mcu", "board_f_cpu", "board_f_cpu", "board_f_flash", "board_flash_mode",
"board_f_flash", "board_flash_mode", "build_flags", "src_build_flags", "build_flags", "src_build_flags", "build_unflags",
"build_unflags", "src_filter", "extra_script", "targets", "src_filter", "extra_script", "targets", "upload_port",
"upload_port", "upload_protocol", "upload_speed", "upload_flags", "upload_protocol", "upload_speed", "upload_flags",
"upload_resetmethod", "lib_install", "lib_deps", "lib_force", "upload_resetmethod", "lib_deps", "lib_ignore",
"lib_ignore", "lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode", "lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode",
"test_ignore", "test_port", "piotest") "piotest", "test_transport", "test_ignore", "test_port",
"debug_tool", "debug_port", "debug_init_cmds",
"debug_extra_cmds", "debug_server", "debug_init_break",
"debug_load_cmd")
IGNORE_BUILD_OPTIONS = ("test_transport", "test_filter", "test_ignore",
"test_port", "debug_tool", "debug_port",
"debug_init_cmds", "debug_extra_cmds",
"debug_server", "debug_init_break",
"debug_load_cmd")
REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"} REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"}
@ -158,16 +172,17 @@ class EnvironmentProcessor(object):
terminal_width, _ = click.get_terminal_size() terminal_width, _ = click.get_terminal_size()
start_time = time() start_time = time()
# multi-line values to one line
for k, v in self.options.items(): for k, v in self.options.items():
if "\n" in v: self.options[k] = self.options[k].strip()
self.options[k] = self.options[k].strip().replace("\n", ", ")
if not self.silent: if not self.silent:
click.echo("[%s] Processing %s (%s)" % ( click.echo("[%s] Processing %s (%s)" %
datetime.now().strftime("%c"), click.style( (datetime.now().strftime("%c"),
self.name, fg="cyan", bold=True), ", ".join( click.style(self.name, fg="cyan", bold=True),
["%s: %s" % (k, v) for k, v in self.options.items()]))) "; ".join([
"%s: %s" % (k, v.replace("\n", ", "))
for k, v in self.options.items()
])))
click.secho("-" * terminal_width, bold=True) click.secho("-" * terminal_width, bold=True)
self.options = self._validate_options(self.options) self.options = self._validate_options(self.options)
@ -179,10 +194,10 @@ class EnvironmentProcessor(object):
if is_error or "piotest_processor" not in self.cmd_ctx.meta: if is_error or "piotest_processor" not in self.cmd_ctx.meta:
print_header( print_header(
"[%s] Took %.2f seconds" % ((click.style( "[%s] Took %.2f seconds" %
"ERROR", fg="red", bold=True) if is_error else click.style( ((click.style("ERROR", fg="red", bold=True)
"SUCCESS", fg="green", bold=True)), if is_error else click.style(
time() - start_time), "SUCCESS", fg="green", bold=True)), time() - start_time),
is_error=is_error) is_error=is_error)
return not is_error return not is_error
@ -210,41 +225,46 @@ class EnvironmentProcessor(object):
# warn about unknown options # warn about unknown options
if k not in self.KNOWN_OPTIONS: if k not in self.KNOWN_OPTIONS:
click.secho( click.secho(
"Detected non-PlatformIO `%s` option in `[env:]` section" % "Detected non-PlatformIO `%s` option in `[env:%s]` section"
k, % (k, self.name),
fg="yellow") fg="yellow")
result[k] = v result[k] = v
return result return result
def _get_build_variables(self): def get_build_variables(self):
variables = {"pioenv": self.name} variables = {"pioenv": self.name}
if self.upload_port: if self.upload_port:
variables['upload_port'] = self.upload_port variables['upload_port'] = self.upload_port
for k, v in self.options.items(): for k, v in self.options.items():
if k in self.REMAPED_OPTIONS: if k in self.REMAPED_OPTIONS:
k = self.REMAPED_OPTIONS[k] k = self.REMAPED_OPTIONS[k]
if k in self.IGNORE_BUILD_OPTIONS:
continue
if k == "targets" or (k == "upload_port" and self.upload_port): if k == "targets" or (k == "upload_port" and self.upload_port):
continue continue
variables[k] = v variables[k] = v
return variables return variables
def _get_build_targets(self): def get_build_targets(self):
targets = [] targets = []
if self.targets: if self.targets:
targets = [t for t in self.targets] targets = [t for t in self.targets]
elif "targets" in self.options: elif "targets" in self.options:
targets = self.options['targets'].split() targets = self.options['targets'].split(", ")
return targets return targets
def _run(self): def _run(self):
if "platform" not in self.options: if "platform" not in self.options:
raise exception.UndefinedEnvPlatform(self.name) raise exception.UndefinedEnvPlatform(self.name)
build_vars = self._get_build_variables() build_vars = self.get_build_variables()
build_targets = self._get_build_targets() build_targets = self.get_build_targets()
telemetry.on_run_environment(self.options, build_targets) telemetry.on_run_environment(self.options, build_targets)
# skip monitor target, we call it above
if "monitor" in build_targets:
build_targets.remove("monitor")
if "nobuild" not in build_targets: if "nobuild" not in build_targets:
# install dependent libraries # install dependent libraries
if "lib_install" in self.options: if "lib_install" in self.options:
@ -255,7 +275,9 @@ class EnvironmentProcessor(object):
], self.verbose) ], self.verbose)
if "lib_deps" in self.options: if "lib_deps" in self.options:
_autoinstall_libdeps(self.cmd_ctx, [ _autoinstall_libdeps(self.cmd_ctx, [
d.strip() for d in self.options['lib_deps'].split(", ") d.strip()
for d in self.options['lib_deps'].split(
"\n" if "\n" in self.options['lib_deps'] else ", ")
if d.strip() if d.strip()
], self.verbose) ], self.verbose)
@ -346,17 +368,19 @@ def print_summary(results, start_time):
err=status is False) err=status is False)
print_header( print_header(
"[%s] Took %.2f seconds" % ((click.style( "[%s] Took %.2f seconds" %
"SUCCESS", fg="green", bold=True) if successed else click.style( ((click.style("SUCCESS", fg="green", bold=True)
"ERROR", fg="red", bold=True)), time() - start_time), if successed else click.style("ERROR", fg="red", bold=True)),
time() - start_time),
is_error=not successed) is_error=not successed)
def check_project_defopts(config): def check_project_defopts(config):
if not config.has_section("platformio"): if not config.has_section("platformio"):
return True return True
known = ("home_dir", "lib_dir", "libdeps_dir", "src_dir", "envs_dir", known = ("env_default", "home_dir", "lib_dir", "libdeps_dir", "src_dir",
"data_dir", "test_dir", "env_default", "lib_extra_dirs") "envs_dir", "data_dir", "test_dir", "boards_dir",
"lib_extra_dirs")
unknown = set([k for k, _ in config.items("platformio")]) - set(known) unknown = set([k for k, _ in config.items("platformio")]) - set(known)
if not unknown: if not unknown:
return True return True

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -22,7 +22,18 @@ from platformio.managers.core import pioplus_call
@click.command("test", short_help="Local Unit Testing") @click.command("test", short_help="Local Unit Testing")
@click.option("--environment", "-e", multiple=True, metavar="<environment>") @click.option("--environment", "-e", multiple=True, metavar="<environment>")
@click.option("--ignore", "-i", multiple=True, metavar="<pattern>") @click.option(
"--filter",
"-f",
multiple=True,
metavar="<pattern>",
help="Filter tests by a pattern")
@click.option(
"--ignore",
"-i",
multiple=True,
metavar="<pattern>",
help="Ignore tests by a pattern")
@click.option("--upload-port") @click.option("--upload-port")
@click.option("--test-port") @click.option("--test-port")
@click.option( @click.option(

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -38,8 +38,9 @@ class FileDownloader(object):
disposition = self._request.headers.get("content-disposition") disposition = self._request.headers.get("content-disposition")
if disposition and "filename=" in disposition: if disposition and "filename=" in disposition:
self._fname = disposition[disposition.index("filename=") + self._fname = disposition[
9:].replace('"', "").replace("'", "") disposition.index("filename=") + 9:].replace('"', "").replace(
"'", "")
self._fname = self._fname.encode("utf8") self._fname = self._fname.encode("utf8")
else: else:
self._fname = url.split("/")[-1] self._fname = url.split("/")[-1]

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -20,8 +20,7 @@ class PlatformioException(Exception):
def __str__(self): # pragma: no cover def __str__(self): # pragma: no cover
if self.MESSAGE: if self.MESSAGE:
return self.MESSAGE.format(*self.args) return self.MESSAGE.format(*self.args)
else: return Exception.__str__(self)
return Exception.__str__(self)
class ReturnErrorCode(PlatformioException): class ReturnErrorCode(PlatformioException):

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,19 +15,22 @@
import json import json
import os import os
import re import re
from cStringIO import StringIO
from os.path import abspath, basename, expanduser, isdir, isfile, join, relpath from os.path import abspath, basename, expanduser, isdir, isfile, join, relpath
import bottle import bottle
import click
from platformio import app, exception, util from platformio import exception, util
from platformio.commands.run import cli as cmd_run
class ProjectGenerator(object): class ProjectGenerator(object):
def __init__(self, project_dir, ide, board): def __init__(self, project_dir, ide, env_name):
self.project_dir = project_dir self.project_dir = project_dir
self.ide = ide self.ide = ide
self.board = board self.env_name = env_name
self._tplvars = {} self._tplvars = {}
with util.cd(self.project_dir): with util.cd(self.project_dir):
@ -43,36 +46,38 @@ class ProjectGenerator(object):
@util.memoized @util.memoized
def get_project_env(self): def get_project_env(self):
data = {"env_name": "PlatformIO"} data = None
config = util.load_project_config(self.project_dir) config = util.load_project_config(self.project_dir)
for section in config.sections(): for section in config.sections():
if not section.startswith("env:"): if not section.startswith("env:"):
continue continue
if self.env_name != section[4:]:
continue
data = {"env_name": section[4:]} data = {"env_name": section[4:]}
for k, v in config.items(section): for k, v in config.items(section):
data[k] = v data[k] = v
if self.board == data.get("board"):
break
return data return data
@util.memoized @util.memoized
def get_project_build_data(self): def get_project_build_data(self):
data = {"defines": [], "includes": [], "cxx_path": None} data = {"defines": [], "includes": [], "cxx_path": None}
envdata = self.get_project_env() envdata = self.get_project_env()
if "env_name" not in envdata: if not envdata:
return data return data
cmd = [util.get_pythonexe_path(), "-m", "platformio", "-f"]
if app.get_session_var("caller_id"):
cmd.extend(["-c", app.get_session_var("caller_id")])
cmd.extend(["run", "-t", "idedata", "-e", envdata['env_name']])
cmd.extend(["-d", self.project_dir])
result = util.exec_command(cmd)
if result['returncode'] != 0 or '"includes":' not in result['out']: out = StringIO()
raise exception.PlatformioException( with util.capture_stdout(out):
"\n".join([result['out'], result['err']])) click.get_current_context().invoke(
cmd_run,
project_dir=self.project_dir,
environment=[envdata['env_name']],
target=["idedata"])
result = out.getvalue()
for line in result['out'].split("\n"): if '"includes":' not in result:
raise exception.PlatformioException(result)
for line in result.split("\n"):
line = line.strip() line = line.strip()
if line.startswith('{"') and line.endswith("}"): if line.startswith('{"') and line.endswith("}"):
data = json.loads(line) data = json.loads(line)
@ -146,16 +151,24 @@ class ProjectGenerator(object):
self._tplvars.update(self.get_project_env()) self._tplvars.update(self.get_project_env())
self._tplvars.update(self.get_project_build_data()) self._tplvars.update(self.get_project_build_data())
self._tplvars.update({ self._tplvars.update({
"project_name": self.get_project_name(), "project_name":
"src_files": self.get_src_files(), self.get_project_name(),
"user_home_dir": abspath(expanduser("~")), "src_files":
"project_dir": self.project_dir, self.get_src_files(),
"project_src_dir": self.project_src_dir, "user_home_dir":
"systype": util.get_systype(), abspath(expanduser("~")),
"project_dir":
self.project_dir,
"project_src_dir":
self.project_src_dir,
"systype":
util.get_systype(),
"platformio_path": "platformio_path":
self._fix_os_path(util.where_is_program("platformio")), self._fix_os_path(util.where_is_program("platformio")),
"env_pathsep": os.pathsep, "env_pathsep":
"env_path": self._fix_os_path(os.getenv("PATH")) os.pathsep,
"env_path":
self._fix_os_path(os.getenv("PATH"))
}) })
@staticmethod @staticmethod

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB" value="true"/>
<listAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB_LIST"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="platformio -c eclipse debug -d ${project_loc} --interface=gdb"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_ON_FORK" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.GDB_INIT" value=".pioinit"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="false"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REVERSE" value="false"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.REVERSE_MODE" value="UseSoftTrace"/>
<listAttribute key="org.eclipse.cdt.dsf.gdb.SOLIB_PATH"/>
<stringAttribute key="org.eclipse.cdt.dsf.gdb.TRACEPOINT_MODE" value="TP_NORMAL_ONLY"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.internal.ui.launching.LocalApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="gdb"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value=".pioenvs/{{env_name}}/firmware.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="{{project_name}}"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/{{project_name}}"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute>
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;memoryBlockExpressionList context=&quot;reserved-for-future-use&quot;/&gt;&#10;"/>
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
<stringAttribute key="saved_expressions&lt;seperator&gt;Unknown" value="0x55f4"/>
</launchConfiguration>

View File

@ -93,5 +93,12 @@
{ {
"path": "." "path": "."
} }
] ],
"settings":
{
"sublimegdb_workingdir": "{{project_dir}}",
"sublimegdb_exec_cmd": "-exec-continue",
"sublimegdb_commandline": "{{platformio_path}} -f -c sublimetext debug --interface=gdb --interpreter=mi -x .pioinit"
}
} }

View File

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

View File

@ -0,0 +1,8 @@
{
"execPath": "{{ cxx_path.replace("\\", "/") }}",
"gccDefaultCFlags": "-fsyntax-only {{! cc_flags.replace(' -MMD ', ' ').replace('"', '\\"') }}",
"gccDefaultCppFlags": "-fsyntax-only {{! cxx_flags.replace(' -MMD ', ' ').replace('"', '\\"') }}",
"gccErrorLimit": 15,
"gccIncludePaths": "{{ ','.join(includes).replace("\\", "/") }}",
"gccSuppressWarnings": false
}

View File

@ -0,0 +1,4 @@
.pioenvs
.piolibdeps
.clang_complete
.gcc-flags.json

View File

@ -0,0 +1,3 @@
.pioenvs
.piolibdeps
.vscode

View File

@ -0,0 +1,37 @@
{
"configurations": [
{
% import platform
% systype = platform.system().lower()
% if systype == "windows":
"name": "Win32",
% elif systype == "darwin":
"name": "Mac",
% else:
"name": "Linux",
% end
"includePath": [
% for include in includes:
"{{include.replace('\\\\', '/').replace('\\', '/').replace('"', '\\"')}}",
% end
""
],
"browse": {
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": "",
"path": [
% for include in includes:
"{{include.replace('\\\\', '/').replace('\\', '/').replace('"', '\\"')}}",
% end
""
]
},
"defines": [
% for define in defines:
"{{!define.replace('"', '\\"')}}",
% end
""
]
}
]
}

View File

@ -0,0 +1,15 @@
% from os.path import dirname, join
{
"version": "0.2.0",
"configurations": [
{
"type": "gdb",
"request": "launch",
"cwd": "${workspaceRoot}",
"name": "PlatformIO Debugger",
"target": "{{prog_path.replace('\\\\', '/').replace('\\', '/').replace('"', '\\"')}}",
"gdbpath": "{{join(dirname(platformio_path), "piodebuggdb").replace('\\\\', '/').replace('\\', '/').replace('"', '\\"')}}",
"autorun": [ "source .pioinit" ]
}
]
}

View File

@ -0,0 +1,121 @@
{
"version": "0.1.0",
"runner": "terminal",
"command": "{{platformio_path}}",
"isShellCommand": false,
"args": ["-c", "vscode"],
"showOutput": "always",
"echoCommand": false,
"suppressTaskName": true,
"tasks": [
{
"taskName": "PlatformIO: Build",
"isBuildCommand": true,
"args": ["run"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Clean",
"args": ["run", "-t", "clean"]
},
{
"taskName": "PlatformIO: Upload",
"args": ["run", "-t", "upload"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Upload using Programmer",
"args": ["run", "-t", "program"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Upload SPIFFS image",
"args": ["run", "-t", "uploadfs"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Upload and Monitor",
"args": ["run", "-t", "upload", "-t", "monitor"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Test",
"args": ["test"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^([^:\\n]+):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"taskName": "PlatformIO: Update platforms and libraries",
"args": ["update"]
},
{
"taskName": "PlatformIO: Upgrade PIO Core",
"args": ["upgrade"]
}
]
}

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -38,14 +38,19 @@ def in_silence(ctx=None):
ctx = ctx or app.get_session_var("command_ctx") ctx = ctx or app.get_session_var("command_ctx")
assert ctx assert ctx
ctx_args = ctx.args or [] ctx_args = ctx.args or []
return (ctx_args and conditions = [
(ctx.args[0] == "upgrade" or "--json-output" in ctx_args)) ctx.args[0] == "upgrade", "--json-output" in ctx_args,
"--version" in ctx_args
]
return ctx_args and any(conditions)
def on_platformio_start(ctx, force, caller): def on_platformio_start(ctx, force, caller):
if not caller: if not caller:
if getenv("PLATFORMIO_CALLER"): if getenv("PLATFORMIO_CALLER"):
caller = getenv("PLATFORMIO_CALLER") caller = getenv("PLATFORMIO_CALLER")
elif getenv("VSCODE_PID") or getenv("VSCODE_NLS_CONFIG"):
caller = "vscode"
elif util.is_container(): elif util.is_container():
if getenv("C9_UID"): if getenv("C9_UID"):
caller = "C9" caller = "C9"
@ -90,20 +95,22 @@ class Upgrader(object):
self.to_version = semantic_version.Version.coerce( self.to_version = semantic_version.Version.coerce(
util.pepver_to_semver(to_version)) util.pepver_to_semver(to_version))
self._upgraders = [ self._upgraders = [(semantic_version.Version("3.0.0-a.1"),
(semantic_version.Version("3.0.0-a.1"), self._upgrade_to_3_0_0), self._upgrade_to_3_0_0),
(semantic_version.Version("3.0.0-b.11"), self._upgrade_to_3_0_0b11) (semantic_version.Version("3.0.0-b.11"),
] self._upgrade_to_3_0_0b11),
(semantic_version.Version("3.4.0-a.9"),
self._update_dev_platforms)]
def run(self, ctx): def run(self, ctx):
if self.from_version > self.to_version: if self.from_version > self.to_version:
return True return True
result = [True] result = [True]
for item in self._upgraders: for version, callback in self._upgraders:
if self.from_version >= item[0] or self.to_version < item[0]: if self.from_version >= version or self.to_version < version:
continue continue
result.append(item[1](ctx)) result.append(callback(ctx))
return all(result) return all(result)
@ -144,14 +151,36 @@ class Upgrader(object):
ctx.invoke(cmd_platform_uninstall, platforms=["espressif"]) ctx.invoke(cmd_platform_uninstall, platforms=["espressif"])
return True return True
@staticmethod
def _update_dev_platforms(ctx):
ctx.invoke(cmd_platform_update)
return True
def after_upgrade(ctx): def after_upgrade(ctx):
terminal_width, _ = click.get_terminal_size()
last_version = app.get_state_item("last_version", "0.0.0") last_version = app.get_state_item("last_version", "0.0.0")
if last_version == __version__: if last_version == __version__:
return return
if last_version == "0.0.0": if last_version == "0.0.0":
app.set_state_item("last_version", __version__) app.set_state_item("last_version", __version__)
elif semantic_version.Version.coerce(util.pepver_to_semver(
last_version)) > semantic_version.Version.coerce(
util.pepver_to_semver(__version__)):
click.secho("*" * terminal_width, fg="yellow")
click.secho(
"Obsolete PIO Core v%s is used (previous was %s)" % (__version__,
last_version),
fg="yellow")
click.secho(
"Please remove multiple PIO Cores from a system:", fg="yellow")
click.secho(
"http://docs.platformio.org/page/faq.html"
"#multiple-pio-cores-in-a-system",
fg="cyan")
click.secho("*" * terminal_width, fg="yellow")
return
else: else:
click.secho("Please wait while upgrading PlatformIO...", fg="yellow") click.secho("Please wait while upgrading PlatformIO...", fg="yellow")
app.clean_cache() app.clean_cache()
@ -175,25 +204,26 @@ def after_upgrade(ctx):
click.echo("") click.echo("")
# PlatformIO banner # PlatformIO banner
terminal_width, _ = click.get_terminal_size()
click.echo("*" * terminal_width) click.echo("*" * terminal_width)
click.echo("If you like %s, please:" % (click.style( click.echo("If you like %s, please:" %
"PlatformIO", fg="cyan"))) (click.style("PlatformIO", fg="cyan")))
click.echo("- %s us on Twitter to stay up-to-date " click.echo("- %s us on Twitter to stay up-to-date "
"on the latest project news > %s" % (click.style( "on the latest project news > %s" %
"follow", fg="cyan"), click.style( (click.style("follow", fg="cyan"),
"https://twitter.com/PlatformIO_Org", fg="cyan"))) click.style("https://twitter.com/PlatformIO_Org", fg="cyan")))
click.echo("- %s it on GitHub > %s" % click.echo(
(click.style("star", fg="cyan"), click.style( "- %s it on GitHub > %s" %
"https://github.com/platformio/platformio", fg="cyan"))) (click.style("star", fg="cyan"),
click.style("https://github.com/platformio/platformio", fg="cyan")))
if not getenv("PLATFORMIO_IDE"): if not getenv("PLATFORMIO_IDE"):
click.echo("- %s PlatformIO IDE for IoT development > %s" % click.echo(
(click.style("try", fg="cyan"), click.style( "- %s PlatformIO IDE for IoT development > %s" %
"http://platformio.org/platformio-ide", fg="cyan"))) (click.style("try", fg="cyan"),
click.style("http://platformio.org/platformio-ide", fg="cyan")))
if not util.is_ci(): if not util.is_ci():
click.echo("- %s us with PlatformIO Plus > %s" % (click.style( click.echo("- %s us with PlatformIO Plus > %s" %
"support", fg="cyan"), click.style( (click.style("support", fg="cyan"),
"https://pioplus.com", fg="cyan"))) click.style("https://pioplus.com", fg="cyan")))
click.echo("*" * terminal_width) click.echo("*" * terminal_width)
click.echo("") click.echo("")
@ -256,8 +286,8 @@ def check_internal_updates(ctx, what):
if manifest['name'] in outdated_items: if manifest['name'] in outdated_items:
continue continue
conds = [ conds = [
pm.outdated(manifest['__pkg_dir']), what == "platforms" and pm.outdated(manifest['__pkg_dir']),
PlatformFactory.newPlatform( what == "platforms" and PlatformFactory.newPlatform(
manifest['__pkg_dir']).are_outdated_packages() manifest['__pkg_dir']).are_outdated_packages()
] ]
if any(conds): if any(conds):
@ -271,8 +301,8 @@ def check_internal_updates(ctx, what):
click.echo("") click.echo("")
click.echo("*" * terminal_width) click.echo("*" * terminal_width)
click.secho( click.secho(
"There are the new updates for %s (%s)" % "There are the new updates for %s (%s)" % (what,
(what, ", ".join(outdated_items)), ", ".join(outdated_items)),
fg="yellow") fg="yellow")
if not app.get_setting("auto_update_" + what): if not app.get_setting("auto_update_" + what):

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -17,12 +17,12 @@ import subprocess
import sys import sys
from os.path import join from os.path import join
from platformio import exception, util from platformio import __version__, exception, util
from platformio.managers.package import PackageManager from platformio.managers.package import PackageManager
CORE_PACKAGES = { CORE_PACKAGES = {
"pysite-pioplus": ">=0.3.0,<2", "pysite-pioplus": ">=0.3.0,<2",
"tool-pioplus": ">=0.6.10,<2", "tool-pioplus": ">=0.9.0,<2",
"tool-unity": "~1.20302.1", "tool-unity": "~1.20302.1",
"tool-scons": "~3.20501.2" "tool-scons": "~3.20501.2"
} }
@ -41,6 +41,33 @@ class CorePackageManager(PackageManager):
("" if sys.version_info < (2, 7, 9) else "s") ("" if sys.version_info < (2, 7, 9) else "s")
]) ])
def install(self, name, requirements=None, *args,
**kwargs): # pylint: disable=arguments-differ
PackageManager.install(self, name, requirements, *args, **kwargs)
self.cleanup_packages()
return self.get_package_dir(name, requirements)
def update(self, *args, **kwargs): # pylint: disable=arguments-differ
result = PackageManager.update(self, *args, **kwargs)
self.cleanup_packages()
return result
def cleanup_packages(self):
self.cache_reset()
best_pkg_versions = {}
for name, requirements in CORE_PACKAGES.items():
pkg_dir = self.get_package_dir(name, requirements)
if not pkg_dir:
continue
best_pkg_versions[name] = self.load_manifest(pkg_dir)['version']
for manifest in self.get_installed():
if manifest['name'] not in best_pkg_versions:
continue
if manifest['version'] != best_pkg_versions[manifest['name']]:
self.uninstall(manifest['__pkg_dir'], trigger_event=False)
self.cache_reset()
return True
def get_core_package_dir(name): def get_core_package_dir(name):
assert name in CORE_PACKAGES assert name in CORE_PACKAGES
@ -63,6 +90,13 @@ def update_core_packages(only_check=False, silent=False):
def pioplus_call(args, **kwargs): def pioplus_call(args, **kwargs):
if "windows" in util.get_systype() and sys.version_info < (2, 7, 6):
raise exception.PlatformioException(
"PlatformIO Core Plus v%s does not run under Python version %s.\n"
"Minimum supported version is 2.7.6, please upgrade Python.\n"
"Python 3 is not yet supported.\n" % (__version__,
sys.version.split()[0]))
pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus") pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path() os.environ['PYTHONEXEPATH'] = util.get_pythonexe_path()
os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("pysite-pioplus") os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("pysite-pioplus")

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -64,7 +64,7 @@ class LibraryManager(BasePkgManager):
if not manifest: if not manifest:
return manifest return manifest
# if Arudino library.properties # if Arduino library.properties
if "sentence" in manifest: if "sentence" in manifest:
manifest['frameworks'] = ["arduino"] manifest['frameworks'] = ["arduino"]
manifest['description'] = manifest['sentence'] manifest['description'] = manifest['sentence']
@ -226,9 +226,9 @@ class LibraryManager(BasePkgManager):
cache_valid="30d") cache_valid="30d")
assert dl_data assert dl_data
return self._install_from_url( return self._install_from_url(name, dl_data['url'].replace(
name, dl_data['url'].replace("http://", "https://") "http://", "https://") if app.get_setting("enable_ssl") else
if app.get_setting("enable_ssl") else dl_data['url'], requirements) dl_data['url'], requirements)
def install( # pylint: disable=arguments-differ def install( # pylint: disable=arguments-differ
self, self,
@ -239,8 +239,8 @@ class LibraryManager(BasePkgManager):
interactive=False): interactive=False):
pkg_dir = None pkg_dir = None
try: try:
_name, _requirements, _url = self.parse_pkg_input(name, _name, _requirements, _url = self.parse_pkg_input(
requirements) name, requirements)
if not _url: if not _url:
name = "id=%d" % self.get_pkg_id_by_name( name = "id=%d" % self.get_pkg_id_by_name(
_name, _name,
@ -309,8 +309,9 @@ class LibraryManager(BasePkgManager):
if not isinstance(values, list): if not isinstance(values, list):
values = [v.strip() for v in values.split(",") if v] values = [v.strip() for v in values.split(",") if v]
for value in values: for value in values:
query.append('%s:"%s"' % (key[:-1] if key.endswith("s") else query.append('%s:"%s"' % (key[:-1]
key, value)) if key.endswith("s") else key,
value))
lib_info = None lib_info = None
result = util.get_api_result( result = util.get_api_result(

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@ import codecs
import hashlib import hashlib
import json import json
import os import os
import re
import shutil import shutil
from os.path import basename, getsize, isdir, isfile, islink, join from os.path import basename, getsize, isdir, isfile, islink, join
from tempfile import mkdtemp from tempfile import mkdtemp
@ -69,8 +70,7 @@ class PackageRepoIterator(object):
if self.package in manifest: if self.package in manifest:
return manifest[self.package] return manifest[self.package]
else: return self.next()
return self.next()
class PkgRepoMixin(object): class PkgRepoMixin(object):
@ -192,12 +192,14 @@ class PkgInstallerMixin(object):
@staticmethod @staticmethod
def get_install_dirname(manifest): def get_install_dirname(manifest):
name = manifest['name'] name = re.sub(r"[^\da-z\_\-\. ]", "_", manifest['name'], flags=re.I)
if "id" in manifest: if "id" in manifest:
name += "_ID%d" % manifest['id'] name += "_ID%d" % manifest['id']
return name return name
def get_src_manifest_path(self, pkg_dir): def get_src_manifest_path(self, pkg_dir):
if not isdir(pkg_dir):
return None
for item in os.listdir(pkg_dir): for item in os.listdir(pkg_dir):
if not isdir(join(pkg_dir, item)): if not isdir(join(pkg_dir, item)):
continue continue
@ -224,20 +226,19 @@ class PkgInstallerMixin(object):
if result: if result:
return result return result
manifest_path = self.get_manifest_path(pkg_dir) manifest = {}
if not manifest_path:
return None
# if non-registry packages: VCS or archive
src_manifest_path = self.get_src_manifest_path(pkg_dir)
src_manifest = None src_manifest = None
manifest_path = self.get_manifest_path(pkg_dir)
src_manifest_path = self.get_src_manifest_path(pkg_dir)
if src_manifest_path: if src_manifest_path:
src_manifest = util.load_json(src_manifest_path) src_manifest = util.load_json(src_manifest_path)
manifest = {} if not manifest_path and not src_manifest_path:
if manifest_path.endswith(".json"): return None
if manifest_path and manifest_path.endswith(".json"):
manifest = util.load_json(manifest_path) manifest = util.load_json(manifest_path)
elif manifest_path.endswith(".properties"): elif manifest_path and manifest_path.endswith(".properties"):
with codecs.open(manifest_path, encoding="utf-8") as fp: with codecs.open(manifest_path, encoding="utf-8") as fp:
for line in fp.readlines(): for line in fp.readlines():
if "=" not in line: if "=" not in line:
@ -305,7 +306,8 @@ class PkgInstallerMixin(object):
def get_package_dir(self, name, requirements=None, url=None): def get_package_dir(self, name, requirements=None, url=None):
manifest = self.get_package(name, requirements, url) manifest = self.get_package(name, requirements, url)
return manifest.get("__pkg_dir") if manifest else None return manifest.get("__pkg_dir") if manifest and isdir(
manifest.get("__pkg_dir")) else None
def find_pkg_root(self, src_dir): def find_pkg_root(self, src_dir):
if self.manifest_exists(src_dir): if self.manifest_exists(src_dir):
@ -345,7 +347,6 @@ class PkgInstallerMixin(object):
requirements=None, requirements=None,
sha1=None, sha1=None,
track=False): track=False):
pkg_dir = None
tmp_dir = mkdtemp("-package", "_tmp_installing-", self.package_dir) tmp_dir = mkdtemp("-package", "_tmp_installing-", self.package_dir)
src_manifest_dir = None src_manifest_dir = None
src_manifest = {"name": name, "url": url, "requirements": requirements} src_manifest = {"name": name, "url": url, "requirements": requirements}
@ -369,19 +370,20 @@ class PkgInstallerMixin(object):
src_manifest_dir = vcs.storage_dir src_manifest_dir = vcs.storage_dir
src_manifest['version'] = vcs.get_current_revision() src_manifest['version'] = vcs.get_current_revision()
pkg_dir = self.find_pkg_root(tmp_dir) _tmp_dir = tmp_dir
if not src_manifest_dir:
_tmp_dir = self.find_pkg_root(tmp_dir)
src_manifest_dir = join(_tmp_dir, ".pio")
# write source data to a special manifest # write source data to a special manifest
if track: if track:
if not src_manifest_dir:
src_manifest_dir = join(pkg_dir, ".pio")
self._update_src_manifest(src_manifest, src_manifest_dir) self._update_src_manifest(src_manifest, src_manifest_dir)
pkg_dir = self._install_from_tmp_dir(pkg_dir, requirements) return self._install_from_tmp_dir(_tmp_dir, requirements)
finally: finally:
if isdir(tmp_dir): if isdir(tmp_dir):
util.rmtree_(tmp_dir) util.rmtree_(tmp_dir)
return pkg_dir return
def _update_src_manifest(self, data, src_dir): def _update_src_manifest(self, data, src_dir):
if not isdir(src_dir): if not isdir(src_dir):
@ -417,8 +419,8 @@ class PkgInstallerMixin(object):
# package should satisfy requirements # package should satisfy requirements
if requirements: if requirements:
mismatch_error = ( mismatch_error = (
"Package version %s doesn't satisfy requirements %s" % ( "Package version %s doesn't satisfy requirements %s" %
tmp_manifest['version'], requirements)) (tmp_manifest['version'], requirements))
try: try:
assert tmp_semver and tmp_semver in semantic_version.Spec( assert tmp_semver and tmp_semver in semantic_version.Spec(
requirements), mismatch_error requirements), mismatch_error
@ -497,10 +499,10 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
url_marker = "://" url_marker = "://"
req_conditions = [ req_conditions = [
not requirements, "@" in text, not requirements,
(url_marker != "git@" and "://git@" not in text) or "@" in text,
text.count("@") > 1 not url_marker.startswith("git")
] ] # yapf: disable
if all(req_conditions): if all(req_conditions):
text, requirements = text.rsplit("@", 1) text, requirements = text.rsplit("@", 1)
if text.isdigit(): if text.isdigit():
@ -650,18 +652,18 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
if isdir(package): if isdir(package):
pkg_dir = package pkg_dir = package
else: else:
name, requirements, url = self.parse_pkg_input(package, name, requirements, url = self.parse_pkg_input(
requirements) package, requirements)
pkg_dir = self.get_package_dir(name, requirements, url) pkg_dir = self.get_package_dir(name, requirements, url)
if not pkg_dir: if not pkg_dir:
raise exception.UnknownPackage("%s @ %s" % raise exception.UnknownPackage("%s @ %s" % (package,
(package, requirements or "*")) requirements or "*"))
manifest = self.load_manifest(pkg_dir) manifest = self.load_manifest(pkg_dir)
click.echo( click.echo(
"Uninstalling %s @ %s: \t" % (click.style( "Uninstalling %s @ %s: \t" %
manifest['name'], fg="cyan"), manifest['version']), (click.style(manifest['name'], fg="cyan"), manifest['version']),
nl=False) nl=False)
if islink(pkg_dir): if islink(pkg_dir):
@ -673,9 +675,9 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
# unfix package with the same name # unfix package with the same name
pkg_dir = self.get_package_dir(manifest['name']) pkg_dir = self.get_package_dir(manifest['name'])
if pkg_dir and "@" in pkg_dir: if pkg_dir and "@" in pkg_dir:
os.rename( os.rename(pkg_dir,
pkg_dir, join(self.package_dir,
join(self.package_dir, self.get_install_dirname(manifest))) self.get_install_dirname(manifest)))
self.cache_reset() self.cache_reset()
click.echo("[%s]" % click.style("OK", fg="green")) click.echo("[%s]" % click.style("OK", fg="green"))
@ -698,8 +700,8 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
pkg_dir = self.get_package_dir(*self.parse_pkg_input(package)) pkg_dir = self.get_package_dir(*self.parse_pkg_input(package))
if not pkg_dir: if not pkg_dir:
raise exception.UnknownPackage("%s @ %s" % raise exception.UnknownPackage("%s @ %s" % (package,
(package, requirements or "*")) requirements or "*"))
manifest = self.load_manifest(pkg_dir) manifest = self.load_manifest(pkg_dir)
name = manifest['name'] name = manifest['name']

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -63,7 +63,7 @@ class PlatformManager(BasePkgManager):
skip_default_package=False, skip_default_package=False,
trigger_event=True, trigger_event=True,
silent=False, silent=False,
**_): # pylint: disable=too-many-arguments **_): # pylint: disable=too-many-arguments, arguments-differ
platform_dir = BasePkgManager.install( platform_dir = BasePkgManager.install(
self, name, requirements, silent=silent) self, name, requirements, silent=silent)
p = PlatformFactory.newPlatform(platform_dir) p = PlatformFactory.newPlatform(platform_dir)
@ -84,8 +84,8 @@ class PlatformManager(BasePkgManager):
if isdir(package): if isdir(package):
pkg_dir = package pkg_dir = package
else: else:
name, requirements, url = self.parse_pkg_input(package, name, requirements, url = self.parse_pkg_input(
requirements) package, requirements)
pkg_dir = self.get_package_dir(name, requirements, url) pkg_dir = self.get_package_dir(name, requirements, url)
p = PlatformFactory.newPlatform(pkg_dir) p = PlatformFactory.newPlatform(pkg_dir)
@ -108,8 +108,8 @@ class PlatformManager(BasePkgManager):
if isdir(package): if isdir(package):
pkg_dir = package pkg_dir = package
else: else:
name, requirements, url = self.parse_pkg_input(package, name, requirements, url = self.parse_pkg_input(
requirements) package, requirements)
pkg_dir = self.get_package_dir(name, requirements, url) pkg_dir = self.get_package_dir(name, requirements, url)
p = PlatformFactory.newPlatform(pkg_dir) p = PlatformFactory.newPlatform(pkg_dir)
@ -207,8 +207,8 @@ class PlatformFactory(object):
else: else:
if not requirements and "@" in name: if not requirements and "@" in name:
name, requirements = name.rsplit("@", 1) name, requirements = name.rsplit("@", 1)
platform_dir = PlatformManager().get_package_dir(name, platform_dir = PlatformManager().get_package_dir(
requirements) name, requirements)
if not platform_dir: if not platform_dir:
raise exception.UnknownPlatform(name if not requirements else raise exception.UnknownPlatform(name if not requirements else
@ -305,9 +305,7 @@ class PlatformPackagesMixin(object):
version = self.packages[name].get("version", "") version = self.packages[name].get("version", "")
if self.is_valid_requirements(version): if self.is_valid_requirements(version):
return self.pm.get_package_dir(name, version) return self.pm.get_package_dir(name, version)
else: return self.pm.get_package_dir(*self._parse_pkg_input(name, version))
return self.pm.get_package_dir(*self._parse_pkg_input(name,
version))
def get_package_version(self, name): def get_package_version(self, name):
pkg_dir = self.get_package_dir(name) pkg_dir = self.get_package_dir(name)
@ -360,7 +358,8 @@ class PlatformRunMixin(object):
util.get_pythonexe_path(), util.get_pythonexe_path(),
join(get_core_package_dir("tool-scons"), "script", "scons"), "-Q", join(get_core_package_dir("tool-scons"), "script", "scons"), "-Q",
"-j %d" % self.get_job_nums(), "--warn=no-no-parallel-support", "-j %d" % self.get_job_nums(), "--warn=no-no-parallel-support",
"-f", join(util.get_source_dir(), "builder", "main.py") "-f",
join(util.get_source_dir(), "builder", "main.py")
] ]
cmd.append("PIOVERBOSE=%d" % (1 if self.verbose else 0)) cmd.append("PIOVERBOSE=%d" % (1 if self.verbose else 0))
cmd += targets cmd += targets
@ -581,8 +580,10 @@ class PlatformBase( # pylint: disable=too-many-public-methods
if not isdir(libcore_dir): if not isdir(libcore_dir):
continue continue
storages.append({ storages.append({
"name": "%s-core-%s" % (opts['package'], item), "name":
"path": libcore_dir "%s-core-%s" % (opts['package'], item),
"path":
libcore_dir
}) })
return storages return storages
@ -645,6 +646,18 @@ class PlatformBoardConfig(object):
"ram": self._manifest.get("upload", {}).get("maximum_ram_size", 0), "ram": self._manifest.get("upload", {}).get("maximum_ram_size", 0),
"rom": self._manifest.get("upload", {}).get("maximum_size", 0), "rom": self._manifest.get("upload", {}).get("maximum_size", 0),
"frameworks": self._manifest.get("frameworks"), "frameworks": self._manifest.get("frameworks"),
"debug": self.get_debug_data(),
"vendor": self._manifest['vendor'], "vendor": self._manifest['vendor'],
"url": self._manifest['url'] "url": self._manifest['url']
} }
def get_debug_data(self):
if not self._manifest.get("debug", {}).get("tools"):
return
tools = {}
for name, options in self._manifest['debug']['tools'].items():
tools[name] = {}
for key, value in options.items():
if key in ("default", "onboard"):
tools[name][key] = value
return {"tools": tools}

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -255,8 +255,9 @@ def measure_ci():
"label": getenv("APPVEYOR_REPO_NAME") "label": getenv("APPVEYOR_REPO_NAME")
}, },
"CIRCLECI": { "CIRCLECI": {
"label": "%s/%s" % (getenv("CIRCLE_PROJECT_USERNAME"), "label":
getenv("CIRCLE_PROJECT_REPONAME")) "%s/%s" % (getenv("CIRCLE_PROJECT_USERNAME"),
getenv("CIRCLE_PROJECT_REPONAME"))
}, },
"TRAVIS": { "TRAVIS": {
"label": getenv("TRAVIS_REPO_SLUG") "label": getenv("TRAVIS_REPO_SLUG")
@ -278,7 +279,10 @@ def measure_ci():
def on_run_environment(options, targets): def on_run_environment(options, targets):
opts = ["%s=%s" % (opt, value) for opt, value in sorted(options.items())] opts = [
"%s=%s" % (opt, value.replace("\n", ", ") if "\n" in value else value)
for opt, value in sorted(options.items())
]
targets = [t.title() for t in targets or ["run"]] targets = [t.title() for t in targets or ["run"]]
on_event("Env", " ".join(targets), "&".join(opts)) on_event("Env", " ".join(targets), "&".join(opts))

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ import socket
import stat import stat
import subprocess import subprocess
import sys import sys
from contextlib import contextmanager
from glob import glob from glob import glob
from os.path import (abspath, basename, dirname, expanduser, isdir, isfile, from os.path import (abspath, basename, dirname, expanduser, isdir, isfile,
join, normpath, splitdrive) join, normpath, splitdrive)
@ -46,7 +47,7 @@ class ProjectConfig(ConfigParser):
VARTPL_RE = re.compile(r"\$\{([^\.\}]+)\.([^\}]+)\}") VARTPL_RE = re.compile(r"\$\{([^\.\}]+)\.([^\}]+)\}")
def items(self, section, **_): def items(self, section, **_): # pylint: disable=arguments-differ
items = [] items = []
for option in ConfigParser.options(self, section): for option in ConfigParser.options(self, section):
items.append((option, self.get(section, option))) items.append((option, self.get(section, option)))
@ -130,10 +131,9 @@ class memoized(object):
return self.func(*args) return self.func(*args)
if args in self.cache: if args in self.cache:
return self.cache[args] return self.cache[args]
else: value = self.func(*args)
value = self.func(*args) self.cache[args] = value
self.cache[args] = value return value
return value
def __repr__(self): def __repr__(self):
'''Return the function's docstring.''' '''Return the function's docstring.'''
@ -161,13 +161,21 @@ def singleton(cls):
return get_instance return get_instance
@contextmanager
def capture_stdout(output):
stdout = sys.stdout
sys.stdout = output
yield
sys.stdout = stdout
def load_json(file_path): def load_json(file_path):
try: try:
with open(file_path, "r") as f: with open(file_path, "r") as f:
return json.load(f) return json.load(f)
except ValueError: except ValueError:
raise exception.PlatformioException("Could not load broken JSON: %s" % raise exception.PlatformioException(
file_path) "Could not load broken JSON: %s" % file_path)
def get_systype(): def get_systype():
@ -212,15 +220,19 @@ def get_project_optional_dir(name, default=None):
def get_home_dir(): def get_home_dir():
home_dir = get_project_optional_dir("home_dir", home_dir = get_project_optional_dir("home_dir",
join(expanduser("~"), ".platformio")) join(expanduser("~"), ".platformio"))
win_home_dir = None
if "windows" in get_systype(): if "windows" in get_systype():
try: win_home_dir = splitdrive(home_dir)[0] + "\\.platformio"
home_dir.encode("utf8") if isdir(win_home_dir):
except UnicodeDecodeError: home_dir = win_home_dir
home_dir = splitdrive(home_dir)[0] + "\\.platformio"
if not isdir(home_dir): if not isdir(home_dir):
os.makedirs(home_dir) try:
os.makedirs(home_dir)
except: # pylint: disable=bare-except
if win_home_dir:
os.makedirs(win_home_dir)
home_dir = win_home_dir
assert isdir(home_dir) assert isdir(home_dir)
return home_dir return home_dir
@ -270,8 +282,8 @@ def get_projectsrc_dir():
def get_projecttest_dir(): def get_projecttest_dir():
return get_project_optional_dir("test_dir", return get_project_optional_dir("test_dir", join(get_project_dir(),
join(get_project_dir(), "test")) "test"))
def get_projectboards_dir(): def get_projectboards_dir():
@ -299,8 +311,8 @@ URL=http://docs.platformio.org/page/projectconf.html#envs-dir
def get_projectdata_dir(): def get_projectdata_dir():
return get_project_optional_dir("data_dir", return get_project_optional_dir("data_dir", join(get_project_dir(),
join(get_project_dir(), "data")) "data"))
def load_project_config(path=None): def load_project_config(path=None):
@ -465,14 +477,14 @@ def _get_api_result(
data=data, data=data,
headers=headers, headers=headers,
auth=auth, auth=auth,
verify=disable_ssl_check) verify=not disable_ssl_check)
else: else:
r = _api_request_session().get( r = _api_request_session().get(
url, url,
params=params, params=params,
headers=headers, headers=headers,
auth=auth, auth=auth,
verify=disable_ssl_check) verify=not disable_ssl_check)
result = r.json() result = r.json()
r.raise_for_status() r.raise_for_status()
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
@ -483,8 +495,8 @@ def _get_api_result(
else: else:
raise exception.APIRequestError(e) raise exception.APIRequestError(e)
except ValueError: except ValueError:
raise exception.APIRequestError("Invalid response: %s" % raise exception.APIRequestError(
r.text.encode("utf-8")) "Invalid response: %s" % r.text.encode("utf-8"))
finally: finally:
if r: if r:
r.close() r.close()
@ -528,14 +540,15 @@ def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
def internet_on(timeout=3): def internet_on(timeout=3):
host = "8.8.8.8" socket.setdefaulttimeout(timeout)
port = 53 for host in ("dl.bintray.com", "dl.platformio.org"):
try: try:
socket.setdefaulttimeout(timeout) socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host,
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port)) 80))
return True return True
except: # pylint: disable=bare-except except: # pylint: disable=bare-except
return False pass
return False
def get_pythonexe_path(): def get_pythonexe_path():

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -37,8 +37,8 @@ class VCSClientFactory(object):
if "#" in remote_url: if "#" in remote_url:
remote_url, tag = remote_url.rsplit("#", 1) remote_url, tag = remote_url.rsplit("#", 1)
if not type_: if not type_:
raise PlatformioException("VCS: Unknown repository type %s" % raise PlatformioException(
remote_url) "VCS: Unknown repository type %s" % remote_url)
obj = getattr(modules[__name__], "%sClient" % type_.title())( obj = getattr(modules[__name__], "%sClient" % type_.title())(
src_dir, remote_url, tag, silent) src_dir, remote_url, tag, silent)
assert isinstance(obj, VCSClientBase) assert isinstance(obj, VCSClientBase)
@ -103,8 +103,8 @@ class VCSClientBase(object):
if result['returncode'] == 0: if result['returncode'] == 0:
return result['out'].strip() return result['out'].strip()
raise PlatformioException( raise PlatformioException(
"VCS: Could not receive an output from `%s` command (%s)" % ( "VCS: Could not receive an output from `%s` command (%s)" %
args, result)) (args, result))
class GitClient(VCSClientBase): class GitClient(VCSClientBase):
@ -152,7 +152,7 @@ class GitClient(VCSClientBase):
return True return True
def update(self): def update(self):
args = ["pull"] args = ["pull", "--recurse-submodules"]
return self.run_cmd(args) return self.run_cmd(args)
def get_current_revision(self): def get_current_revision(self):

View File

@ -0,0 +1,163 @@
# UDEV Rules for debug adapters/boards supported by OpenOCD
#
# INSTALLATION
#
#
# The latest version of this file may be found at:
# https://github.com/platformio/platformio-core/blob/develop/scripts/98-openocd-udev.rules
#
# This file must be placed at:
# /etc/udev/rules.d/98-openocd-udev.rules (preferred location)
# or
# /lib/udev/rules.d/98-openocd-udev.rules (req'd on some broken systems)
#
# To install, type this command in a terminal:
# sudo cp 98-openocd-udev.rules /etc/udev/rules.d/98-openocd-udev.rules
#
# Restart "udev" management tool:
# sudo service udev restart
# or
# sudo udevadm control --reload-rules
# sudo udevadm trigger
#
# Ubuntu/Debian users may need to add own “username” to the “dialout” group if
# they are not “root”, doing this issuing a
# sudo usermod -a -G dialout $USER
# sudo usermod -a -G plugdev $USER
#
# After this file is installed, physically unplug and reconnect your adapter/board.
ACTION!="add|change", GOTO="openocd_rules_end"
SUBSYSTEM!="usb|tty|hidraw", GOTO="openocd_rules_end"
# Please keep this list sorted by VID:PID
# opendous and estick
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204f", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Original FT232/FT245 VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Original FT2232 VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Original FT4232 VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6011", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Original FT232H VID:PID
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", MODE="660", GROUP="plugdev", TAG+="uaccess"
# DISTORTEC JTAG-lock-pick Tiny 2
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8220", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TUMPA, TUMPA Lite
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a98", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8a99", MODE="660", GROUP="plugdev", TAG+="uaccess"
# XDS100v2
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="a6d0", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca0", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bca1", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI/Luminary Stellaris Evaluation Board FTDI (several)
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcd9", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bcda", MODE="660", GROUP="plugdev", TAG+="uaccess"
# egnite Turtelizer 2
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="bdc8", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Section5 ICEbear
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c140", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="c141", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Amontec JTAGkey and JTAGkey-tiny
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="cff8", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI ICDI
ATTRS{idVendor}=="0451", ATTRS{idProduct}=="c32a", MODE="660", GROUP="plugdev", TAG+="uaccess"
# STLink v1
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", MODE="660", GROUP="plugdev", TAG+="uaccess"
# STLink v2
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="660", GROUP="plugdev", TAG+="uaccess"
# STLink v2-1
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Hilscher NXHX Boards
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="0028", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Hitex STR9-comStick
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002c", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Hitex STM32-PerformanceStick
ATTRS{idVendor}=="0640", ATTRS{idProduct}=="002d", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Altera USB Blaster
ATTRS{idVendor}=="09fb", ATTRS{idProduct}=="6001", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Amontec JTAGkey-HiSpeed
ATTRS{idVendor}=="0fbb", ATTRS{idProduct}=="1000", MODE="660", GROUP="plugdev", TAG+="uaccess"
# SEGGER J-Link
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0101", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0102", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0103", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0104", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0105", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0107", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="0108", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1010", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1011", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1012", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1013", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1014", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1015", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1016", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1017", MODE="660", GROUP="plugdev", TAG+="uaccess"
ATTRS{idVendor}=="1366", ATTRS{idProduct}=="1018", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Raisonance RLink
ATTRS{idVendor}=="138e", ATTRS{idProduct}=="9000", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Debug Board for Neo1973
ATTRS{idVendor}=="1457", ATTRS{idProduct}=="5118", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Olimex ARM-USB-OCD
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0003", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Olimex ARM-USB-OCD-TINY
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="0004", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Olimex ARM-JTAG-EW
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="001e", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Olimex ARM-USB-OCD-TINY-H
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002a", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Olimex ARM-USB-OCD-H
ATTRS{idVendor}=="15ba", ATTRS{idProduct}=="002b", MODE="660", GROUP="plugdev", TAG+="uaccess"
# USBprog with OpenOCD firmware
ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c63", MODE="660", GROUP="plugdev", TAG+="uaccess"
# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board
ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="00fd", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Marvell Sheevaplug
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", MODE="660", GROUP="plugdev", TAG+="uaccess"
# Keil Software, Inc. ULink
ATTRS{idVendor}=="c251", ATTRS{idProduct}=="2710", MODE="660", GROUP="plugdev", TAG+="uaccess"
# CMSIS-DAP compatible adapters
ATTRS{product}=="*CMSIS-DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess"
LABEL="openocd_rules_end"

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -12,6 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
#
# INSTALLATION
#
# UDEV Rules for PlatformIO supported boards, http://platformio.org/boards # UDEV Rules for PlatformIO supported boards, http://platformio.org/boards
# #
# The latest version of this file may be found at: # The latest version of this file may be found at:
@ -31,6 +35,11 @@
# sudo udevadm control --reload-rules # sudo udevadm control --reload-rules
# sudo udevadm trigger # sudo udevadm trigger
# #
# Ubuntu/Debian users may need to add own “username” to the “dialout” group if
# they are not “root”, doing this issuing a
# sudo usermod -a -G dialout $USER
# sudo usermod -a -G plugdev $USER
#
# After this file is installed, physically unplug and reconnect your board. # After this file is installed, physically unplug and reconnect your board.
# CP210X USB UART # CP210X USB UART
@ -65,6 +74,9 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374?", MODE:="066
# USBtiny # USBtiny
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE="0666" SUBSYSTEMS=="usb", ATTRS{idProduct}=="0c9f", ATTRS{idVendor}=="1781", MODE="0666"
# USBasp V2.0
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", MODE:="0666"
# Teensy boards # Teensy boards
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}="1" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1" ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789]?", ENV{MTP_NO_PROBE}="1"

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -36,7 +36,7 @@ def is_compat_platform_and_framework(platform, framework):
return False return False
def generate_boards(boards): def generate_boards(boards, extend_debug=False):
def _round_memory_size(size): def _round_memory_size(size):
if size == 1: if size == 1:
@ -48,6 +48,8 @@ def generate_boards(boards):
return int(ceil(size / b) * b) return int(ceil(size / b) * b)
assert NotImplemented() assert NotImplemented()
platforms = {m['name']: m['title'] for m in PLATFORM_MANIFESTS}
lines = [] lines = []
lines.append(""" lines.append("""
@ -56,22 +58,44 @@ def generate_boards(boards):
* - ID * - ID
- Name - Name
- Platform
- Debug
- Microcontroller - Microcontroller
- Frequency - Frequency
- Flash - Flash
- RAM""") - RAM""")
for data in sorted(boards, key=lambda item: item['id']): for data in sorted(boards, key=lambda item: item['id']):
debug = [":ref:`Yes <piodebug>`" if data['debug'] else ""]
if extend_debug and data['debug']:
debug = []
for name, options in data['debug']['tools'].items():
attrs = []
if options.get("default"):
attrs.append("default")
if options.get("onboard"):
attrs.append("on-board")
tool = ":ref:`debugging_tool_%s`" % name
if attrs:
debug.append("%s (%s)" % (tool, ", ".join(attrs)))
else:
debug.append(tool)
board_ram = float(data['ram']) / 1024 board_ram = float(data['ram']) / 1024
lines.append(""" lines.append("""
* - ``{id}`` * - ``{id}``
- `{name} <{url}>`_ - `{name} <{url}>`_
- :ref:`{platform_title} <platform_{platform}>`
- {debug}
- {mcu} - {mcu}
- {f_cpu:d} MHz - {f_cpu:d} MHz
- {rom} Kb - {rom} Kb
- {ram} Kb""".format( - {ram} Kb""".format(
id=data['id'], id=data['id'],
name=data['name'], name=data['name'],
platform=data['platform'],
platform_title=platforms[data['platform']],
debug=", ".join(debug),
url=data['url'], url=data['url'],
mcu=data['mcu'].upper(), mcu=data['mcu'].upper(),
f_cpu=int(data['fcpu']) / 1000000, f_cpu=int(data['fcpu']) / 1000000,
@ -108,29 +132,29 @@ Packages
.. warning:: .. warning::
**Linux Users**: **Linux Users**:
* Ubuntu/Debian users may need to add own "username" to the "dialout" * Install "udev" rules file `99-platformio-udev.rules <https://github.com/platformio/platformio-core/blob/develop/scripts/99-platformio-udev.rules>`_
group if they are not "root", doing this issuing a (an instruction is located inside a file).
``sudo usermod -a -G dialout yourusername``. * Raspberry Pi users, please read this article
* Install "udev" rules file `99-platformio-udev.rules <https://github.com/platformio/platformio-core/blob/develop/scripts/99-platformio-udev.rules>`_ `Enable serial port on Raspberry Pi <https://hallard.me/enable-serial-port-on-raspberry-pi/>`__.
(an instruction is located in the file).
* Raspberry Pi users, please read this article
`Enable serial port on Raspberry Pi <https://hallard.me/enable-serial-port-on-raspberry-pi/>`__.
""") """)
if platform == "teensy": if platform == "teensy":
lines.append(""" lines.append("""
**Windows Users:** Teensy programming uses only Windows built-in HID **Windows Users:**
drivers. When Teensy is programmed to act as a USB Serial device,
Windows XP, Vista, 7 and 8 require `this serial driver Teensy programming uses only Windows built-in HID
<http://www.pjrc.com/teensy/serial_install.exe>`_ drivers. When Teensy is programmed to act as a USB Serial device,
is needed to access the COM port your program uses. No special driver Windows XP, Vista, 7 and 8 require `this serial driver
installation is necessary on Windows 10. <http://www.pjrc.com/teensy/serial_install.exe>`_
is needed to access the COM port your program uses. No special driver
installation is necessary on Windows 10.
""") """)
else: else:
lines.append(""" lines.append("""
**Windows Users:** Please check that you have correctly installed USB **Windows Users:**
driver from board manufacturer
Please check that you have a correctly installed USB driver from board
manufacturer
""") """)
return "\n".join(lines) return "\n".join(lines)
@ -141,7 +165,7 @@ def generate_platform(name):
lines = [] lines = []
lines.append( lines.append(
""".. Copyright 2014-present PlatformIO <contact@platformio.org> """.. Copyright (c) 2014-present PlatformIO <contact@platformio.org>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -152,21 +176,22 @@ def generate_platform(name):
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
""") """)
p = PlatformFactory.newPlatform(name)
lines.append(".. _platform_%s:" % name) lines.append(".. _platform_%s:" % p.name)
lines.append("") lines.append("")
_title = "Platform ``%s``" % name lines.append(p.title)
lines.append(_title) lines.append("=" * len(p.title))
lines.append("=" * len(_title)) lines.append(":ref:`projectconf_env_platform` = ``%s``" % p.name)
lines.append("")
p = PlatformFactory.newPlatform(name)
lines.append(p.description) lines.append(p.description)
lines.append(""" lines.append("""
For more detailed information please visit `vendor site <%s>`_.""" % For more detailed information please visit `vendor site <%s>`_.""" %
p.vendor_url) p.vendor_url)
lines.append(""" lines.append("""
.. contents::""") .. contents:: Contents
:local:""")
# #
# Packages # Packages
@ -247,7 +272,7 @@ def generate_framework(type_, data):
lines = [] lines = []
lines.append( lines.append(
""".. Copyright 2014-present PlatformIO <contact@platformio.org> """.. Copyright (c) 2014-present PlatformIO <contact@platformio.org>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -262,15 +287,18 @@ def generate_framework(type_, data):
lines.append(".. _framework_%s:" % type_) lines.append(".. _framework_%s:" % type_)
lines.append("") lines.append("")
_title = "Framework ``%s``" % type_ lines.append(data['title'])
lines.append(_title) lines.append("=" * len(data['title']))
lines.append("=" * len(_title)) lines.append(":ref:`projectconf_env_framework` = ``%s``" % type_)
lines.append("")
lines.append(data['description']) lines.append(data['description'])
lines.append(""" lines.append("""
For more detailed information please visit `vendor site <%s>`_. For more detailed information please visit `vendor site <%s>`_.
""" % data['url']) """ % data['url'])
lines.append(".. contents::") lines.append("""
.. contents:: Contents
:local:""")
lines.append(""" lines.append("""
Platforms Platforms
@ -371,7 +399,7 @@ def update_embedded_boards():
lines = [] lines = []
lines.append( lines.append(
""".. Copyright 2014-present PlatformIO <contact@platformio.org> """.. Copyright (c) 2014-present PlatformIO <contact@platformio.org>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -394,14 +422,16 @@ Rapid Embedded Development, Continuous and IDE integration in a few
steps with PlatformIO thanks to built-in project generator for the most steps with PlatformIO thanks to built-in project generator for the most
popular embedded boards and IDE. popular embedded boards and IDE.
* You can list pre-configured boards using :ref:`cmd_boards` command or .. note::
`PlatformIO Boards Explorer <http://platformio.org/boards>`_ * You can list pre-configured boards by :ref:`cmd_boards` command or
* For more detailed ``board`` information please scroll tables below by `PlatformIO Boards Explorer <http://platformio.org/boards>`_
horizontal. * For more detailed ``board`` information please scroll tables below by horizontal.
""") """)
lines.append(".. contents::") lines.append("""
lines.append("") .. contents:: Vendors
:local:
""")
vendors = {} vendors = {}
for data in BOARDS: for data in BOARDS:
@ -423,11 +453,88 @@ popular embedded boards and IDE.
f.write("\n".join(lines)) f.write("\n".join(lines))
def update_debugging():
vendors = {}
platforms = []
frameworks = []
for data in BOARDS:
if not data['debug']:
continue
platforms.append(data['platform'])
frameworks.extend(data['frameworks'])
vendor = data['vendor']
if vendor in vendors:
vendors[vendor].append(data)
else:
vendors[vendor] = [data]
lines = []
# Platforms
lines.append(""".. _debugging_platforms:
Platforms
---------
.. list-table::
:header-rows: 1
* - Name
- Description""")
for manifest in PLATFORM_MANIFESTS:
if manifest['name'] not in platforms:
continue
p = PlatformFactory.newPlatform(manifest['name'])
lines.append(
"""
* - :ref:`platform_{type_}`
- {description}"""
.format(type_=manifest['name'], description=p.description))
# Frameworks
lines.append("""
Frameworks
----------
.. list-table::
:header-rows: 1
* - Name
- Description""")
for framework in API_FRAMEWORKS:
if framework['name'] not in frameworks:
continue
lines.append("""
* - :ref:`framework_{name}`
- {description}""".format(**framework))
# Boards
lines.append("""
Boards
------
.. note::
For more detailed ``board`` information please scroll tables below by horizontal.
""")
for vendor, boards in sorted(vendors.iteritems()):
lines.append(str(vendor))
lines.append("~" * len(vendor))
lines.append(generate_boards(boards, extend_debug=True))
with open(
join(util.get_source_dir(), "..", "docs", "plus",
"debugging.rst"), "r+") as fp:
content = fp.read()
fp.seek(0)
fp.truncate()
fp.write(content[:content.index(".. _debugging_platforms:")] +
"\n".join(lines))
def main(): def main():
update_create_platform_doc() update_create_platform_doc()
update_platform_docs() update_platform_docs()
update_framework_docs() update_framework_docs()
update_embedded_boards() update_embedded_boards()
update_debugging()
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -112,23 +112,25 @@ def install_pip():
def install_platformio(): def install_platformio():
r = None r = None
cmd = ["-m", "pip.__main__" if sys.version_info < (2, 7, 0) else "pip"] cmd = ["pip", "install", "-U", "platformio"]
# cmd = [
# "pip", "install", "-U",
# "https://github.com/platformio/platformio-core/archive/develop.zip"
# ]
try: try:
r = exec_python_cmd(cmd + ["install", "-U", "platformio"]) r = exec_python_cmd(cmd)
assert r['returncode'] == 0 assert r['returncode'] == 0
except AssertionError: except AssertionError:
r = exec_python_cmd(cmd + ["--no-cache-dir", "install", "-U", cmd.insert(1, "--no-cache-dir")
"platformio"]) r = exec_python_cmd(cmd)
if r: if r:
print_exec_result(r) print_exec_result(r)
def main(): def main():
steps = [ steps = [("Fixing Windows %PATH% Environment", fix_winpython_pathenv),
("Fixing Windows %PATH% Environment", fix_winpython_pathenv), ("Installing Python Package Manager", install_pip),
("Installing Python Package Manager", install_pip), ("Installing PlatformIO and dependencies", install_platformio)]
("Installing PlatformIO and dependencies", install_platformio)
]
if not IS_WINDOWS: if not IS_WINDOWS:
del steps[0] del steps[0]
@ -157,7 +159,7 @@ Permission denied
You need the `sudo` permission to install Python packages. Try You need the `sudo` permission to install Python packages. Try
$ sudo python -c "$(curl -fsSL $ sudo python -c "$(curl -fsSL
https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" https://raw.githubusercontent.com/platformio/platformio/develop/scripts/get-platformio.py)"
""") """)
if is_error: if is_error:

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -23,7 +23,7 @@ install_requires = [
"click>=5,<6", "click>=5,<6",
"colorama", "colorama",
"lockfile>=0.9.1,<0.13", "lockfile>=0.9.1,<0.13",
"pyserial>=3,<4", "pyserial>=3,<4,!=3.3",
"requests>=2.4.0,<3", "requests>=2.4.0,<3",
"semantic_version>=2.5.0" "semantic_version>=2.5.0"
] ]
@ -51,6 +51,7 @@ setup(
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [
"pio = platformio.__main__:main", "pio = platformio.__main__:main",
"piodebuggdb = platformio.__main__:debug_gdb_main",
"platformio = platformio.__main__:main" "platformio = platformio.__main__:main"
] ]
}, },
@ -67,9 +68,8 @@ setup(
"Topic :: Software Development :: Compilers" "Topic :: Software Development :: Compilers"
], ],
keywords=[ keywords=[
"iot", "ide", "build", "compile", "library manager", "iot", "embedded", "arduino", "mbed", "esp8266", "esp32", "fpga",
"embedded", "ci", "continuous integration", "arduino", "mbed", "firmware", "continuous-integration", "cloud-ide", "avr", "arm",
"esp8266", "framework", "ide", "ide integration", "library.json", "ide", "unit-testing", "hardware", "verilog", "microcontroller",
"make", "cmake", "makefile", "mk", "pic32", "fpga", "artik" "debug"
] ])
)

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -25,15 +25,14 @@ def test_ci_empty(clirunner):
def test_ci_boards(clirunner, validate_cliresult): def test_ci_boards(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_ci, [ result = clirunner.invoke(cmd_ci, [
join("examples", "atmelavr-and-arduino", "arduino-internal-libs", join("examples", "atmelavr", "arduino-internal-libs", "src",
"src", "ChatServer.ino"), "-b", "uno", "-b", "leonardo" "ChatServer.ino"), "-b", "uno", "-b", "leonardo"
]) ])
validate_cliresult(result) validate_cliresult(result)
def test_ci_project_conf(clirunner, validate_cliresult): def test_ci_project_conf(clirunner, validate_cliresult):
project_dir = join("examples", "atmelavr-and-arduino", project_dir = join("examples", "atmelavr", "arduino-internal-libs")
"arduino-internal-libs")
result = clirunner.invoke(cmd_ci, [ result = clirunner.invoke(cmd_ci, [
join(project_dir, "src", "ChatServer.ino"), "--project-conf", join(project_dir, "src", "ChatServer.ino"), "--project-conf",
join(project_dir, "platformio.ini") join(project_dir, "platformio.ini")
@ -43,8 +42,7 @@ def test_ci_project_conf(clirunner, validate_cliresult):
def test_ci_lib_and_board(clirunner, validate_cliresult): def test_ci_lib_and_board(clirunner, validate_cliresult):
example_dir = join("examples", "atmelavr-and-arduino", example_dir = join("examples", "atmelavr", "arduino-external-libs")
"arduino-external-libs")
result = clirunner.invoke(cmd_ci, [ result = clirunner.invoke(cmd_ci, [
join(example_dir, "lib", "OneWire", "examples", "DS2408_Switch", join(example_dir, "lib", "OneWire", "examples", "DS2408_Switch",
"DS2408_Switch.pde"), "-l", join(example_dir, "lib", "OneWire"), "DS2408_Switch.pde"), "-l", join(example_dir, "lib", "OneWire"),

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -73,7 +73,7 @@ def test_init_ide_atom(clirunner, validate_cliresult, tmpdir):
# switch to NodeMCU # switch to NodeMCU
result = clirunner.invoke( result = clirunner.invoke(
cmd_init, ["--ide", "atom", "-b", "nodemcuv2", "-b", "uno"]) cmd_init, ["--ide", "atom", "-b", "nodemcuv2"])
validate_cliresult(result) validate_cliresult(result)
validate_pioproject(str(tmpdir)) validate_pioproject(str(tmpdir))
assert "arduinoespressif" in tmpdir.join(".clang_complete").read() assert "arduinoespressif" in tmpdir.join(".clang_complete").read()

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -112,6 +112,7 @@ def test_global_install_repository(clirunner, validate_cliresult,
"https://github.com/gioblu/PJON.git#6.2", "https://github.com/gioblu/PJON.git#6.2",
"https://github.com/bblanchon/ArduinoJson.git", "https://github.com/bblanchon/ArduinoJson.git",
"https://gitlab.com/ivankravets/rs485-nodeproto.git", "https://gitlab.com/ivankravets/rs485-nodeproto.git",
"https://github.com/platformio/platformio-libmirror.git",
# "https://developer.mbed.org/users/simon/code/TextLCD/", # "https://developer.mbed.org/users/simon/code/TextLCD/",
"knolleary/pubsubclient" "knolleary/pubsubclient"
]) ])
@ -124,6 +125,14 @@ def test_global_install_repository(clirunner, validate_cliresult,
] ]
assert set(items1) >= set(items2) assert set(items1) >= set(items2)
# check lib with duplicate URL
result = clirunner.invoke(cmd_lib, [
"-g", "install",
"https://github.com/platformio/platformio-libmirror.git"
])
validate_cliresult(result)
assert "is already installed" in result.output
def test_global_lib_list(clirunner, validate_cliresult, isolated_pio_home): def test_global_lib_list(clirunner, validate_cliresult, isolated_pio_home):
result = clirunner.invoke(cmd_lib, ["-g", "list"]) result = clirunner.invoke(cmd_lib, ["-g", "list"])
@ -141,7 +150,8 @@ def test_global_lib_list(clirunner, validate_cliresult, isolated_pio_home):
items2 = [ items2 = [
"OneWire", "DHT22", "PJON", "ESPAsyncTCP", "ArduinoJson", "OneWire", "DHT22", "PJON", "ESPAsyncTCP", "ArduinoJson",
"PubSubClient", "rs485-nodeproto", "Adafruit ST7735 Library", "PubSubClient", "rs485-nodeproto", "Adafruit ST7735 Library",
"RadioHead-1.62", "DallasTemperature", "NeoPixelBus", "IRremoteESP8266" "RadioHead-1.62", "DallasTemperature", "NeoPixelBus",
"IRremoteESP8266", "platformio-libmirror"
] ]
assert set(items1) == set(items2) assert set(items1) == set(items2)
@ -175,7 +185,7 @@ def test_global_lib_update(clirunner, validate_cliresult, isolated_pio_home):
validate_cliresult(result) validate_cliresult(result)
validate_cliresult(result) validate_cliresult(result)
assert result.output.count("[Skip]") == 5 assert result.output.count("[Skip]") == 5
assert result.output.count("[Up-to-date]") == 9 assert result.output.count("[Up-to-date]") == 10
assert "Uninstalling ArduinoJson @ 5.7.3" in result.output assert "Uninstalling ArduinoJson @ 5.7.3" in result.output
assert "Uninstalling IRremoteESP8266 @ fee16e880b" in result.output assert "Uninstalling IRremoteESP8266 @ fee16e880b" in result.output
@ -208,7 +218,7 @@ def test_global_lib_uninstall(clirunner, validate_cliresult,
"ArduinoJson", "ArduinoJson_ID64@5.6.7", "DallasTemperature_ID54", "ArduinoJson", "ArduinoJson_ID64@5.6.7", "DallasTemperature_ID54",
"DHT22_ID58", "ESPAsyncTCP_ID305", "NeoPixelBus_ID547", "PJON", "DHT22_ID58", "ESPAsyncTCP_ID305", "NeoPixelBus_ID547", "PJON",
"PJON@src-79de467ebe19de18287becff0a1fb42d", "PubSubClient", "PJON@src-79de467ebe19de18287becff0a1fb42d", "PubSubClient",
"RadioHead-1.62", "rs485-nodeproto" "RadioHead-1.62", "rs485-nodeproto", "platformio-libmirror"
] ]
assert set(items1) == set(items2) assert set(items1) == set(items2)

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -20,10 +20,11 @@ from platformio import util
def test_local_env(): def test_local_env():
result = util.exec_command(["platformio", "test", "-d", result = util.exec_command([
join("examples", "unit-testing", "calculator"), "platformio", "test", "-d",
"-e", "native"]) join("examples", "unit-testing", "calculator"), "-e", "native"
])
if result['returncode'] != 1: if result['returncode'] != 1:
pytest.fail(result) pytest.fail(result)
assert all( assert all([s in result['out']
[s in result['out'] for s in ("PASSED", "IGNORED", "FAILED")]) for s in ("PASSED", "IGNORED", "FAILED")]), result['out']

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,11 +15,8 @@
import os import os
import pytest import pytest
import requests
from click.testing import CliRunner from click.testing import CliRunner
requests.packages.urllib3.disable_warnings()
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def clirunner(): def clirunner():

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -127,6 +127,11 @@ def test_pkg_input_parser():
"git+ssh://git@gitlab.private-server.com/user/package#1.2.0", "git+ssh://git@gitlab.private-server.com/user/package#1.2.0",
("package", None, ("package", None,
"git+ssh://git@gitlab.private-server.com/user/package#1.2.0") "git+ssh://git@gitlab.private-server.com/user/package#1.2.0")
],
[
"git+ssh://user@gitlab.private-server.com:1234/package#1.2.0",
("package", None,
"git+ssh://user@gitlab.private-server.com:1234/package#1.2.0")
] ]
] ]
for params, result in items: for params, result in items:

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.

View File

@ -1,4 +1,4 @@
# Copyright 2014-present PlatformIO <contact@platformio.org> # Copyright (c) 2014-present PlatformIO <contact@platformio.org>
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -21,10 +21,9 @@ usedevelop = True
deps = deps =
isort isort
flake8 flake8
yapf yapf<0.17
pylint pylint
pytest pytest
show
commands = python --version commands = python --version
[testenv:docs] [testenv:docs]