Merge branch 'release/v3.4.1'

This commit is contained in:
Ivan Kravets
2017-08-02 16:51:45 +03:00
28 changed files with 281 additions and 596 deletions

15
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"python.pythonPath": "${workspaceRoot}/.tox/develop/bin/python",
"python.formatting.provider": "yapf",
"files.exclude": {
"**/*.pyc": true,
"*.egg-info": true,
".cache": true,
"build": true,
"dist": true
},
"editor.rulers": [79],
"restructuredtext.builtDocumentationPath": "${workspaceRoot}/docs/_build/html",
"restructuredtext.confPath": "${workspaceRoot}/docs",
"restructuredtext.linter.executablePath": "${workspaceRoot}/.tox/docs/bin/restructuredtext-lint"
}

View File

@ -4,6 +4,27 @@ Release Notes
PlatformIO 3.0 PlatformIO 3.0
-------------- --------------
3.4.1 (2017-08-02)
~~~~~~~~~~~~~~~~~~
* Pre/Post extra scripting for advanced control of PIO Build System
(`issue #891 <https://github.com/platformio/platformio-core/issues/891>`_)
* New `lib_archive <http://docs.platformio.org/page/projectconf/section_env_library.html#lib-archive>`_
option to control library archiving and linking behaviour
(`issue #993 <https://github.com/platformio/platformio-core/issues/993>`_)
* Add "inc" folder automatically to CPPPATH when "src" is available (works for project and library)
(`issue #1003 <https://github.com/platformio/platformio-core/issues/1003>`_)
* Use a root of library when filtering source code using
`library.json <http://docs.platformio.org/page/librarymanager/config.html>`__
and ``srcFilter`` field
* Added ``monitor_*`` options to white-list for `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf.html>`__
(`issue #982 <https://github.com/platformio/platformio-core/issues/982>`_)
* Do not ask for board ID when initialize project for desktop platform
* Handle broken PIO Core state and create new one
* Fixed an issue with a custom transport for `PIO Unit Testing <http://docs.platformio.org/page/plus/unit-testing.html>`__
when multiple tests are present
* Fixed an issue when can not upload firmware to SAM-BA based board (Due)
3.4.0 (2017-06-26) 3.4.0 (2017-06-26)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -62,75 +83,6 @@ PlatformIO 3.0
custom user name and SSH port custom user name and SSH port
(`issue #925 <https://github.com/platformio/platformio-core/issues/925>`_) (`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)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -177,88 +129,6 @@ PlatformIO 3.0
* Fixed package installing with VCS branch for Python 2.7.3 * Fixed package installing with VCS branch for Python 2.7.3
(`issue #885 <https://github.com/platformio/platformio-core/issues/885>`_) (`issue #885 <https://github.com/platformio/platformio-core/issues/885>`_)
-------
* Development platform `Atmel AVR <https://github.com/platformio/platform-atmelavr>`__
+ New boards: EnviroDIY Mayfly, The Things Uno, SparkFun Qduino Mini,
SparkFun ATmega128RFA1 Dev Board, SparkFun Serial 7-Segment Display,
Generic ATTiny2313 and ATTiny4313
+ Set fuse bits with new target named ``fuses``
(`issue #865 <https://github.com/platformio/platformio-core/issues/865>`_)
+ Updated Arduino Core to 1.6.17
+ Fixed ISO C99 warning for EnviroDIY Mayfly board
+ Fixed firmware uploading to Arduino Leonardo
* Development platform `Atmel SAM <https://github.com/platformio/platform-atmelsam>`__
+ Added support for Adafruit Circuit Playground Express, Arduino MKRZero,
Atmel ATSAMW25-XPRO boards
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
+ Updated Arduino SAM & SAMD Core to 1.6.11
* Development platform `Espressif 32 <https://github.com/platformio/platform-espressif32>`__
+ Added support for Simba & Pumbaa Frameworks
+ Added new boards: Node32s, Hornbill ESP32 Dev, Hornbill ESP32 Minim
+ Updated Arduino Core
+ Updated ESP-IDF framework to the latest v2.0 Release Candidate 1
+ New ESP IDF examples: BLE, Coap Server, Peripherals UART, Storage SDCard
* Development platform `Freescale Kinetis <https://github.com/platformio/platform-freescalekinetis>`__
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
* Development platform `Lattice iCE40 <https://github.com/platformio/platform-lattice_ice40>`__
+ Improved path management for Windows
+ Custom uploader using ``$UPLOAD`` build variable
(`issue #6 <https://github.com/platformio/platform-lattice_ice40/issues/6>`__)
+ Updated toolchain-icestorm to 1.10.0 (added -C option to "time" target)
+ Updated toolchain-iverilog to 1.1.0 (loaed all vlib/\*.v files in "iverilog" builder)
* Development platform `Linux ARM <https://github.com/platformio/platform-linux_arm>`__
+ Added support for Samsung ARTIK boards (520, 530, 710, 1020) and ARTIK SDK
(`issue #353 <https://github.com/platformio/platformio-core/issues/353>`_)
* Development platform `Nordic nRF51 <https://github.com/platformio/platform-nordicnrf51>`__
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
* Development platform `NXP LPC <https://github.com/platformio/platform-nxplpc>`__
+ Added support for LPCXpresso4337 and y5 LPC11U35 mbug boards
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
* Development platform `Silicon Labs EFM32 <https://github.com/platformio/platform-siliconlabsefm32>`__
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
* Development platform `ST STM32 <https://github.com/platformio/platform-ststm32>`__
+ Added support for new boards: Espotel LoRa Module, NAMote72, MTS Dragonfly,
ST Nucleo F303ZE, u-blox EVK-ODIN-W2, MultiTech xDot
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
* Development platform `Teensy <https://github.com/platformio/platform-teensy>`__
+ Added support for ARM mbed events library
+ Updated ARM mbed OS to 5.3.6/rev137
+ Updated Arduino Core to v1.35
* Development platform `TI TIVA <https://github.com/platformio/platform-titiva>`__
+ Updated Energia Core to 1.0.2
3.2.1 (2016-12-07) 3.2.1 (2016-12-07)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -323,93 +193,6 @@ PlatformIO 3.0
* Fixed issue with ``PATH`` auto-configuring for upload tools * Fixed issue with ``PATH`` auto-configuring for upload tools
* Fixed ``99-platformio-udev.rules`` checker for Linux OS * Fixed ``99-platformio-udev.rules`` checker for Linux OS
-------
* Development platform `Atmel AVR <https://github.com/platformio/platform-atmelavr>`__
+ Added support for SODAQ AVR boards
(`issue #796 <https://github.com/platformio/platformio-core/issues/796>`__)
+ Added support for Pololu A-Star boards
(`issue #804 <https://github.com/platformio/platformio-core/issues/804>`__)
+ Added support for Altair board
(`issue #15 <https://github.com/platformio/platform-atmelavr/issues/15>`__)
+ Added support for ATmega328PB MCUs
+ Updated Atmel AVR toolchain to GCC 4.9.2
+ Updated Arduino Core for LightBlue Bean/LightBlue Bean+ boards
+ Handle "micronucleus" tool base on upload protocol
(`issue #18 <https://github.com/platformio/platform-atmelavr/issues/18>`__)
+ Fixed programming of ATtiny boards when "micronucleus" uploader is used
(`issue #13 <https://github.com/platformio/platform-atmelavr/issues/13>`__)
* Development platform `Atmel SAM <https://github.com/platformio/platform-atmelsam>`__
+ Added support for SODAQ SAMD boards
(`issue #796 <https://github.com/platformio/platformio-core/issues/796>`__)
+ Updated ARM mbed OS to 5.1.4/rev126
+ Fixed issue with uploading to Arduino Zero on programming USB port
(`issue #805 <https://github.com/platformio/platformio-core/issues/805>`__)
* Development platform `Espressif 32 <https://github.com/platformio/platform-espressif32>`__
* Initial support for Espressif IDF and Arduino for ESP32
* Development platform `Espressif 8266 <https://github.com/platformio/platform-espressif8266>`__
+ Added support for ESPrectro board
+ Additional target "buildfs" to accompany "uploadfs"
(`issue #6 <https://github.com/platformio/platform-espressif8266/issues/6>`__)
* Development platform `Freescale Kinetis <https://github.com/platformio/platform-freescalekinetis>`__
+ Updated ARM mbed OS to 5.1.4/rev126
* Development platform `Microchip PIC32 <https://github.com/platformio/platform-microchippic32>`__
+ Add support for MikroElektronika Clicker 2 board
+ Updated ChipKIT Core to v1.3.1
+ Updated Microchip PIC32 GCC-based toolchain and "pic32prog" tool
* Development platform `Nordic nRF51 <https://github.com/platformio/platform-nordicnrf51>`__
+ Added BBC micro:bit B(S130) board
(`issue #3 <https://github.com/platformio/platform-nordicnrf51/issues/3>`__)
+ Updated ARM mbed OS to 5.1.4/rev126
+ Fixed “undefined reference to `_sbrk” error for RFDuino
(`issue #1 <https://github.com/platformio/platform-nordicnrf51/issues/1>`__)
* Development platform `NXP LPC <https://github.com/platformio/platform-nxplpc>`__
+ Updated ARM mbed OS to 5.1.4/rev126
* Development platform `Silicon Labs EFM32 <https://github.com/platformio/platform-siliconlabsefm32>`__
+ Updated ARM mbed OS to 5.1.4/rev126
* Development platform `ST STM32 <https://github.com/platformio/platform-ststm32>`__
+ Added support for Maple Mini Original and Maple Mini Bootloader 2.0
(`issue #22 <https://github.com/platformio/platform-ststm32/issues/22>`__)
+ Added support for new boards: ST 32F769IDISCOVERY
+ Updated ARM mbed OS to 5.1.4/rev126
+ Use ``serial`` protocol by default for STM32Duino-based boards
(`issue #14 <https://github.com/platformio/platform-ststm32/issues/14>`__)
+ Fixed linker error "undefined reference to _sbrk" for STM32Duino
(`issue #10 <https://github.com/platformio/platform-ststm32/issues/10>`__)
* Development platform `Teensy <https://github.com/platformio/platform-teensy>`__
+ Updated Arduino Framework for Teensy to v131
+ Updated ARM mbed OS to 5.1.4/rev126
+ Added support for Teensy Audio feature (``build_flags = -D USB_AUDIO``)
* Development platform `TI MSP430 <https://github.com/platformio/platform-timsp430>`__
+ Upgrade development platform with the latest GCC toolchains and Energia
framework
(`issue #1 <https://github.com/platformio/platform-timsp430/issues/1>`__,
`issue #2 <https://github.com/platformio/platform-timsp430/issues/2>`__,
`issue #3 <https://github.com/platformio/platform-timsp430/issues/1>`__)
3.1.0 (2016-09-19) 3.1.0 (2016-09-19)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -428,48 +211,6 @@ PlatformIO 3.0
* Fixed SSL Server-Name-Indication for Python < 2.7.9 * Fixed SSL Server-Name-Indication for Python < 2.7.9
(`issue #774 <https://github.com/platformio/platformio-core/issues/774>`_) (`issue #774 <https://github.com/platformio/platformio-core/issues/774>`_)
-------
* Development platform `Espressif 8266 <https://github.com/platformio/platform-espressif8266>`__
+ Add support for `SparkFun Blynk Board <https://www.sparkfun.com/products/13794>`_
+ Created `staging <http://docs.platformio.org/page/platforms/espressif8266.html#using-arduino-framework-with-staging-version>`__
branch to work with development version of Arduino Framework
* Development platform `Freescale Kinetis <https://github.com/platformio/platform-freescalekinetis>`__
+ Added support for new boards: FRDM-KL26Z, FRDM-KL27Z, FRDM-KL43Z, Hexiwear
* Development platform `Nordic nRF51 <https://github.com/platformio/platform-nordicnrf51>`__
+ Added support for new boards: Seeed Arch BLE, Seeed Arch Link, Switch
Science mbed TY51822r3, y5 nRF51822 mbug, JKSoft Wallbot BLE
* Development platform `NXP LPC <https://github.com/platformio/platform-nxplpc>`__
+ Added support for new boards: ARM mbed LPC11U24 (+CAN), Bambino-210E,
CoCo-ri-Co!, DipCortex M3, LPCXpresso11U68, LPCXpresso824-MAX, mBuino,
MicroNFCBoard, NXP LPC11C24, NXP LPC11U34, EA LPC11U35 QuickStart Board,
NXP LPC11U37, NXP LPC2368, NXP LPC2460, NXP LPC800-MAX, Seeed Arch GPRS V2,
Seeed Xadow M0, Smeshlink xbed LPC1768, Switch Science mbed LPC824
* Development platform `ST STM32 <https://github.com/platformio/platform-ststm32>`__
+ New Arduino framework for ST STM32 -
`STM32Duino <https://github.com/rogerclarkmelbourne/Arduino_STM32>`__.
Supported boards: BluePill F103C8, Generic STM32F103C8, Generic STM32F103R8,
Generic STM32F103RB, Generic STM32F103RC, Generic STM32F103RE, Olimexino STM32
+ Added support for new ARM mbed based boards: ST 32F746GDISCOVER,
MultiTech mDot, ST Nucleo F207ZG, ST Nucleo F429ZI, ST Nucleo F446ZE,
ST Nucleo F746ZG, ST Nucleo F767ZI, ST Nucleo L011K4, ST Nucleo L432KC,
Seeed Arch Max
* Development platform `Teensy <https://github.com/platformio/platform-teensy>`__
+ Added support for Teensy 3.5 and 3.6 boards
+ Updated Arduino Framework for Teensy to v130
3.0.1 (2016-09-08) 3.0.1 (2016-09-08)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -559,29 +300,6 @@ PlatformIO 3.0
(`issue #742 <https://github.com/platformio/platformio-core/issues/742>`_) (`issue #742 <https://github.com/platformio/platformio-core/issues/742>`_)
* Stopped supporting Python 2.6 * Stopped supporting Python 2.6
------
* Development platform `Atmel SAM <https://github.com/platformio/platform-atmelsam>`__
+ Fixed missing analog ports for Adafruit Feather M0 Bluefruit
(`issue #2 <https://github.com/platformio/platform-atmelsam/issues/2>`__)
* Development platform `Nordic nRF51 <https://github.com/platformio/platform-nordicnrf51>`__
+ Added support for BBC micro:bit board
(`issue #709 <https://github.com/platformio/platformio-core/issues/709>`_)
* Development platform `ST STM32 <https://github.com/platformio/platform-ststm32>`__
+ Added support for BluePill F103C8 board
(`pull #2 <https://github.com/platformio/platform-ststm32/pull/2>`__)
* Development platform `Teensy <https://github.com/platformio/platform-teensy>`__
+ Updated Arduino Framework to v1.29
(`issue #2 <https://github.com/platformio/platform-teensy/issues/2>`__)
PlatformIO 2.0 PlatformIO 2.0
-------------- --------------
@ -1721,7 +1439,6 @@ PlatformIO 0.0
* Added support for *Microduino* and *Raspduino* boards in * Added support for *Microduino* and *Raspduino* boards in
`atmelavr <http://docs.platformio.org/page/platforms/atmelavr.html>`_ platform `atmelavr <http://docs.platformio.org/page/platforms/atmelavr.html>`_ platform
0.3.1 (2014-06-21) 0.3.1 (2014-06-21)
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~

View File

@ -95,7 +95,7 @@ Development Platforms
* `ST STM32 <http://platformio.org/platforms/ststm32>`_ * `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 Tiva <http://platformio.org/platforms/titiva>`_
* `WIZNet W7500 <http://platformio.org/platforms/wiznet7500>`_ * `WIZNet W7500 <http://platformio.org/platforms/wiznet7500>`_
Frameworks Frameworks

2
docs

Submodule docs updated: 58574c0741...ebd68b4bac

View File

@ -14,7 +14,7 @@
import sys import sys
VERSION = (3, 4, 0) VERSION = (3, 4, 1)
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"

View File

@ -88,7 +88,7 @@ class State(object):
self._lock_state_file() self._lock_state_file()
if isfile(self.path): if isfile(self.path):
self._state = util.load_json(self.path) self._state = util.load_json(self.path)
except ValueError: except exception.PlatformioException:
self._state = {} self._state = {}
self._prev_state = deepcopy(self._state) self._prev_state = deepcopy(self._state)
return self._state return self._state

View File

@ -32,7 +32,7 @@ commonvars = Variables(None)
commonvars.AddVariables( commonvars.AddVariables(
("PLATFORM_MANIFEST",), ("PLATFORM_MANIFEST",),
("BUILD_SCRIPT",), ("BUILD_SCRIPT",),
("EXTRA_SCRIPT",), ("EXTRA_SCRIPTS",),
("PIOENV",), ("PIOENV",),
("PIOTEST",), ("PIOTEST",),
("PIOPLATFORM",), ("PIOPLATFORM",),
@ -50,6 +50,7 @@ commonvars.AddVariables(
("LIB_DEPS",), ("LIB_DEPS",),
("LIB_IGNORE",), ("LIB_IGNORE",),
("LIB_EXTRA_DIRS",), ("LIB_EXTRA_DIRS",),
("LIB_ARCHIVE",),
# board options # board options
("BOARD",), ("BOARD",),
@ -67,6 +68,11 @@ commonvars.AddVariables(
) # yapf: disable ) # yapf: disable
MULTILINE_VARS = [
"EXTRA_SCRIPTS", "PIOFRAMEWORK", "BUILD_FLAGS", "SRC_BUILD_FLAGS",
"BUILD_UNFLAGS", "SRC_FILTER", "LIB_DEPS", "LIB_IGNORE", "LIB_EXTRA_DIRS"
]
DEFAULT_ENV_OPTIONS = dict( DEFAULT_ENV_OPTIONS = dict(
tools=[ tools=[
"ar", "as", "gcc", "g++", "gnulink", "platformio", "pioplatform", "ar", "as", "gcc", "g++", "gnulink", "platformio", "pioplatform",
@ -110,8 +116,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]: if k in MULTILINE_VARS:
env[k] = [v.strip() for v in env[k].split("\n") if v.strip()] env[k] = util.parse_conf_multi_values(env[k])
if env.GetOption('clean'): if env.GetOption('clean'):
env.PioClean(env.subst("$BUILD_DIR")) env.PioClean(env.subst("$BUILD_DIR"))
@ -120,38 +126,30 @@ elif not int(ARGUMENTS.get("PIOVERBOSE", 0)):
print "Verbose mode can be enabled via `-v, --verbose` option" print "Verbose mode can be enabled via `-v, --verbose` option"
# Handle custom variables from system environment # Handle custom variables from system environment
for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPT", for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPTS",
"UPLOAD_PORT", "UPLOAD_FLAGS", "LIB_EXTRA_DIRS"): "UPLOAD_PORT", "UPLOAD_FLAGS", "LIB_EXTRA_DIRS"):
k = "PLATFORMIO_%s" % var k = "PLATFORMIO_%s" % var
if k not in environ: if k not in environ:
continue continue
if var in ("UPLOAD_PORT", "EXTRA_SCRIPT") or not env.get(var): if var in ("UPLOAD_PORT", ):
env[var] = environ.get(k) env[var] = environ.get(k)
elif isinstance(env[var], list):
env.Append(**{var: environ.get(k)})
else:
env[var] = "%s%s%s" % (environ.get(k), ", "
if var == "LIB_EXTRA_DIRS" else " ", env[var])
# Parse comma separated items
for opt in ("PIOFRAMEWORK", "LIB_DEPS", "LIB_IGNORE", "LIB_EXTRA_DIRS"):
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.Append(**{var: util.parse_conf_multi_values(environ.get(k))})
# 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=util.parse_conf_multi_values(
env.Prepend(LIBSOURCE_DIRS=[ util.get_project_optional_dir("lib_extra_dirs")))
l.strip() for l in items.split("\n" if "\n" in items else ", ")
if l.strip()
])
env.Prepend(LIBSOURCE_DIRS=env.get("LIB_EXTRA_DIRS", [])) env.Prepend(LIBSOURCE_DIRS=env.get("LIB_EXTRA_DIRS", []))
env.LoadPioPlatform(commonvars) env.LoadPioPlatform(commonvars)
env.SConscriptChdir(0) env.SConscriptChdir(0)
env.SConsignFile(join("$PROJECTPIOENVS_DIR", ".sconsign.dblite")) env.SConsignFile(join("$PROJECTPIOENVS_DIR", ".sconsign.dblite"))
for item in env.GetPreExtraScripts():
env.SConscript(item, exports="env")
env.SConscript("$BUILD_SCRIPT") env.SConscript("$BUILD_SCRIPT")
AlwaysBuild(env.Alias("__debug", DEFAULT_TARGETS + ["size"])) AlwaysBuild(env.Alias("__debug", DEFAULT_TARGETS + ["size"]))
@ -160,8 +158,8 @@ AlwaysBuild(env.Alias("__test", DEFAULT_TARGETS + ["size"]))
if "UPLOAD_FLAGS" in env: if "UPLOAD_FLAGS" in env:
env.Append(UPLOADERFLAGS=["$UPLOAD_FLAGS"]) env.Append(UPLOADERFLAGS=["$UPLOAD_FLAGS"])
if env.get("EXTRA_SCRIPT"): for item in env.GetPostExtraScripts():
env.SConscript(env.get("EXTRA_SCRIPT"), exports="env") env.SConscript(item, exports="env")
if "envdump" in COMMAND_LINE_TARGETS: if "envdump" in COMMAND_LINE_TARGETS:
print env.Dump() print env.Dump()

View File

@ -150,7 +150,10 @@ class LibBuilderBase(object):
return join("$BUILD_DIR", "lib", basename(self.path)) return join("$BUILD_DIR", "lib", basename(self.path))
def get_inc_dirs(self): def get_inc_dirs(self):
return [self.src_dir] items = [self.src_dir]
if all([isdir(join(self.path, d)) for d in ("inc", "src")]):
items.append(join(self.path, "inc"))
return items
@property @property
def build_flags(self): def build_flags(self):
@ -166,7 +169,7 @@ class LibBuilderBase(object):
@property @property
def lib_archive(self): def lib_archive(self):
return True return self.env.get("LIB_ARCHIVE", "") != "false"
@staticmethod @staticmethod
def validate_ldf_mode(mode): def validate_ldf_mode(mode):
@ -383,24 +386,26 @@ class LibBuilderBase(object):
for lb in self._circular_deps: for lb in self._circular_deps:
self.env.AppendUnique(CPPPATH=lb.get_inc_dirs()) self.env.AppendUnique(CPPPATH=lb.get_inc_dirs())
if not self._is_built: if self._is_built:
self.env.AppendUnique(CPPPATH=self.get_inc_dirs()) return libs
self._is_built = True
if self.lib_ldf_mode == "off": self.env.AppendUnique(CPPPATH=self.get_inc_dirs())
for lb in self.envorigin.GetLibBuilders():
if self == lb or not lb.is_built:
continue
for key in ("CPPPATH", "LIBPATH", "LIBS", "LINKFLAGS"):
self.env.AppendUnique(**{key: lb.env.get(key)})
if self.lib_archive: if self.lib_ldf_mode == "off":
libs.append( for lb in self.envorigin.GetLibBuilders():
self.env.BuildLibrary(self.build_dir, self.src_dir, if self == lb or not lb.is_built:
self.src_filter)) continue
else: for key in ("CPPPATH", "LIBPATH", "LIBS", "LINKFLAGS"):
self.env.BuildSources(self.build_dir, self.src_dir, self.env.AppendUnique(**{key: lb.env.get(key)})
self.src_filter)
self._is_built = True if self.lib_archive:
libs.append(
self.env.BuildLibrary(self.build_dir, self.src_dir,
self.src_filter))
else:
self.env.BuildSources(self.build_dir, self.src_dir,
self.src_filter)
return libs return libs
@ -408,45 +413,6 @@ class UnknownLibBuilder(LibBuilderBase):
pass pass
class ProjectAsLibBuilder(LibBuilderBase):
def __init__(self, *args, **kwargs):
LibBuilderBase.__init__(self, *args, **kwargs)
self._is_built = True
@property
def src_dir(self):
return self.env.subst("$PROJECTSRC_DIR")
@property
def lib_ldf_mode(self):
mode = LibBuilderBase.lib_ldf_mode.fget(self)
if not mode.startswith("chain"):
return mode
# parse all project files
return "deep+" if "+" in mode else "deep"
@property
def src_filter(self):
return self.env.get("SRC_FILTER", LibBuilderBase.src_filter.fget(self))
def process_extra_options(self):
# skip for project, options are already processed
pass
def search_deps_recursive(self, search_paths=None):
for dep in self.env.get("LIB_DEPS", []):
for token in ("@", "="):
if token in dep:
dep, _ = dep.split(token, 1)
for lb in self.envorigin.GetLibBuilders():
if lb.name == dep:
if lb not in self.depbuilders:
self.depend_recursive(lb)
break
return LibBuilderBase.search_deps_recursive(self, search_paths)
class ArduinoLibBuilder(LibBuilderBase): class ArduinoLibBuilder(LibBuilderBase):
def load_manifest(self): def load_manifest(self):
@ -521,6 +487,15 @@ class PlatformIOLibBuilder(LibBuilderBase):
def _is_arduino_manifest(self): def _is_arduino_manifest(self):
return isfile(join(self.path, "library.properties")) return isfile(join(self.path, "library.properties"))
@property
def src_dir(self):
if all([
"srcFilter" in self._manifest.get("build", {})
or self.env['SRC_FILTER'], not self._is_arduino_manifest()
]):
return self.path
return LibBuilderBase.src_dir.fget(self)
@property @property
def src_filter(self): def src_filter(self):
if "srcFilter" in self._manifest.get("build", {}): if "srcFilter" in self._manifest.get("build", {}):
@ -578,9 +553,9 @@ class PlatformIOLibBuilder(LibBuilderBase):
inc_dirs = LibBuilderBase.get_inc_dirs(self) inc_dirs = LibBuilderBase.get_inc_dirs(self)
# backwards compatibility with PlatformIO 2.0 # backwards compatibility with PlatformIO 2.0
if ("build" not in self._manifest and self._is_arduino_manifest() and if ("build" not in self._manifest and self._is_arduino_manifest()
not isdir(join(self.path, "src")) and and not isdir(join(self.path, "src"))
isdir(join(self.path, "utility"))): and isdir(join(self.path, "utility"))):
inc_dirs.append(join(self.path, "utility")) inc_dirs.append(join(self.path, "utility"))
for path in self.env.get("CPPPATH", []): for path in self.env.get("CPPPATH", []):
@ -589,6 +564,46 @@ class PlatformIOLibBuilder(LibBuilderBase):
return inc_dirs return inc_dirs
class ProjectAsLibBuilder(LibBuilderBase):
@property
def src_dir(self):
return self.env.subst("$PROJECTSRC_DIR")
@property
def lib_ldf_mode(self):
mode = LibBuilderBase.lib_ldf_mode.fget(self)
if not mode.startswith("chain"):
return mode
# parse all project files
return "deep+" if "+" in mode else "deep"
@property
def src_filter(self):
return self.env.get("SRC_FILTER", LibBuilderBase.src_filter.fget(self))
def process_extra_options(self):
# skip for project, options are already processed
pass
def search_deps_recursive(self, search_paths=None):
for dep in self.env.get("LIB_DEPS", []):
for token in ("@", "="):
if token in dep:
dep, _ = dep.split(token, 1)
for lb in self.envorigin.GetLibBuilders():
if lb.name == dep:
if lb not in self.depbuilders:
self.depend_recursive(lb)
break
return LibBuilderBase.search_deps_recursive(self, search_paths)
def build(self):
self._is_built = True # do not build Project now
self.env.AppendUnique(CPPPATH=self.get_inc_dirs())
return LibBuilderBase.build(self)
def GetLibBuilders(env): # pylint: disable=too-many-branches def GetLibBuilders(env): # pylint: disable=too-many-branches
if "__PIO_LIB_BUILDERS" in DefaultEnvironment(): if "__PIO_LIB_BUILDERS" in DefaultEnvironment():
@ -596,8 +611,8 @@ def GetLibBuilders(env): # pylint: disable=too-many-branches
items = [] items = []
compat_mode = int(env.get("LIB_COMPAT_MODE", 1)) compat_mode = int(env.get("LIB_COMPAT_MODE", 1))
verbose = (int(ARGUMENTS.get("PIOVERBOSE", 0)) and verbose = (int(ARGUMENTS.get("PIOVERBOSE", 0))
not env.GetOption('clean')) and not env.GetOption('clean'))
def _check_lib_builder(lb): def _check_lib_builder(lb):
if lb.name in env.get("LIB_IGNORE", []): if lb.name in env.get("LIB_IGNORE", []):
@ -655,7 +670,7 @@ def GetLibBuilders(env): # pylint: disable=too-many-branches
return items return items
def BuildDependentLibraries(env, src_dir): def BuildProjectLibraries(env):
lib_builders = env.GetLibBuilders() lib_builders = env.GetLibBuilders()
def correct_found_libs(): def correct_found_libs():
@ -684,7 +699,7 @@ def BuildDependentLibraries(env, src_dir):
print "Collected %d compatible libraries" % len(lib_builders) print "Collected %d compatible libraries" % len(lib_builders)
print "Looking for dependencies..." print "Looking for dependencies..."
project = ProjectAsLibBuilder(env, src_dir) project = ProjectAsLibBuilder(env, "$PROJECT_DIR")
project.env = env project.env = env
project.search_deps_recursive() project.search_deps_recursive()
@ -708,5 +723,5 @@ def exists(_):
def generate(env): def generate(env):
env.AddMethod(GetLibBuilders) env.AddMethod(GetLibBuilders)
env.AddMethod(BuildDependentLibraries) env.AddMethod(BuildProjectLibraries)
return env return env

View File

@ -285,10 +285,9 @@ def ProcessTest(env):
join("$BUILD_DIR", "UnityTestLib"), get_core_package_dir("tool-unity")) join("$BUILD_DIR", "UnityTestLib"), get_core_package_dir("tool-unity"))
env.Prepend(LIBS=[unitylib]) env.Prepend(LIBS=[unitylib])
src_filter = None src_filter = ["+<*.cpp>", "+<*.c>"]
if "PIOTEST" in env: if "PIOTEST" in env:
src_filter = "+<output_export.cpp>" src_filter.append("+<%s%s>" % (env['PIOTEST'], sep))
src_filter += " +<%s%s>" % (env['PIOTEST'], sep)
return env.CollectBuildFiles( return env.CollectBuildFiles(
"$BUILDTEST_DIR", "$BUILDTEST_DIR",
@ -297,6 +296,20 @@ def ProcessTest(env):
duplicate=False) duplicate=False)
def GetPreExtraScripts(env):
return [
item[4:] for item in env.get("EXTRA_SCRIPTS", [])
if item.startswith("pre:")
]
def GetPostExtraScripts(env):
return [
item[5:] if item.startswith("post:") else item
for item in env.get("EXTRA_SCRIPTS", []) if not item.startswith("pre:")
]
def exists(_): def exists(_):
return True return True
@ -309,4 +322,6 @@ def generate(env):
env.AddMethod(PioClean) env.AddMethod(PioClean)
env.AddMethod(ProcessDebug) env.AddMethod(ProcessDebug)
env.AddMethod(ProcessTest) env.AddMethod(ProcessTest)
env.AddMethod(GetPreExtraScripts)
env.AddMethod(GetPostExtraScripts)
return env return env

View File

@ -80,9 +80,9 @@ 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
not any([k.startswith("BOARD_"), or not any([k.startswith("BOARD_"),
k.startswith("UPLOAD_")])): 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

@ -48,6 +48,7 @@ def TouchSerialPort(env, port, baudrate):
s.close() s.close()
except: # pylint: disable=W0702 except: # pylint: disable=W0702
pass pass
sleep(0.4) # DO NOT REMOVE THAT (required by SAM-BA based boards)
def WaitForNewSerialPort(env, before): def WaitForNewSerialPort(env, before):
@ -115,8 +116,8 @@ def AutodetectUploadPort(*args, **kwargs): # pylint: disable=unused-argument
] ]
if any([isfile(p) for p in mbed_pages]): if any([isfile(p) for p in mbed_pages]):
return item['disk'] return item['disk']
if (item['name'] and if (item['name']
any([l in item['name'].lower() for l in msdlabels])): and any([l in item['name'].lower() for l in msdlabels])):
return item['disk'] return item['disk']
return None return None

View File

@ -63,11 +63,11 @@ def BuildProgram(env):
_append_pio_macros() _append_pio_macros()
# build dependent libs # build dependent libs
deplibs = env.BuildDependentLibraries("$PROJECTSRC_DIR") deplibs = env.BuildProjectLibraries()
# append specified LD_SCRIPT # append specified LD_SCRIPT
if ("LDSCRIPT_PATH" in env and if ("LDSCRIPT_PATH" in env
not any(["-Wl,-T" in f for f in env['LINKFLAGS']])): and not any(["-Wl,-T" in f for f in env['LINKFLAGS']])):
env.Append(LINKFLAGS=['-Wl,-T"$LDSCRIPT_PATH"']) env.Append(LINKFLAGS=['-Wl,-T"$LDSCRIPT_PATH"'])
# enable "cyclic reference" for linker # enable "cyclic reference" for linker
@ -79,7 +79,6 @@ def BuildProgram(env):
env.ProcessFlags(env.get("SRC_BUILD_FLAGS")) env.ProcessFlags(env.get("SRC_BUILD_FLAGS"))
env.Append( env.Append(
CPPPATH=["$PROJECTSRC_DIR"],
LIBS=deplibs, LIBS=deplibs,
LIBPATH=["$BUILD_DIR"], LIBPATH=["$BUILD_DIR"],
PIOBUILDFILES=env.CollectBuildFiles( PIOBUILDFILES=env.CollectBuildFiles(

View File

@ -123,13 +123,14 @@ def get_best_envname(project_dir, boards=None):
"env_default").split(", ")[0].strip() "env_default").split(", ")[0].strip()
if env_default: if env_default:
return env_default return env_default
section = None
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") and (not boards or config.get( elif config.has_option(section, "board") and (not boards or config.get(
section, "board") in boards): section, "board") in boards):
return section[4:] break
return None return section[4:] if section else None
def init_base_project(project_dir): def init_base_project(project_dir):

View File

@ -66,6 +66,9 @@ def cli(ctx, **options):
"Please use `platformio lib --global %s` command to remove " "Please use `platformio lib --global %s` command to remove "
"this warning." % ctx.invoked_subcommand, "this warning." % ctx.invoked_subcommand,
fg="yellow") fg="yellow")
elif util.is_platformio_project(storage_dir):
with util.cd(storage_dir):
storage_dir = util.get_projectlibdeps_dir()
if not storage_dir and not util.is_platformio_project(): if not storage_dir and not util.is_platformio_project():
raise exception.NotGlobalLibDir(util.get_project_dir(), raise exception.NotGlobalLibDir(util.get_project_dir(),
@ -382,8 +385,8 @@ def lib_show(library, json_output):
@cli.command("register", short_help="Register a new library") @cli.command("register", short_help="Register a new library")
@click.argument("config_url") @click.argument("config_url")
def lib_register(config_url): def lib_register(config_url):
if (not config_url.startswith("http://") and if (not config_url.startswith("http://")
not config_url.startswith("https://")): and not config_url.startswith("https://")):
raise exception.InvalidLibConfURL(config_url) raise exception.InvalidLibConfURL(config_url)
result = get_api_result("/lib/register", data=dict(config_url=config_url)) result = get_api_result("/lib/register", data=dict(config_url=config_url))

View File

@ -77,10 +77,8 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
env_default = None env_default = None
if config.has_option("platformio", "env_default"): if config.has_option("platformio", "env_default"):
env_default = [ env_default = util.parse_conf_multi_values(
e.strip() config.get("platformio", "env_default"))
for e in config.get("platformio", "env_default").split(", ")
]
results = [] results = []
start_time = time() start_time = time()
@ -90,8 +88,8 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
envname = section[4:] envname = section[4:]
skipenv = any([ skipenv = any([
environment and envname not in environment, not environment and environment and envname not in environment, not environment
env_default and envname not in env_default and env_default and envname not in env_default
]) ])
if skipenv: if skipenv:
results.append((envname, None)) results.append((envname, None))
@ -130,24 +128,30 @@ class EnvironmentProcessor(object):
KNOWN_OPTIONS = ("platform", "framework", "board", "board_mcu", KNOWN_OPTIONS = ("platform", "framework", "board", "board_mcu",
"board_f_cpu", "board_f_flash", "board_flash_mode", "board_f_cpu", "board_f_flash", "board_flash_mode",
"build_flags", "src_build_flags", "build_unflags", "build_flags", "src_build_flags", "build_unflags",
"src_filter", "extra_script", "targets", "upload_port", "src_filter", "extra_scripts", "targets", "upload_port",
"upload_protocol", "upload_speed", "upload_flags", "upload_protocol", "upload_speed", "upload_flags",
"upload_resetmethod", "lib_deps", "lib_ignore", "upload_resetmethod", "lib_deps", "lib_ignore",
"lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode", "lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode",
"piotest", "test_transport", "test_ignore", "test_port", "lib_archive", "piotest", "test_transport", "test_ignore",
"debug_tool", "debug_port", "debug_init_cmds", "test_port", "debug_tool", "debug_port",
"debug_extra_cmds", "debug_server", "debug_init_break", "debug_init_cmds", "debug_extra_cmds", "debug_server",
"debug_load_cmd") "debug_init_break", "debug_load_cmd", "monitor_port",
"monitor_baud", "monitor_rts", "monitor_dtr")
IGNORE_BUILD_OPTIONS = ("test_transport", "test_filter", "test_ignore", IGNORE_BUILD_OPTIONS = ("test_transport", "test_filter", "test_ignore",
"test_port", "debug_tool", "debug_port", "test_port", "debug_tool", "debug_port",
"debug_init_cmds", "debug_extra_cmds", "debug_init_cmds", "debug_extra_cmds",
"debug_server", "debug_init_break", "debug_server", "debug_init_break",
"debug_load_cmd") "debug_load_cmd", "monitor_port", "monitor_baud",
"monitor_rts", "monitor_dtr")
REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"} REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"}
RENAMED_OPTIONS = {"lib_use": "lib_deps", "lib_force": "lib_deps"} RENAMED_OPTIONS = {
"lib_use": "lib_deps",
"lib_force": "lib_deps",
"extra_script": "extra_scripts"
}
RENAMED_PLATFORMS = {"espressif": "espressif8266"} RENAMED_PLATFORMS = {"espressif": "espressif8266"}
@ -176,13 +180,13 @@ class EnvironmentProcessor(object):
self.options[k] = self.options[k].strip() self.options[k] = self.options[k].strip()
if not self.silent: if not self.silent:
click.echo("[%s] Processing %s (%s)" % click.echo(
(datetime.now().strftime("%c"), "[%s] Processing %s (%s)" %
click.style(self.name, fg="cyan", bold=True), (datetime.now().strftime("%c"),
"; ".join([ click.style(self.name, fg="cyan", bold=True), "; ".join([
"%s: %s" % (k, v.replace("\n", ", ")) "%s: %s" % (k, ", ".join(util.parse_conf_multi_values(v)))
for k, v in self.options.items() 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)
@ -274,12 +278,10 @@ class EnvironmentProcessor(object):
if d.strip() if d.strip()
], self.verbose) ], self.verbose)
if "lib_deps" in self.options: if "lib_deps" in self.options:
_autoinstall_libdeps(self.cmd_ctx, [ _autoinstall_libdeps(
d.strip() self.cmd_ctx,
for d in self.options['lib_deps'].split( util.parse_conf_multi_values(self.options['lib_deps']),
"\n" if "\n" in self.options['lib_deps'] else ", ") self.verbose)
if d.strip()
], self.verbose)
try: try:
p = PlatformFactory.newPlatform(self.options['platform']) p = PlatformFactory.newPlatform(self.options['platform'])
@ -294,6 +296,8 @@ class EnvironmentProcessor(object):
def _autoinstall_libdeps(ctx, libraries, verbose=False): def _autoinstall_libdeps(ctx, libraries, verbose=False):
if not libraries:
return
storage_dir = util.get_projectlibdeps_dir() storage_dir = util.get_projectlibdeps_dir()
ctx.obj = LibraryManager(storage_dir) ctx.obj = LibraryManager(storage_dir)
if verbose: if verbose:
@ -318,8 +322,8 @@ def _clean_pioenvs_dir(pioenvs_dir):
proj_hash = calculate_project_hash() proj_hash = calculate_project_hash()
# if project's config is modified # if project's config is modified
if (isdir(pioenvs_dir) and if (isdir(pioenvs_dir)
getmtime(join(util.get_project_dir(), "platformio.ini")) > and getmtime(join(util.get_project_dir(), "platformio.ini")) >
getmtime(pioenvs_dir)): getmtime(pioenvs_dir)):
util.rmtree_(pioenvs_dir) util.rmtree_(pioenvs_dir)

View File

@ -18,11 +18,15 @@ import click
import requests import requests
from platformio import VERSION, __version__, exception, util from platformio import VERSION, __version__, exception, util
from platformio.managers.core import update_core_packages
@click.command( @click.command(
"upgrade", short_help="Upgrade PlatformIO to the latest version") "upgrade", short_help="Upgrade PlatformIO to the latest version")
def cli(): def cli():
# Update PlatformIO's Core packages
update_core_packages(silent=True)
latest = get_latest_version() latest = get_latest_version()
if __version__ == latest: if __version__ == latest:
return click.secho( return click.secho(
@ -66,8 +70,8 @@ def cli():
if not r: if not r:
raise exception.UpgradeError("\n".join([str(cmd), str(e)])) raise exception.UpgradeError("\n".join([str(cmd), str(e)]))
permission_errors = ("permission denied", "not permitted") permission_errors = ("permission denied", "not permitted")
if (any([m in r['err'].lower() for m in permission_errors]) and if (any([m in r['err'].lower() for m in permission_errors])
"windows" not in util.get_systype()): and "windows" not in util.get_systype()):
click.secho( click.secho(
""" """
----------------- -----------------

View File

@ -32,6 +32,10 @@ class MinitermException(PlatformioException):
pass pass
class UserSideException(PlatformioException):
pass
class AbortedByUser(PlatformioException): class AbortedByUser(PlatformioException):
MESSAGE = "Aborted by user" MESSAGE = "Aborted by user"

View File

@ -46,7 +46,7 @@ class ProjectGenerator(object):
@util.memoized @util.memoized
def get_project_env(self): def get_project_env(self):
data = None data = {}
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:"):

View File

@ -1,121 +0,0 @@
{
"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

@ -38,11 +38,10 @@ 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 []
conditions = [ return ctx_args and any([
ctx.args[0] == "upgrade", "--json-output" in ctx_args, ctx.args[0] == "upgrade", "--json-output" in ctx_args,
"--version" 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):
@ -235,6 +234,9 @@ def check_platformio_upgrade():
if (time() - interval) < last_check.get("platformio_upgrade", 0): if (time() - interval) < last_check.get("platformio_upgrade", 0):
return return
# Update PlatformIO's Core packages
update_core_packages(silent=True)
last_check['platformio_upgrade'] = int(time()) last_check['platformio_upgrade'] = int(time())
app.set_state_item("last_check", last_check) app.set_state_item("last_check", last_check)

View File

@ -22,13 +22,15 @@ 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.9.0,<2", "tool-pioplus": ">=0.9.1,<2",
"tool-unity": "~1.20302.1", "tool-unity": "~1.20302.1",
"tool-scons": "~3.20501.2" "tool-scons": "~3.20501.2"
} }
PIOPLUS_AUTO_UPDATES_MAX = 100 PIOPLUS_AUTO_UPDATES_MAX = 100
# pylint: disable=arguments-differ
class CorePackageManager(PackageManager): class CorePackageManager(PackageManager):
@ -41,13 +43,12 @@ 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, def install(self, name, requirements=None, *args, **kwargs):
**kwargs): # pylint: disable=arguments-differ
PackageManager.install(self, name, requirements, *args, **kwargs) PackageManager.install(self, name, requirements, *args, **kwargs)
self.cleanup_packages() self.cleanup_packages()
return self.get_package_dir(name, requirements) return self.get_package_dir(name, requirements)
def update(self, *args, **kwargs): # pylint: disable=arguments-differ def update(self, *args, **kwargs):
result = PackageManager.update(self, *args, **kwargs) result = PackageManager.update(self, *args, **kwargs)
self.cleanup_packages() self.cleanup_packages()
return result return result

View File

@ -516,8 +516,8 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
# Handle GitHub URL (https://github.com/user/package) # Handle GitHub URL (https://github.com/user/package)
url.startswith("https://github.com/") and not url.endswith( url.startswith("https://github.com/") and not url.endswith(
(".zip", ".tar.gz")), (".zip", ".tar.gz")),
url.startswith("http") and url.startswith("http")
(url.split("#", 1)[0] if "#" in url else url).endswith(".git") and (url.split("#", 1)[0] if "#" in url else url).endswith(".git")
] ]
if any(git_conditions): if any(git_conditions):
url = "git+" + url url = "git+" + url

View File

@ -38,8 +38,8 @@ class PlatformManager(BasePkgManager):
"{0}://dl.platformio.org/platforms/manifest.json".format( "{0}://dl.platformio.org/platforms/manifest.json".format(
"https" if app.get_setting("enable_ssl") else "http") "https" if app.get_setting("enable_ssl") else "http")
] ]
BasePkgManager.__init__(self, package_dir or BasePkgManager.__init__(self, package_dir
join(util.get_home_dir(), "platforms"), or join(util.get_home_dir(), "platforms"),
repositories) repositories)
@property @property
@ -144,8 +144,8 @@ class PlatformManager(BasePkgManager):
for manifest in pm.get_installed(): for manifest in pm.get_installed():
if manifest['name'] not in names: if manifest['name'] not in names:
continue continue
if (manifest['name'] not in deppkgs or if (manifest['name'] not in deppkgs
manifest['version'] not in deppkgs[manifest['name']]): or manifest['version'] not in deppkgs[manifest['name']]):
pm.uninstall(manifest['__pkg_dir'], trigger_event=False) pm.uninstall(manifest['__pkg_dir'], trigger_event=False)
self.cache_reset() self.cache_reset()
@ -168,12 +168,12 @@ class PlatformManager(BasePkgManager):
def board_config(self, id_, platform=None): def board_config(self, id_, platform=None):
for manifest in self.get_installed_boards(): for manifest in self.get_installed_boards():
if manifest['id'] == id_ and (not platform or if manifest['id'] == id_ and (not platform
manifest['platform'] == platform): or manifest['platform'] == platform):
return manifest return manifest
for manifest in self.get_registered_boards(): for manifest in self.get_registered_boards():
if manifest['id'] == id_ and (not platform or if manifest['id'] == id_ and (not platform
manifest['platform'] == platform): or manifest['platform'] == platform):
return manifest return manifest
raise exception.UnknownBoard(id_) raise exception.UnknownBoard(id_)
@ -270,8 +270,8 @@ class PlatformPackagesMixin(object):
if _opts.get("type") == item: if _opts.get("type") == item:
candidate = _name candidate = _name
if (self.frameworks and item.startswith("framework-") and if (self.frameworks and item.startswith("framework-")
item[10:] in self.frameworks): and item[10:] in self.frameworks):
candidate = self.frameworks[item[10:]]['package'] candidate = self.frameworks[item[10:]]['package']
result.append(candidate) result.append(candidate)
@ -498,8 +498,8 @@ class PlatformBase( # pylint: disable=too-many-public-methods
config = PlatformBoardConfig(manifest_path) config = PlatformBoardConfig(manifest_path)
if "platform" in config and config.get("platform") != self.name: if "platform" in config and config.get("platform") != self.name:
return return
elif ("platforms" in config and elif ("platforms" in config
self.name not in config.get("platforms")): and self.name not in config.get("platforms")):
return return
config.manifest['platform'] = self.name config.manifest['platform'] = self.name
self._BOARDS_CACHE[board_id] = config self._BOARDS_CACHE[board_id] = config
@ -645,6 +645,7 @@ class PlatformBoardConfig(object):
int(self._manifest.get("build", {}).get("f_cpu", "0L")[:-1]), int(self._manifest.get("build", {}).get("f_cpu", "0L")[:-1]),
"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),
"connectivity": self._manifest.get("connectivity"),
"frameworks": self._manifest.get("frameworks"), "frameworks": self._manifest.get("frameworks"),
"debug": self.get_debug_data(), "debug": self.get_debug_data(),
"vendor": self._manifest['vendor'], "vendor": self._manifest['vendor'],

View File

@ -92,12 +92,26 @@ class MeasurementProtocol(TelemetryBase):
self['an'] = " ".join(dpdata) self['an'] = " ".join(dpdata)
def _prefill_custom_data(self): def _prefill_custom_data(self):
def _filter_args(items):
result = []
stop = False
for item in items:
item = str(item).lower()
result.append(item)
if stop:
break
if item == "account":
stop = True
return result
caller_id = str(app.get_session_var("caller_id")) caller_id = str(app.get_session_var("caller_id"))
self['cd1'] = util.get_systype() self['cd1'] = util.get_systype()
self['cd2'] = "Python/%s %s" % (platform.python_version(), self['cd2'] = "Python/%s %s" % (platform.python_version(),
platform.platform()) platform.platform())
self['cd4'] = 1 if (not util.is_ci() and self['cd3'] = " ".join(_filter_args(sys.argv[1:]))
(caller_id or not util.is_container())) else 0 self['cd4'] = 1 if (not util.is_ci()
and (caller_id or not util.is_container())) else 0
if caller_id: if caller_id:
self['cd5'] = caller_id.lower() self['cd5'] = caller_id.lower()
@ -109,7 +123,6 @@ class MeasurementProtocol(TelemetryBase):
return _arg return _arg
return None return None
self['cd3'] = " ".join([str(s).lower() for s in sys.argv[1:]])
if not app.get_session_var("command_ctx"): if not app.get_session_var("command_ctx"):
return return
ctx_args = app.get_session_var("command_ctx").args ctx_args = app.get_session_var("command_ctx").args
@ -301,12 +314,15 @@ def on_event(category, action, label=None, value=None, screen_name=None):
def on_exception(e): def on_exception(e):
skip = any([ skip_conditions = [
isinstance(e, cls) isinstance(e, cls)
for cls in (IOError, exception.AbortedByUser, for cls in (IOError, exception.AbortedByUser,
exception.NotGlobalLibDir, exception.InternetIsOffline) exception.NotGlobalLibDir, exception.InternetIsOffline,
]) exception.NotPlatformIOProject,
if skip: exception.UserSideException)
]
skip_conditions.append("[API] Account: " in str(e))
if any(skip_conditions):
return return
is_crash = any([ is_crash = any([
not isinstance(e, exception.PlatformioException), not isinstance(e, exception.PlatformioException),

View File

@ -200,8 +200,8 @@ def get_project_optional_dir(name, default=None):
else: else:
try: try:
config = load_project_config() config = load_project_config()
if (config.has_section("platformio") and if (config.has_section("platformio")
config.has_option("platformio", name)): and config.has_option("platformio", name)):
data = config.get("platformio", name) data = config.get("platformio", name)
except exception.NotPlatformIOProject: except exception.NotPlatformIOProject:
pass pass
@ -327,6 +327,15 @@ def load_project_config(path=None):
return cp return cp
def parse_conf_multi_values(items):
if not items:
return []
return [
item.strip() for item in items.split("\n" if "\n" in items else ", ")
if item.strip()
]
def change_filemtime(path, time): def change_filemtime(path, time):
os.utime(path, (time, time)) os.utime(path, (time, time))

View File

@ -19,7 +19,7 @@ from sys import modules
from urlparse import urlparse from urlparse import urlparse
from platformio import util from platformio import util
from platformio.exception import PlatformioException from platformio.exception import PlatformioException, UserSideException
class VCSClientFactory(object): class VCSClientFactory(object):
@ -64,7 +64,7 @@ class VCSClientBase(object):
else: else:
assert self.run_cmd(["--version"]) assert self.run_cmd(["--version"])
except (AssertionError, OSError, PlatformioException): except (AssertionError, OSError, PlatformioException):
raise PlatformioException( raise UserSideException(
"VCS: `%s` client is not installed in your system" % "VCS: `%s` client is not installed in your system" %
self.command) self.command)
return True return True

View File

@ -31,6 +31,7 @@ basepython = python2.7
deps = deps =
sphinx sphinx
sphinx_rtd_theme sphinx_rtd_theme
restructuredtext-lint
commands = commands =
sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html
sphinx-build -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex sphinx-build -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex