Decentralized architecture for development platforms // Issue #479

This commit is contained in:
Ivan Kravets
2016-05-26 19:43:36 +03:00
parent 349b159a7b
commit d68eb28629
40 changed files with 1269 additions and 1042 deletions

View File

@ -1,3 +1,3 @@
[settings]
line_length=79
known_third_party=bottle,click,lockfile,pytest,requests,serial,SCons
known_third_party=bottle,click,lockfile,pytest,requests,semantic_version,serial,SCons

View File

@ -1,6 +1,17 @@
Release Notes
=============
PlatformIO 3.0
--------------
3.0.0 (2016-??-??)
~~~~~~~~~~~~~~~~~~
* Decentralized architecture for development platforms: "platform.json",
semantic versioning, package dependencies, embedded board configs, isolated
build scripts
(`issue #479 <https://github.com/platformio/platformio/issues/479>`_)
PlatformIO 2.0
--------------

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -152,7 +152,7 @@ Examples
- sudo pip install -U platformio
# pre-install PlatformIO development platforms, they will be cached
- platformio platforms install atmelavr atmelsam teensy
- platformio platform install atmelavr atmelsam teensy
#
# Libraries from PlatformIO Library Registry:

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -41,11 +41,11 @@ Platform Manager
Used in demo
~~~~~~~~~~~~
1. :ref:`userguide_platforms`
2. :ref:`cmd_platforms_list` command
3. :ref:`platformio platforms search avr <cmd_platforms_search>` command
4. :ref:`platformio platforms show teensy <cmd_platforms_show>` command
5. :ref:`cmd_platforms_update` command.
1. :ref:`userguide_platform`
2. :ref:`cmd_platform_list` command
3. :ref:`platformio platform search avr <cmd_platform_search>` command
4. :ref:`platformio platform show teensy <cmd_platform_show>` command
5. :ref:`cmd_platform_update` command.
Library Manager
---------------

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -58,7 +58,7 @@ Embedded Development. *Easier Than Ever.*
* Built-in :ref:`Serial Port Monitor <cmd_serialports_monitor>` and
configurable build :ref:`-flags/-options <projectconf_build_flags>`
* Pre-built toolchains, :ref:`frameworks` for the
:ref:`Development Platforms <platforms>`
:ref:`platforms`
Smart Build System. *Fast and Reliable.*
----------------------------------------
@ -108,7 +108,7 @@ Contents
:caption: Instruments
:maxdepth: 3
Platforms & Boards <platforms/index>
platforms/index
frameworks/index
.. toctree::

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -33,10 +33,10 @@ JSON Structure
The key fields:
* ``build`` data will be used by :ref:`Platforms <platforms>` and
* ``build`` data will be used by :ref:`platforms` and
:ref:`frameworks` builders
* ``frameworks`` is the list with supported :ref:`frameworks`
* ``platform`` main type of :ref:`Platforms <platforms>`
* ``platform`` main type of :ref:`platforms`
* ``upload`` upload settings which depend on the ``platform``
.. code-block:: json

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -27,7 +27,7 @@ different/own build scripts, uploader and etc.
.. note::
If you want to change some build flags for the existing
:ref:`Platforms <platforms>`, you don't need to create (or duplicate) own
:ref:`platforms`, you don't need to create (or duplicate) own
development platforms! Please use :ref:`projectconf_build_flags` option.
**Step-by-Step Manual**
@ -361,9 +361,9 @@ Installation
1. Create ``platforms`` directory in :ref:`projectconf_pio_home_dir` if it
doesn't exist.
2. Copy ``test.py`` and ``test-builder.py`` files to ``platforms`` directory.
3. Search available platforms via :ref:`cmd_platforms_search` command. You should see
3. Search available platforms via :ref:`cmd_platform_search` command. You should see
``test`` platform.
4. Install ``test`` platform via :ref:`cmd_platforms_install` command.
4. Install ``test`` platform via :ref:`cmd_platform_install` command.
Now, you can use ``test`` for the :ref:`projectconf_env_platform` option in
:ref:`projectconf`.
@ -480,6 +480,6 @@ and copy there two files:
Default([target_firm, target_size])
Now, we should see ``ststm32gdb`` platform using :ref:`cmd_platforms_search` command output
and can install it via :ref:`platformio platforms install ststm32gdb <cmd_platforms_install>` command.
Now, we should see ``ststm32gdb`` platform using :ref:`cmd_platform_search` command output
and can install it via :ref:`platformio platform install ststm32gdb <cmd_platform_install>` command.

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -11,8 +11,8 @@
.. _platforms:
Platforms & Embedded Boards
===========================
Development Platforms
=====================
*PlatformIO* has pre-built different development platforms for popular OS
(*Mac OS X, Linux (+ARM) and Windows*). Each of them include compiler,

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -194,7 +194,7 @@ General options
``platform``
^^^^^^^^^^^^
:ref:`Platform <platforms>` type.
:ref:`platforms` name.
.. _projectconf_env_framework:
@ -202,7 +202,7 @@ General options
``framework``
^^^^^^^^^^^^^
:ref:`Framework <frameworks>` type.
:ref:`frameworks` name.
The multiple frameworks are allowed, split them with comma ``,`` separator.

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -33,6 +33,11 @@ Options
.. program:: platformio boards
.. option::
--installed
List boards only from the installed platforms
.. option::
--json-output

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -27,7 +27,7 @@ Usage
Description
-----------
Check or update installed :ref:`Platforms <platforms>` and
Check or update installed :ref:`platforms` and
:ref:`Libraries <librarymanager>`

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -62,7 +62,7 @@ Commands
cmd_boards
cmd_ci
cmd_init
platformio platforms <platforms/index>
platformio platform <platforms/index>
cmd_run
cmd_serialports
cmd_settings

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_install:
.. _cmd_platform_install:
platformio platforms install
============================
platformio platform install
===========================
.. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash
platformio platforms install [OPTIONS] [PLATFORMS]
platformio platform install [OPTIONS] [PLATFORMS]
Description
-----------
Install pre-built development :ref:`Platforms <platforms>` with related
Install pre-built development :ref:`platforms` with related
packages.
There are several predefined aliases for packages, such as:
@ -38,7 +38,7 @@ There are several predefined aliases for packages, such as:
Options
-------
.. program:: platformio platforms install
.. program:: platformio platform install
.. option::
--with-package
@ -63,7 +63,7 @@ Examples
.. code-block:: bash
$ platformio platforms install timsp430
$ platformio platform install timsp430
Installing toolchain-timsp430 package:
Downloading [####################################] 100%
Unpacking [####################################] 100%
@ -81,7 +81,7 @@ Examples
.. code-block:: bash
$ platformio platforms install timsp430 --skip-default-package --with-package=uploader
$ platformio platform install timsp430 --skip-default-package --with-package=uploader
Installing tool-mspdebug package:
Downloading [####################################] 100%
Unpacking [####################################] 100%

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_list:
.. _cmd_platform_list:
platformio platforms list
=========================
platformio platform list
========================
.. contents::
@ -21,18 +21,18 @@ Usage
.. code-block:: bash
platformio platforms list [OPTIONS]
platformio platform list [OPTIONS]
Description
-----------
List installed :ref:`Platforms <platforms>`
List installed :ref:`platforms`
Options
~~~~~~~
.. program:: platformio platforms list
.. program:: platformio platform list
.. option::
--json-output
@ -44,13 +44,28 @@ Examples
.. code-block:: bash
$ platformio platforms list
atmelavr with packages: toolchain-atmelavr, tool-avrdude, framework-arduinoavr, tool-micronucleus
atmelsam with packages: framework-arduinosam, ldscripts, toolchain-gccarmnoneeabi, tool-bossac
freescalekinetis with packages: framework-mbed, toolchain-gccarmnoneeabi
nordicnrf51 with packages: framework-mbed, toolchain-gccarmnoneeabi
nxplpc with packages: framework-mbed, toolchain-gccarmnoneeabi
ststm32 with packages: framework-libopencm3, toolchain-gccarmnoneeabi, tool-stlink, framework-spl, framework-cmsis, framework-mbed, ldscripts
teensy with packages: toolchain-atmelavr, ldscripts, framework-arduinoteensy, toolchain-gccarmnoneeabi, tool-teensy
timsp430 with packages: toolchain-timsp430, tool-mspdebug, framework-energiamsp430, framework-arduinomsp430
titiva with packages: ldscripts, framework-libopencm3, toolchain-gccarmnoneeabi, tool-lm4flash, framework-energiativa
$ platformio platform list
atmelavr ~ Atmel AVR
====================
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance, power efficiency and design flexibility. Optimized to speed time to market-and easily adapt to new ones-they are based on the industrys most code-efficient architecture for C and assembly programming.
Home: http://platformio.org/platforms/atmelavr
Packages: toolchain-atmelavr, framework-simba
Version: 0.0.0
atmelsam ~ Atmel SAM
====================
Atmel | SMART offers Flash- based ARM products based on the ARM Cortex-M0+, Cortex-M3 and Cortex-M4 architectures, ranging from 8KB to 2MB of Flash including a rich peripheral and feature mix.
Home: http://platformio.org/platforms/atmelsam
Packages: framework-arduinosam, framework-mbed, framework-simba, toolchain-gccarmnoneeabi, tool-bossac
Version: 0.0.0
espressif ~ Espressif
=====================
Espressif Systems is a privately held fabless semiconductor company. They provide wireless communications and Wi-Fi chips which are widely used in mobile devices and the Internet of Things applications.
Home: http://platformio.org/platforms/espressif
Packages: framework-simba, tool-esptool, framework-arduinoespressif, sdk-esp8266, toolchain-xtensa
Version: 0.0.0
...

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_search:
.. _cmd_platform_search:
platformio platforms search
===========================
platformio platform search
==========================
.. contents::
@ -21,18 +21,18 @@ Usage
.. code-block:: bash
platformio platforms search QUERY [OPTIONS]
platformio platform search QUERY [OPTIONS]
Description
-----------
Search for development :ref:`Platforms <platforms>`
Search for development :ref:`platforms`
Options
~~~~~~~
.. program:: platformio platforms search
.. program:: platformio platform search
.. option::
--json-output
@ -47,73 +47,100 @@ Examples
.. code-block:: bash
$ platformio platforms search
atmelavr (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
--------
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance...
$ platformio platform search
atmelavr ~ Atmel AVR
====================
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance, power efficiency and design flexibility. Optimized to speed time to market-and easily adapt to new ones-they are based on the industrys most code-efficient architecture for C and assembly programming.
atmelsam (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
--------
Atmel | SMART offers Flash- based ARM products based on the ...
Home: http://platformio.org/platforms/atmelavr
Packages: toolchain-atmelavr, framework-simba
Version: 0.0.0
freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
----------------
Freescale Kinetis Microcontrollers is family of multiple hardware- and ...
atmelsam ~ Atmel SAM
====================
Atmel | SMART offers Flash- based ARM products based on the ARM Cortex-M0+, Cortex-M3 and Cortex-M4 architectures, ranging from 8KB to 2MB of Flash including a rich peripheral and feature mix.
nordicnrf51 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-----------
The Nordic nRF51 Series is a family of highly flexible, multi-protocol ...
Home: http://platformio.org/platforms/atmelsam
Packages: framework-arduinosam, framework-mbed, framework-simba, toolchain-gccarmnoneeabi, tool-bossac
Version: 0.0.0
nxplpc (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
------
The NXP LPC is a family of 32-bit microcontroller integrated circuits ...
espressif ~ Espressif
=====================
Espressif Systems is a privately held fabless semiconductor company. They provide wireless communications and Wi-Fi chips which are widely used in mobile devices and the Internet of Things applications.
ststm32 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-------
The STM32 family of 32-bit Flash MCUs based on the ARM Cortex-M ...
teensy (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
------
Teensy is a complete USB-based microcontroller development syste ...
timsp430 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
--------
MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are ...
titiva (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
------
Texas Instruments TM4C12x MCUs offer the industrys most popular ...
Home: http://platformio.org/platforms/espressif
Packages: framework-simba, tool-esptool, framework-arduinoespressif, sdk-esp8266, toolchain-xtensa
Version: 0.0.0
...
2. Search for TI development platforms
.. code-block:: bash
$ platformio platforms search ti
timsp430 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
--------
MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are ...
$ platformio platform search texas
timsp430 ~ TI MSP430
====================
MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are 16-bit, RISC-based, mixed-signal processors designed for ultra-low power. These MCUs offer the lowest power consumption and the perfect mix of integrated peripherals for thousands of applications.
titiva (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
------
Texas Instruments TM4C12x MCUs offer the industrys most popular ...
Home: http://platformio.org/platforms/timsp430
Packages: toolchain-timsp430, tool-mspdebug, framework-energiamsp430, framework-arduinomsp430
3. Search for development platforms which support "mbed Framework"
titiva ~ TI TIVA
================
Texas Instruments TM4C12x MCUs offer the industrys most popular ARM Cortex-M4 core with scalable memory and package options, unparalleled connectivity peripherals, advanced application functions, industry-leading analog integration, and extensive software solutions.
Home: http://platformio.org/platforms/titiva
Packages: ldscripts, framework-libopencm3, toolchain-gccarmnoneeabi, tool-lm4flash, framework-energiativa
.. code-block:: bash
$ platformio platforms search mbed
freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
----------------
Freescale Kinetis Microcontrollers is family of multiple hardware- and ...
$ platformio platform search framework-mbed
atmelsam ~ Atmel SAM
====================
Atmel | SMART offers Flash- based ARM products based on the ARM Cortex-M0+, Cortex-M3 and Cortex-M4 architectures, ranging from 8KB to 2MB of Flash including a rich peripheral and feature mix.
nordicnrf51 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-----------
The Nordic nRF51 Series is a family of highly flexible, multi-protocol ...
Home: http://platformio.org/platforms/atmelsam
Packages: toolchain-gccarmnoneeabi, framework-arduinosam, framework-simba, tool-openocd, framework-mbed, ldscripts, tool-bossac
nxplpc (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
------
The NXP LPC is a family of 32-bit microcontroller integrated circuits ...
freescalekinetis ~ Freescale Kinetis
====================================
Freescale Kinetis Microcontrollers is family of multiple hardware- and software-compatible ARM Cortex-M0+, Cortex-M4 and Cortex-M7-based MCU series. Kinetis MCUs offer exceptional low-power performance, scalability and feature integration.
ststm32 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-------
The STM32 family of 32-bit Flash MCUs based on the ARM Cortex-M ...
Home: http://platformio.org/platforms/freescalekinetis
Packages: framework-mbed, toolchain-gccarmnoneeabi
nordicnrf51 ~ Nordic nRF51
==========================
The Nordic nRF51 Series is a family of highly flexible, multi-protocol, system-on-chip (SoC) devices for ultra-low power wireless applications. nRF51 Series devices support a range of protocol stacks including Bluetooth Smart (previously called Bluetooth low energy), ANT and proprietary 2.4GHz protocols such as Gazell.
Home: http://platformio.org/platforms/nordicnrf51
Packages: framework-mbed, tool-rfdloader, toolchain-gccarmnoneeabi, framework-arduinonordicnrf51
nxplpc ~ NXP LPC
================
The NXP LPC is a family of 32-bit microcontroller integrated circuits by NXP Semiconductors. The LPC chips are grouped into related series that are based around the same 32-bit ARM processor core, such as the Cortex-M4F, Cortex-M3, Cortex-M0+, or Cortex-M0. Internally, each microcontroller consists of the processor core, static RAM memory, flash memory, debugging interface, and various peripherals.
Home: http://platformio.org/platforms/nxplpc
Packages: framework-mbed, toolchain-gccarmnoneeabi
siliconlabsefm32 ~ Silicon Labs EFM32
=====================================
Silicon Labs EFM32 Gecko 32-bit microcontroller (MCU) family includes devices that offer flash memory configurations up to 256 kB, 32 kB of RAM and CPU speeds up to 48 MHz. Based on the powerful ARM Cortex-M core, the Gecko family features innovative low energy techniques, short wake-up time from energy saving modes and a wide selection of peripherals, making it ideal for battery operated applications and other systems requiring high performance and low-energy consumption.
Home: http://platformio.org/platforms/siliconlabsefm32
Packages: framework-mbed, toolchain-gccarmnoneeabi
ststm32 ~ ST STM32
==================
The STM32 family of 32-bit Flash MCUs based on the ARM Cortex-M processor is designed to offer new degrees of freedom to MCU users. It offers a 32-bit product range that combines very high performance, real-time capabilities, digital signal processing, and low-power, low-voltage operation, while maintaining full integration and ease of development.
Home: http://platformio.org/platforms/ststm32
Packages: framework-libopencm3, toolchain-gccarmnoneeabi, tool-stlink, framework-spl, framework-cmsis, framework-mbed, ldscripts
teensy ~ Teensy
===============
Teensy is a complete USB-based microcontroller development system, in a very small footprint, capable of implementing many types of projects. All programming is done via the USB port. No special programmer is needed, only a standard USB cable and a PC or Macintosh with a USB port.
Home: http://platformio.org/platforms/teensy
Packages: framework-arduinoteensy, tool-teensy, toolchain-gccarmnoneeabi, framework-mbed, toolchain-atmelavr, ldscripts
...

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_show:
.. _cmd_platform_show:
platformio platforms show
=========================
platformio platform show
========================
.. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash
platformio platforms show PLATFORM
platformio platform show PLATFORM
Description
-----------
Show details about the installed :ref:`Platforms <platforms>`
Show details about the installed :ref:`platforms`
Examples
@ -35,22 +35,53 @@ Examples
.. code-block:: bash
$ platformio platforms show atmelavr
atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework)
----------
Package: toolchain-atmelavr
Alias: toolchain
Version: 1
Installed: 2014-12-13 23:58:48
----------
Package: tool-avrdude
Version: 2
Installed: 2015-02-13 22:23:17
----------
Package: framework-arduinoavr
Version: 12
Installed: 2015-02-23 20:57:40
----------
Package: tool-micronucleus
Version: 1
Installed: 2015-02-23 21:20:14
$ platformio platform show atmelavr
atmelavr ~ Atmel AVR
====================
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance, power efficiency and design flexibility. Optimized to speed time to market-and easily adapt to new ones-they are based on the industrys most code-efficient architecture for C and assembly programming.
Version: 0.0.0
Home: http://platformio.org/platforms/atmelavr
License: Apache-2.0
Frameworks: simba, arduino
Package toolchain-atmelavr
--------------------------
Type: toolchain
Optional: No
Requirements: ~1.40801.0
Installed: Yes
Description: avr-gcc
Url: https://gcc.gnu.org/wiki/avr-gcc
Version: 1.40801.0
Package framework-arduinoavr
----------------------------
Type: framework
Optional: Yes
Requirements: ~1.10608.0
Installed: No (optional)
Package framework-simba
-----------------------
Type: framework
Optional: Yes
Requirements: ~1.50.0
Installed: Yes
Description: framework-simba
Url: https://github.com/eerimoq/simba
Version: 1.50.0
Package tool-avrdude
--------------------
Type: uploader
Optional: Yes
Requirements: >=1.60001.0,<=1.60100.0
Installed: No (optional)
Package tool-micronucleus
-------------------------
Type: uploader
Optional: Yes
Requirements: ~1.200.0
Installed: No (optional)

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_uninstall:
.. _cmd_platform_uninstall:
platformio platforms uninstall
==============================
platformio platform uninstall
=============================
.. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash
platformio platforms uninstall PLATFORM
platformio platform uninstall PLATFORM
Description
-----------
Uninstall specified :ref:`Platforms <platforms>`
Uninstall specified :ref:`platforms`
Examples
@ -35,7 +35,7 @@ Examples
.. code-block:: bash
$ platformio platforms uninstall timsp430
$ platformio platform uninstall timsp430
Uninstalling toolchain-timsp430 package: [OK]
Uninstalling tool-mspdebug package: [OK]
Uninstalling framework-energiamsp430 package: [OK]

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _cmd_platforms_update:
.. _cmd_platform_update:
platformio platforms update
===========================
platformio platform update
==========================
.. contents::
@ -21,90 +21,100 @@ Usage
.. code-block:: bash
platformio platforms update
platformio platform update
Description
-----------
Check or update installed :ref:`Platforms <platforms>`
Check or update installed :ref:`platforms`
Options
-------
.. program:: platformio platform update
.. option::
--only-packages
Update only platform related packages. Do not update development platform
build scripts, board configs and etc.
Examples
--------
.. code-block:: bash
$ platformio platforms update
$ platformio platform update
Platform atmelavr
--------
Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-avrdude package:
Versions: Current=2, Latest=2 [Up-to-date]
Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-arduinoavr package:
Versions: Current=12, Latest=12 [Up-to-date]
Versions: Current=12, Latest=12 [Up-to-date]
Updating tool-micronucleus package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Platform atmelsam
--------
Updating framework-arduinosam package:
Versions: Current=3, Latest=3 [Up-to-date]
Versions: Current=3, Latest=3 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-bossac package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Platform stm32
--------
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-stlink package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-spl package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-cmsis package:
Versions: Current=2, Latest=2 [Up-to-date]
Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Platform teensy
--------
Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-arduinoteensy package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-teensy package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Platform timsp430
--------
Updating toolchain-timsp430 package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-mspdebug package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiamsp430 package:
Versions: Current=2, Latest=2 [Up-to-date]
Versions: Current=2, Latest=2 [Up-to-date]
Platform titiva
--------
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-lm4flash package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date]
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiativa package:
Versions: Current=4, Latest=4 [Up-to-date]
Versions: Current=4, Latest=4 [Up-to-date]

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -9,7 +9,7 @@
See the License for the specific language governing permissions and
limitations under the License.
.. _userguide_platforms:
.. _userguide_platform:
Platform Manager
================
@ -18,8 +18,8 @@ To print all available commands and options use:
.. code-block:: bash
$ platformio platforms --help
$ platformio platforms COMMAND --help
$ platformio platform --help
$ platformio platform COMMAND --help
.. image:: ../../_static/platformio-demo-platforms.gif

View File

@ -1,4 +1,4 @@
.. Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
.. Copyright 2014-present Ivan Kravets <me@ikravets.com>
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
@ -76,7 +76,7 @@ Alright, so PlatformIO can run on different operating systems. But more
importantly, from development perspective at least, is a list of supported
boards and MCUs. To keep things short: PlatformIO supports approximately 200
`Embedded Boards <http://platformio.org/boards>`_ and all major
:ref:`Development Platforms <platforms>`.
:ref:`platforms`.
User SHOULD have a choice
-------------------------

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
import sys
VERSION = (2, 9, "2.dev0")
VERSION = (3, 0, "0.dev0")
__version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio"

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -51,15 +51,9 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
@staticmethod
def _handle_obsolate_command(name):
if name in ("install", "list", "search", "show", "uninstall"):
click.secho(
"Warning! `platformio %s` command is deprecated and will be "
"removed in the next release! Please use "
"`platformio platforms %s` instead." % (name, name),
fg="yellow"
)
from platformio.commands import platforms
return getattr(platforms, "platforms_" + name)
if name == "platforms":
from platformio.commands import platform
return platform.cli
raise AttributeError()

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -22,23 +22,18 @@ from time import time
from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, Variables
from platformio import util
from platformio.exception import UnknownBoard
# AllowSubstExceptions()
# allow common variables from INI file
commonvars = Variables(None)
commonvars.AddVariables(
("PLATFORM_MANIFEST",),
("BUILD_SCRIPT",),
("EXTRA_SCRIPT",),
("PIOENV",),
("PLATFORM",),
# package aliases
("PIOPACKAGE_TOOLCHAIN",),
("PIOPACKAGE_FRAMEWORK",),
("PIOPACKAGE_UPLOADER",),
# options
("FRAMEWORK",),
("BUILD_FLAGS",),
@ -67,9 +62,9 @@ commonvars.AddVariables(
DefaultEnvironment(
tools=[
"gcc", "g++", "as", "ar", "gnulink",
"platformio", "pioupload", "pioar", "piomisc"
"platformio", "devplatform", "pioupload", "pioar", "piomisc"
],
toolpath=[join("$PIOBUILDER_DIR", "tools")],
toolpath=[join(util.get_source_dir(), "builder", "tools")],
variables=commonvars,
# Propagating External Environment
@ -85,15 +80,11 @@ DefaultEnvironment(
PROJECTDATA_DIR=util.get_projectdata_dir(),
PIOENVS_DIR=util.get_pioenvs_dir(),
PIOBUILDER_DIR=join(util.get_source_dir(), "builder"),
PIOPACKAGES_DIR=join("$PIOHOME_DIR", "packages"),
BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"),
BUILDSRC_DIR=join("$BUILD_DIR", "src"),
LIBSOURCE_DIRS=[
"$PROJECTLIB_DIR",
util.get_lib_dir(),
join("$PLATFORMFW_DIR", "libraries")
util.get_lib_dir()
],
PYTHONEXE=normpath(sys.executable)
@ -106,58 +97,27 @@ for k in commonvars.keys():
if k in env:
env[k] = base64.b64decode(env[k])
env.Prepend(LIBPATH=[join("$PIOPACKAGES_DIR", "ldscripts")])
if "BOARD" in env:
try:
env.Replace(BOARD_OPTIONS=util.get_boards(env.subst("$BOARD")))
except UnknownBoard as e:
env.Exit("Error: %s" % str(e))
for k in commonvars.keys():
if (k in env or
not any([k.startswith("BOARD_"), k.startswith("UPLOAD_")])):
continue
_opt, _val = k.lower().split("_", 1)
if _opt == "board":
_opt = "build"
if _val in env['BOARD_OPTIONS'][_opt]:
env.Replace(**{k: "${BOARD_OPTIONS['%s']['%s']}" % (_opt, _val)})
if "ldscript" in env.get("BOARD_OPTIONS", {}).get("build", {}):
env.Replace(
LDSCRIPT_PATH="${BOARD_OPTIONS['build']['ldscript']}"
)
if env['PLATFORM'] != env.get("BOARD_OPTIONS", {}).get("platform"):
env.Exit(
"Error: '%s' platform doesn't support this board. "
"Use '%s' platform instead." % (
env['PLATFORM'], env.get("BOARD_OPTIONS", {}).get("platform")))
env.LoadDevPlatform(commonvars)
# Parse library names
for opt in ("LIB_IGNORE", "LIB_USE"):
if opt not in env:
continue
env[opt] = [l.strip() for l in env[opt].split(",") if l.strip()]
if env.subst("$PIOPACKAGE_TOOLCHAIN"):
env.PrependENVPath(
"PATH",
env.subst(join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN", "bin"))
)
# handle custom variable from system environment
# Handle custom variables from system environment
for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPT",
"UPLOAD_PORT", "UPLOAD_FLAGS"):
k = "PLATFORMIO_%s" % var
if environ.get(k):
env[var] = environ.get(k)
env.SConscriptChdir(0)
env.SConsignFile(join("$PIOENVS_DIR", ".sconsign.dblite"))
env.SConscript("$BUILD_SCRIPT")
if "UPLOAD_FLAGS" in env:
env.Append(UPLOADERFLAGS=["$UPLOAD_FLAGS"])

View File

@ -0,0 +1,107 @@
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# 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 isdir, isfile, join
from SCons.Script import COMMAND_LINE_TARGETS
from platformio import exception, util
from platformio.managers.platform import PlatformFactory
@util.memoized
def initDevPlatform(name):
return PlatformFactory.newPlatform(name)
def DevPlatform(env):
variables = {}
for key in ("board", "framework"):
if key not in env:
continue
variables[key] = env[key.upper()]
p = initDevPlatform(env['PLATFORM_MANIFEST'])
p.configure_default_packages(variables, COMMAND_LINE_TARGETS)
return p
def BoardConfig(env, board=None):
p = initDevPlatform(env['PLATFORM_MANIFEST'])
try:
config = p.board_config(board if board else env['BOARD'])
except exception.UnknownBoard as e:
env.Exit("Error: %s" % str(e))
return config
def GetFrameworkScript(env, framework):
p = env.DevPlatform()
frameworks = p.get_frameworks()
assert frameworks and framework in frameworks
script_path = env.subst(frameworks[framework]['script'])
if not isfile(script_path):
script_path = join(p.get_dir(), script_path)
return script_path
def LoadDevPlatform(env, variables):
p = env.DevPlatform()
installed_packages = p.get_installed_packages()
# Add toolchains and uploaders to $PATH
for name in installed_packages.keys():
type_ = p.get_package_type(name)
if type_ not in ("toolchain", "uploader"):
continue
path = p.get_package_dir(name)
if isdir(join(path, "bin")):
path = join(path, "bin")
env.PrependENVPath("PATH", path)
# Platform specific LD Scripts
if isdir(join(p.get_dir(), "ldscripts")):
env.Prepend(LIBPATH=[join(p.get_dir(), "ldscripts")])
if "BOARD" not in env:
return
board_config = env.BoardConfig()
for k in variables.keys():
if (k in env or
not any([k.startswith("BOARD_"), k.startswith("UPLOAD_")])):
continue
_opt, _val = k.lower().split("_", 1)
if _opt == "board":
_opt = "build"
if _val in board_config.get(_opt):
env.Replace(**{k: board_config.get("%s.%s" % (_opt, _val))})
if "build.ldscript" in board_config:
env.Replace(
LDSCRIPT_PATH=board_config.get("build.ldscript")
)
def exists(_):
return True
def generate(env):
env.AddMethod(DevPlatform)
env.AddMethod(BoardConfig)
env.AddMethod(GetFrameworkScript)
env.AddMethod(LoadDevPlatform)
return env

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ from glob import glob
from os import environ, listdir, remove
from os.path import isdir, isfile, join
from platformio.util import exec_command, where_is_program
from platformio import util
class InoToCPPConverter(object):
@ -143,8 +143,6 @@ def ConvertInoToCpp(env):
def DumpIDEData(env):
BOARD_CORE = env.get("BOARD_OPTIONS", {}).get("build", {}).get("core")
def get_includes(env_):
includes = []
# includes from used framework and libs
@ -164,15 +162,18 @@ def DumpIDEData(env):
lsd_dir = env_.subst(d)
_append_lib_includes(env_, lsd_dir, includes)
# includes from toolchain
toolchain_dir = env_.subst(
join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN"))
toolchain_incglobs = [
join(toolchain_dir, "*", "include*"),
join(toolchain_dir, "lib", "gcc", "*", "*", "include*")
]
for g in toolchain_incglobs:
includes.extend(glob(g))
# includes from toolchains
p = env.DevPlatform()
for name in p.get_installed_packages().keys():
if p.get_package_type(name) != "toolchain":
continue
toolchain_dir = 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
@ -186,9 +187,10 @@ def DumpIDEData(env):
if name in env_.get("LIB_IGNORE", []):
continue
if name == "__cores__":
if isdir(join(libs_dir, name, BOARD_CORE)):
board_core = env_.BoardConfig().get("build.core")
if isdir(join(libs_dir, name, board_core)):
_append_lib_includes(
env_, join(libs_dir, name, BOARD_CORE), includes)
env_, join(libs_dir, name, board_core), includes)
return
include = (
@ -208,10 +210,9 @@ def DumpIDEData(env):
defines.append(env_.subst(item).replace('\\"', '"'))
# special symbol for Atmel AVR MCU
board = env_.get("BOARD_OPTIONS", {})
if board and board['platform'] == "atmelavr":
if env.subst("$PLATFORM") == "atmelavr":
defines.append(
"__AVR_%s__" % board['build']['mcu'].upper()
"__AVR_%s__" % env.BoardConfig().get("build.mcu").upper()
.replace("ATMEGA", "ATmega")
.replace("ATTINY", "ATtiny")
)
@ -226,7 +227,7 @@ def DumpIDEData(env):
"includes": get_includes(env_),
"cc_flags": env_.subst(LINTCCOM),
"cxx_flags": env_.subst(LINTCXXCOM),
"cxx_path": where_is_program(
"cxx_path": util.where_is_program(
env_.subst("$CXX"), env_.subst("${ENV['PATH']}"))
}
@ -254,7 +255,7 @@ def GetCompilerType(env):
try:
sysenv = environ.copy()
sysenv['PATH'] = str(env['ENV']['PATH'])
result = exec_command([env.subst("$CC"), "-v"], env=sysenv)
result = util.exec_command([env.subst("$CC"), "-v"], env=sysenv)
except OSError:
return None
if result['returncode'] != 0:

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -83,14 +83,16 @@ def AutodetectUploadPort(env):
env.Replace(UPLOAD_PORT=item['disk'])
break
else:
board_build_opts = env.get("BOARD_OPTIONS", {}).get("build", {})
board_hwids = []
if "BOARD" in env and "build.hwids" in env.BoardConfig():
board_hwids = env.BoardConfig().get("build.hwids")
for item in get_serialports():
if "VID:PID" not in item['hwid']:
continue
env.Replace(UPLOAD_PORT=item['port'])
for hwid in board_build_opts.get("hwid", []):
board_hwid = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
if board_hwid in item['hwid']:
for hwid in board_hwids:
hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
if hwid_str in item['hwid']:
break
if "UPLOAD_PORT" in env:

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -43,9 +43,8 @@ def BuildProgram(env):
)
# process extra flags from board
env.ProcessFlags([
env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags")
])
if "BOARD" in env and "build.extra_flags" in env.BoardConfig():
env.ProcessFlags([env.BoardConfig().get("build.extra_flags")])
# remove base flags
env.ProcessUnFlags(env.get("BUILD_UNFLAGS"))
# apply user flags
@ -208,20 +207,21 @@ def BuildFrameworks(env, frameworks):
if not frameworks or "uploadlazy" in COMMAND_LINE_TARGETS:
return
board_frameworks = env.get("BOARD_OPTIONS", {}).get("frameworks", [])
board_frameworks = []
if "BOARD" in env:
board_frameworks = env.BoardConfig().get("frameworks", [])
if frameworks == ["platformio"]:
if board_frameworks:
frameworks.insert(0, board_frameworks[0])
else:
env.Exit("Error: Please specify board type")
env.Exit("Error: Please specify `board` in `platformio.ini`")
for f in frameworks:
if f in ("arduino", "energia"):
env.ConvertInoToCpp()
if f in board_frameworks:
SConscript(env.subst(
join("$PIOBUILDER_DIR", "scripts", "frameworks", "%s.py" % f)))
SConscript(env.GetFrameworkScript(f))
else:
env.Exit("Error: This board doesn't support %s framework!" % f)

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -16,30 +16,30 @@ import json
import click
from platformio.util import get_boards
from platformio.managers.platform import PlatformManager
@click.command("list", short_help="Pre-configured Embedded Boards")
@click.command("boards", short_help="Pre-configured Embedded Boards")
@click.argument("query", required=False)
@click.option("--installed", is_flag=True)
@click.option("--json-output", is_flag=True)
def cli(query, json_output): # pylint: disable=R0912
def cli(query, installed, json_output): # pylint: disable=R0912
if json_output:
return ouput_boards_json(query)
return _ouput_boards_json(query, installed)
BOARDLIST_TPL = ("{type:<30} {mcu:<14} {frequency:<8} "
" {flash:<7} {ram:<6} {name}")
terminal_width, _ = click.get_terminal_size()
grpboards = {}
for type_, data in get_boards().items():
if data['platform'] not in grpboards:
grpboards[data['platform']] = {}
grpboards[data['platform']][type_] = data
for board in _get_boards(installed):
if board['platform'] not in grpboards:
grpboards[board['platform']] = []
grpboards[board['platform']].append(board)
for (platform, boards) in sorted(grpboards.items()):
for (platform, pboards) in sorted(grpboards.items()):
if query:
search_data = json.dumps(boards).lower()
search_data = json.dumps(pboards).lower()
if query.lower() not in search_data.lower():
continue
@ -48,45 +48,56 @@ def cli(query, json_output): # pylint: disable=R0912
click.secho(platform, bold=True)
click.echo("-" * terminal_width)
click.echo(BOARDLIST_TPL.format(
type=click.style("Type", fg="cyan"), mcu="MCU",
type=click.style("ID", fg="cyan"), mcu="MCU",
frequency="Frequency", flash="Flash", ram="RAM", name="Name"))
click.echo("-" * terminal_width)
for type_, data in sorted(boards.items(), key=lambda b: b[1]['name']):
for board in sorted(pboards, key=lambda b: b['id']):
if query:
search_data = "%s %s" % (type_, json.dumps(data).lower())
search_data = "%s %s" % (
board['id'], json.dumps(board).lower())
if query.lower() not in search_data.lower():
continue
flash_size = ""
if "maximum_size" in data.get("upload", None):
flash_size = int(data['upload']['maximum_size'])
flash_size = "%dkB" % (flash_size / 1024)
flash_size = "%dkB" % (board['rom'] / 1024)
ram_size = ""
if "maximum_ram_size" in data.get("upload", None):
ram_size = int(data['upload']['maximum_ram_size'])
if ram_size >= 1024:
if ram_size % 1024:
ram_size = "%.1fkB" % (ram_size / 1024.0)
else:
ram_size = "%dkB" % (ram_size / 1024)
ram_size = board['ram']
if ram_size >= 1024:
if ram_size % 1024:
ram_size = "%.1fkB" % (ram_size / 1024.0)
else:
ram_size = "%dB" % ram_size
ram_size = "%dkB" % (ram_size / 1024)
else:
ram_size = "%dB" % ram_size
click.echo(BOARDLIST_TPL.format(
type=click.style(type_, fg="cyan"), mcu=data['build']['mcu'],
frequency="%dMhz" % (
int(data['build']['f_cpu'][:-1]) / 1000000),
flash=flash_size, ram=ram_size, name=data['name']))
type=click.style(board['id'], fg="cyan"),
mcu=board['mcu'],
frequency="%dMhz" % (board['fcpu'] / 1000000),
flash=flash_size, ram=ram_size, name=board['name']))
def ouput_boards_json(query):
result = {}
for type_, data in get_boards().items():
def _get_boards(installed=False):
boards = PlatformManager.get_registered_boards()
if installed:
_installed_boards = [
"%s:%s" % (b['platform'], b['id'])
for b in PlatformManager().get_installed_boards()
]
_new_boards = []
for board in boards:
key = "%s:%s" % (board['platform'], board['id'])
if key in _installed_boards:
_new_boards.append(board)
boards = _new_boards
return boards
def _ouput_boards_json(query, installed=False):
result = []
for board in _get_boards(installed):
if query:
search_data = "%s %s" % (type_, json.dumps(data).lower())
search_data = "%s %s" % (board['id'], json.dumps(board).lower())
if query.lower() not in search_data.lower():
continue
result[type_] = data
result.append(board)
click.echo(json.dumps(result))

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -23,9 +23,9 @@ import click
from platformio import app
from platformio.commands.init import cli as cmd_init
from platformio.commands.init import validate_boards
from platformio.commands.run import cli as cmd_run
from platformio.exception import CIBuildEnvsEmpty
from platformio.util import get_boards
def validate_path(ctx, param, value): # pylint: disable=W0613
@ -45,22 +45,12 @@ def validate_path(ctx, param, value): # pylint: disable=W0613
raise click.BadParameter("Found invalid path: %s" % invalid_path)
def validate_boards(ctx, param, value): # pylint: disable=W0613
unknown_boards = set(value) - set(get_boards().keys())
try:
assert not unknown_boards
return value
except AssertionError:
raise click.BadParameter(
"%s. Please search for the board types using "
"`platformio boards` command" % ", ".join(unknown_boards))
@click.command("ci", short_help="Continuous Integration")
@click.argument("src", nargs=-1, callback=validate_path)
@click.option("--lib", "-l", multiple=True, callback=validate_path)
@click.option("--exclude", multiple=True)
@click.option("--board", "-b", multiple=True, callback=validate_boards)
@click.option("--board", "-b", multiple=True, metavar="ID",
callback=validate_boards)
@click.option("--build-dir", default=mkdtemp,
type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True))

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -19,21 +19,26 @@ from shutil import copyfile
import click
from platformio import app, exception, util
from platformio.commands.platforms import \
platforms_install as cli_platforms_install
from platformio.commands.platform import \
platform_install as cli_platform_install
from platformio.ide.projectgenerator import ProjectGenerator
from platformio.platforms.base import PlatformFactory
from platformio.util import get_boards, get_source_dir
from platformio.managers.platform import PlatformManager
def validate_boards(ctx, param, value): # pylint: disable=W0613
unknown_boards = set(value) - set(get_boards().keys())
pm = PlatformManager()
# check installed boards
known_boards = set([b['id'] for b in pm.get_installed_boards()])
# if boards are not listed as installed, check registered boards
if set(value) - known_boards:
known_boards = set([b['id'] for b in pm.get_registered_boards()])
unknown_boards = set(value) - known_boards
try:
assert not unknown_boards
return value
except AssertionError:
raise click.BadParameter(
"%s. Please search for the board types using "
"%s. Please search for the board ID using "
"`platformio boards` command" % ", ".join(unknown_boards))
@ -41,7 +46,7 @@ def validate_boards(ctx, param, value): # pylint: disable=W0613
@click.option("--project-dir", "-d", default=getcwd,
type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True))
@click.option("--board", "-b", multiple=True, metavar="TYPE",
@click.option("--board", "-b", multiple=True, metavar="ID",
callback=validate_boards)
@click.option("--ide",
type=click.Choice(ProjectGenerator.get_supported_ides()))
@ -90,9 +95,9 @@ def cli(ctx, project_dir, board, ide, # pylint: disable=R0913
click.secho(
"Warning! You have initialised project with more than 1 board"
" for the specified IDE.\n"
"However, the IDE features (code autocompletion, syntax lint)"
" have been configured for the first board '%s' from your list"
" '%s'." % (board[0], ", ".join(board)),
"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(
@ -115,7 +120,7 @@ def cli(ctx, project_dir, board, ide, # pylint: disable=R0913
def init_base_project(project_dir):
platformio_ini = join(project_dir, "platformio.ini")
if not isfile(platformio_ini):
copyfile(join(get_source_dir(), "projectconftpl.ini"),
copyfile(join(util.get_source_dir(), "projectconftpl.ini"),
platformio_ini)
lib_dir = join(project_dir, "lib")
@ -246,7 +251,7 @@ def init_ci_conf(project_dir):
# - pip install -U platformio
#
# script:
# - platformio ci --lib="." --board=TYPE_1 --board=TYPE_2 --board=TYPE_N
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
""")
@ -258,9 +263,9 @@ def init_cvs_ignore(project_dir):
def fill_project_envs( # pylint: disable=too-many-arguments,too-many-locals
ctx, platformio_ini, board_types, enable_auto_uploading,
ctx, platformio_ini, board_ids, enable_auto_uploading,
env_prefix, force_download):
builtin_boards = get_boards()
installed_boards = PlatformManager().get_installed_boards()
content = []
used_boards = []
used_platforms = []
@ -272,23 +277,30 @@ def fill_project_envs( # pylint: disable=too-many-arguments,too-many-locals
continue
used_boards.append(config.get(section, "board"))
for type_ in board_types:
data = builtin_boards[type_]
used_platforms.append(data['platform'])
for id_ in board_ids:
manifest = None
for boards in (
installed_boards, PlatformManager.get_registered_boards()):
for b in boards:
if b['id'] == id_:
manifest = b
break
assert manifest is not None
if type_ in used_boards:
used_platforms.append(manifest['platform'])
if id_ in used_boards:
continue
content.append("")
content.append("[env:%s%s]" % (env_prefix, type_))
content.append("platform = %s" % data['platform'])
content.append("[env:%s%s]" % (env_prefix, id_))
content.append("platform = %s" % manifest['platform'])
# find default framework for board
frameworks = data.get("frameworks")
frameworks = manifest.get("frameworks")
if frameworks:
content.append("framework = %s" % frameworks[0])
content.append("board = %s" % type_)
content.append("board = %s" % id_)
if enable_auto_uploading:
content.append("targets = upload")
@ -304,10 +316,11 @@ def fill_project_envs( # pylint: disable=too-many-arguments,too-many-locals
def _install_dependent_platforms(ctx, platforms):
installed_platforms = PlatformFactory.get_platforms(installed=True).keys()
installed_platforms = [
p['name'] for p in PlatformManager().get_installed()]
if set(platforms) <= set(installed_platforms):
return
ctx.invoke(
cli_platforms_install,
cli_platform_install,
platforms=list(set(platforms) - set(installed_platforms))
)

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -13,31 +13,76 @@
# limitations under the License.
import json
from datetime import datetime
import click
from platformio import app
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory
from platformio import app, exception, util
from platformio.managers.platform import PlatformFactory, PlatformManager
@click.group(short_help="Platforms and Packages Manager")
@click.group(short_help="Platform Manager")
def cli():
pass
def _print_platforms(platforms):
for platform in platforms:
click.echo("{name} ~ {title}".format(
name=click.style(platform['name'], fg="cyan"),
title=platform['title']))
click.echo("=" * (3 + len(platform['name'] + platform['title'])))
click.echo(platform['description'])
click.echo()
click.echo("Home: %s" %
"http://platformio.org/platforms/" + platform['name'])
if platform['packages']:
click.echo("Packages: %s" % ", ".join(platform['packages']))
if "version" in platform:
click.echo("Version: " + platform['version'])
click.echo()
@cli.command("search", short_help="Search for development platforms")
@click.argument("query", required=False)
@click.option("--json-output", is_flag=True)
def platform_search(query, json_output):
platforms = []
for platform in util.get_api_result("/platforms"):
if query == "all":
query = ""
search_data = json.dumps(platform)
if query and query.lower() not in search_data.lower():
continue
# @TODO update API with NAME/TITLE
platforms.append({
"name": platform['type'],
"title": platform['name'],
"description": platform['description'],
"packages": platform['packages']
})
if json_output:
click.echo(json.dumps(platforms))
else:
_print_platforms(platforms)
@cli.command("install", short_help="Install new platforms")
@click.argument("platforms", nargs=-1, required=True)
@click.option("--with-package", multiple=True, metavar="<package>")
@click.option("--without-package", multiple=True, metavar="<package>")
@click.option("--skip-default-package", is_flag=True)
def platforms_install(platforms, with_package, without_package,
skip_default_package):
def platform_install(platforms, with_package, without_package,
skip_default_package):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.install(with_package, without_package, skip_default_package):
_platform = platform
_version = None
if "@" in platform:
_platform, _version = platform.rsplit("@", 1)
if PlatformManager().install(_platform, _version, with_package,
without_package, skip_default_package):
click.secho(
"The platform '%s' has been successfully installed!\n"
"The rest of packages will be installed automatically "
@ -47,123 +92,96 @@ def platforms_install(platforms, with_package, without_package,
@cli.command("list", short_help="List installed platforms")
@click.option("--json-output", is_flag=True)
def platforms_list(json_output):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
data = []
for platform in installed_platforms:
p = PlatformFactory.newPlatform(platform)
data.append({
"name": platform,
"packages": p.get_installed_packages()
def platform_list(json_output):
platforms = []
for manifest in PlatformManager().get_installed():
p = PlatformFactory.newPlatform(manifest['_manifest_path'])
platforms.append({
"name": p.get_name(),
"title": p.get_title(),
"description": p.get_description(),
"version": p.get_version(),
"packages": p.get_installed_packages().keys()
})
if json_output:
click.echo(json.dumps(data))
click.echo(json.dumps(platforms))
else:
for item in data:
click.echo("{name:<20} with packages: {pkgs}".format(
name=click.style(item['name'], fg="cyan"),
pkgs=", ".join(item['packages'])
))
_print_platforms(platforms)
@cli.command("search", short_help="Search for development platforms")
@click.argument("query", required=False)
@click.option("--json-output", is_flag=True)
def platforms_search(query, json_output):
data = []
platforms = PlatformFactory.get_platforms().keys()
platforms.sort()
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
type_ = p.get_type()
description = p.get_description()
if query == "all":
query = ""
search_data = "%s %s %s" % (type_, description, p.get_packages())
if query and query.lower() not in search_data.lower():
continue
data.append({
"type": type_,
"description": description,
"packages": p.get_packages()
})
if json_output:
click.echo(json.dumps(data))
else:
terminal_width, _ = click.get_terminal_size()
for item in data:
click.secho(item['type'], fg="cyan", nl=False)
click.echo(" (available packages: %s)" % ", ".join(
item.get("packages").keys()))
click.echo("-" * terminal_width)
click.echo(item['description'])
click.echo()
@cli.command("show", short_help="Show details about installed platform")
@cli.command("show", short_help="Show details about installed Platform")
@click.argument("platform")
@click.pass_context
def platforms_show(ctx, platform):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if platform not in installed_platforms:
def platform_show(ctx, platform):
try:
p = PlatformFactory.newPlatform(platform)
except exception.UnknownPlatform:
if (not app.get_setting("enable_prompts") or
click.confirm("The platform '%s' has not been installed yet. "
"Would you like to install it now?" % platform)):
ctx.invoke(platforms_install, platforms=[platform])
ctx.invoke(platform_install, platforms=[platform])
else:
raise PlatformNotInstalledYet(platform)
raise exception.PlatformNotInstalledYet(platform)
p = PlatformFactory.newPlatform(platform)
click.echo("{name:<20} - {description} [ {url} ]".format(
name=click.style(p.get_type(), fg="cyan"),
description=p.get_description(), url=p.get_vendor_url()))
click.echo("{name} ~ {title}".format(
name=click.style(p.get_name(), fg="cyan"), title=p.get_title()))
click.echo("=" * (3 + len(p.get_name() + p.get_title())))
click.echo(p.get_manifest().get("description"))
click.echo()
click.echo("Version: %s" % p.get_version())
if "homepage" in p.get_manifest():
click.echo("Home: %s" % p.get_manifest().get("homepage"))
if "license" in p.get_manifest():
click.echo("License: %s" % p.get_manifest().get("license").get("type"))
if "frameworks" in p.get_manifest():
click.echo("Frameworks: %s" %
", ".join(p.get_manifest().get("frameworks").keys()))
installed_packages = PackageManager.get_installed()
for name in p.get_installed_packages():
data = installed_packages[name]
pkgalias = p.get_package_alias(name)
click.echo("----------")
click.echo("Package: %s" % click.style(name, fg="yellow"))
if pkgalias:
click.echo("Alias: %s" % pkgalias)
click.echo("Version: %d" % int(data['version']))
click.echo("Installed: %s" % datetime.fromtimestamp(
data['time']).strftime("%Y-%m-%d %H:%M:%S"))
if not p.get_packages():
return
installed_pkgs = p.get_installed_packages()
for name, opts in p.get_packages().items():
click.echo()
click.echo("Package %s" % click.style(name, fg="yellow"))
click.echo("-" * (8 + len(name)))
if p.get_package_type(name):
click.echo("Type: %s" % p.get_package_type(name))
click.echo("Requirements: %s" % opts.get("version"))
click.echo("Installed: %s" % (
"Yes" if name in installed_pkgs else "No (optional)"))
if name in installed_pkgs:
for key, value in installed_pkgs[name].items():
if key in ("url", "version", "description"):
click.echo("%s: %s" % (key.title(), value))
@cli.command("uninstall", short_help="Uninstall platforms")
@click.argument("platforms", nargs=-1, required=True)
def platforms_uninstall(platforms):
def platform_uninstall(platforms):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.uninstall():
_platform = platform
_version = None
if "@" in platform:
_platform, _version = platform.rsplit("@", 1)
if PlatformManager().uninstall(_platform, _version):
click.secho("The platform '%s' has been successfully "
"uninstalled!" % platform, fg="green")
@cli.command("update", short_help="Update installed Platforms and Packages")
def platforms_update():
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
for platform in installed_platforms:
click.echo("\nPlatform %s" % click.style(platform, fg="cyan"))
@cli.command("update", short_help="Update installed Platforms")
@click.option("--only-packages", is_flag=True)
def platform_update(only_packages):
for manifest in PlatformManager().get_installed():
click.echo("Platform %s @ %s" % (
click.style(manifest['name'], fg="cyan"), manifest['version']))
click.echo("--------")
p = PlatformFactory.newPlatform(platform)
p.update()
if only_packages:
status = PlatformFactory.newPlatform(
manifest['name'], manifest['version']).update_packages()
if status is None:
click.secho("Packages are up-to-date", fg="green")
else:
PlatformManager().update(manifest['name'], manifest['version'])
click.echo()

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -24,7 +24,7 @@ import click
from platformio import app, exception, telemetry, util
from platformio.commands.lib import lib_install as cmd_lib_install
from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory
from platformio.managers.platform import PlatformFactory
@click.command("run", short_help="Process project environments")

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -15,14 +15,13 @@
import click
from platformio.commands.lib import lib_update as cmd_lib_update
from platformio.commands.platforms import \
platforms_update as cmd_platforms_update
from platformio.commands.platform import platform_update as cmd_platform_update
@click.command("update",
short_help="Update installed Platforms, Packages and Libraries")
@click.pass_context
def cli(ctx):
ctx.invoke(cmd_platforms_update)
ctx.invoke(cmd_platform_update)
click.echo()
ctx.invoke(cmd_lib_update)

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -57,7 +57,7 @@ class BoardNotDefined(PlatformioException):
class UnknownBoard(PlatformioException):
MESSAGE = "Unknown board type '{0}'"
MESSAGE = "Unknown board ID '{0}'"
class UnknownFramework(PlatformioException):
@ -70,9 +70,16 @@ class UnknownPackage(PlatformioException):
MESSAGE = "Detected unknown package '{0}'"
class InvalidPackageVersion(PlatformioException):
class UndefinedPackageVersion(PlatformioException):
MESSAGE = "The package '{0}' with version '{1:d}' does not exist"
MESSAGE = "Can not find package '{0}' with version requirements '{1}'"\
" for your system '{2}'"
class PackageInstallError(PlatformioException):
MESSAGE = "Can not install package '{0}' with version requirements '{1}' "\
"for your system '{2}'"
class NonSystemPackage(PlatformioException):

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -14,23 +14,19 @@
import re
import struct
from os import getenv, remove
from os.path import isdir, isfile, join
from shutil import rmtree
from os import getenv
from time import time
import click
from platformio import __version__, app, exception, telemetry, util
from platformio.commands.lib import lib_update as cmd_libraries_update
from platformio.commands.platforms import \
platforms_install as cmd_platforms_install
from platformio.commands.platforms import \
platforms_update as cmd_platforms_update
from platformio.commands.platform import \
platform_install as cmd_platform_install
from platformio.commands.platform import platform_update as cmd_platform_update
from platformio.commands.upgrade import get_latest_version
from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory
from platformio.util import get_home_dir
from platformio.managers.platform import PlatformManager
def in_silence(ctx):
@ -72,10 +68,9 @@ class Upgrader(object):
self.from_version = self.version_to_int(from_version)
self.to_version = self.version_to_int(to_version)
self._upgraders = (
(self.version_to_int("0.9.0"), self._upgrade_to_0_9_0),
(self.version_to_int("1.0.0"), self._upgrade_to_1_0_0)
)
self._upgraders = [
(self.version_to_int("3.0.0"), self._upgrade_to_3_0_0)
]
@staticmethod
def version_to_int(version):
@ -91,38 +86,16 @@ class Upgrader(object):
result = [True]
for item in self._upgraders:
if self.from_version >= item[0]:
if self.from_version >= item[0] or self.to_version < item[0]:
continue
result.append(item[1](ctx))
return all(result)
def _upgrade_to_0_9_0(self, ctx): # pylint: disable=R0201
prev_platforms = []
# remove platform's folder (obsolete package structure)
for name in PlatformFactory.get_platforms().keys():
pdir = join(get_home_dir(), name)
if not isdir(pdir):
continue
prev_platforms.append(name)
rmtree(pdir)
# remove unused files
for fname in (".pioupgrade", "installed.json"):
if isfile(join(get_home_dir(), fname)):
remove(join(get_home_dir(), fname))
if prev_platforms:
ctx.invoke(cmd_platforms_install, platforms=prev_platforms)
return True
def _upgrade_to_1_0_0(self, ctx): # pylint: disable=R0201
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
def _upgrade_to_3_0_0(self, ctx): # pylint: disable=R0201
installed_platforms = app.get_state_item("installed_platforms", [])
if installed_platforms:
ctx.invoke(cmd_platforms_install, platforms=installed_platforms)
ctx.invoke(cmd_platform_install, platforms=installed_platforms)
return True
@ -131,10 +104,28 @@ def after_upgrade(ctx):
if last_version == __version__:
return
terminal_width, _ = click.get_terminal_size()
if last_version == "0.0.0":
app.set_state_item("last_version", __version__)
else:
click.secho("Please wait while upgrading PlatformIO ...",
fg="yellow")
# promotion
click.echo("")
u = Upgrader(last_version, __version__)
if u.run(ctx):
app.set_state_item("last_version", __version__)
ctx.invoke(cmd_platform_update, only_packages=True)
click.secho("PlatformIO has been successfully upgraded to %s!\n" %
__version__, fg="green")
telemetry.on_event(category="Auto", action="Upgrade",
label="%s > %s" % (last_version, __version__))
else:
raise exception.UpgradeError("Auto upgrading...")
click.echo("")
# PlatformIO banner
terminal_width, _ = click.get_terminal_size()
click.echo("*" * terminal_width)
click.echo("If you like %s, please:" % (
click.style("PlatformIO", fg="cyan")
@ -163,27 +154,6 @@ def after_upgrade(ctx):
click.echo("*" * terminal_width)
click.echo("")
if last_version == "0.0.0":
app.set_state_item("last_version", __version__)
return
click.secho("Please wait while upgrading PlatformIO ...",
fg="yellow")
u = Upgrader(last_version, __version__)
if u.run(ctx):
app.set_state_item("last_version", __version__)
ctx.invoke(cmd_platforms_update)
click.secho("PlatformIO has been successfully upgraded to %s!\n" %
__version__, fg="green")
telemetry.on_event(category="Auto", action="Upgrade",
label="%s > %s" % (last_version, __version__))
else:
raise exception.UpgradeError("Auto upgrading...")
click.echo("")
def check_platformio_upgrade():
last_check = app.get_state_item("last_check", {})
@ -234,10 +204,11 @@ def check_internal_updates(ctx, what):
outdated_items = []
if what == "platforms":
for platform in PlatformFactory.get_platforms(installed=True).keys():
p = PlatformFactory.newPlatform(platform)
if p.is_outdated():
outdated_items.append(platform)
pm = PlatformManager()
for manifest in pm.get_installed():
if pm.is_outdated(manifest['name'], manifest['version']):
outdated_items.append(
"%s@%s" % (manifest['name'], manifest['version']))
elif what == "libraries":
lm = LibraryManager()
outdated_items = lm.get_outdated()
@ -255,13 +226,13 @@ def check_internal_updates(ctx, what):
if not app.get_setting("auto_update_" + what):
click.secho("Please update them via ", fg="yellow", nl=False)
click.secho("`platformio %s update`" %
("lib" if what == "libraries" else "platforms"),
("lib" if what == "libraries" else "platform"),
fg="cyan", nl=False)
click.secho(" command.", fg="yellow")
else:
click.secho("Please wait while updating %s ..." % what, fg="yellow")
if what == "platforms":
ctx.invoke(cmd_platforms_update)
ctx.invoke(cmd_platform_update)
elif what == "libraries":
ctx.invoke(cmd_libraries_update)
click.echo()

View File

@ -0,0 +1,13 @@
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# 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.

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -12,38 +12,41 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from os import makedirs, remove
from os.path import basename, isdir, isfile, join
import os
from os.path import dirname, isdir, isfile, join
from shutil import rmtree
from time import time
import click
import requests
import semantic_version
from platformio import exception, telemetry, util
from platformio.app import get_state_item, set_state_item
from platformio.downloader import FileDownloader
from platformio.unpacker import FileUnpacker
class PackageManager(object):
def __init__(self):
self._package_dir = join(util.get_home_dir(), "packages")
if not isdir(self._package_dir):
makedirs(self._package_dir)
assert isdir(self._package_dir)
_INSTALLED_CACHE = {}
@classmethod
@util.memoized
def get_manifest(cls):
return util.get_api_result("/packages/manifest")
def __init__(self, package_dir=None, repositories=None):
self._INSTALLED_CACHE = {}
self.repositories = repositories
self.package_dir = package_dir or join(util.get_home_dir(), "packages")
if not isdir(self.package_dir):
os.makedirs(self.package_dir)
assert isdir(self.package_dir)
@staticmethod
def reset_cache():
PackageManager._INSTALLED_CACHE = {}
@staticmethod
def download(url, dest_dir, sha1=None):
fd = FileDownloader(url, dest_dir)
fd.start()
fd.verify(sha1)
if sha1:
fd.verify(sha1)
return fd.get_filepath()
@staticmethod
@ -52,98 +55,180 @@ class PackageManager(object):
return fu.start()
@staticmethod
def get_installed():
return get_state_item("installed_packages", {})
def get_manifest_name():
return "package.json"
def get_outdated(self):
outdated = []
for name, data in self.get_installed().items():
if data['version'] != self.get_info(name)['version']:
outdated.append(name)
return outdated
def is_installed(self, name):
return name in self.get_installed()
def get_info(self, name, version=None):
manifest = self.get_manifest()
if name not in manifest:
raise exception.UnknownPackage(name)
# check system platform
@staticmethod
def max_satisfying_version(versions, requirements=None):
item = None
systype = util.get_systype()
builds = ([b for b in manifest[name] if b['system'] == "all" or systype
in b['system']])
if not builds:
raise exception.NonSystemPackage(name, systype)
if requirements is not None:
requirements = str(requirements)
for v in versions:
if isinstance(v['version'], int):
continue
if v['system'] not in ("all", "*") and systype not in v['system']:
continue
if requirements and not semantic_version.match(
requirements, v['version']):
continue
if item is None or semantic_version.compare(
v['version'], item['version']) == 1:
item = v
return item
if version:
for b in builds:
if b['version'] == version:
return b
raise exception.InvalidPackageVersion(name, version)
else:
return sorted(builds, key=lambda s: s['version'])[-1]
def get_installed(self):
if self.package_dir in PackageManager._INSTALLED_CACHE:
return PackageManager._INSTALLED_CACHE[self.package_dir]
items = []
for p in sorted(os.listdir(self.package_dir)):
manifest_path = join(self.package_dir, p, self.get_manifest_name())
if not isfile(manifest_path):
continue
manifest = util.load_json(manifest_path)
manifest['_manifest_path'] = manifest_path
assert set(["name", "version"]) <= set(manifest.keys())
items.append(manifest)
PackageManager._INSTALLED_CACHE[self.package_dir] = items
return items
def install(self, name):
click.echo("Installing %s package:" % click.style(name, fg="cyan"))
def is_installed(self, name, requirements=None):
installed = self.get_installed()
if requirements is None:
return any([p['name'] == name for p in installed])
if self.is_installed(name):
click.secho("Already installed", fg="yellow")
return False
for p in installed:
if p['name'] != name:
continue
elif semantic_version.match(requirements, p['version']):
return True
return None
info = self.get_info(name)
pkg_dir = join(self._package_dir, name)
if not isdir(pkg_dir):
makedirs(pkg_dir)
def get_latest_version(self, name, requirements):
for versions in PackageRepoIterator(name, self.repositories):
pkgdata = self.max_satisfying_version(versions, requirements)
if pkgdata:
return pkgdata['version']
return None
dlpath = None
try:
dlpath = self.download(info['url'], pkg_dir, info['sha1'])
except (requests.exceptions.ConnectionError,
requests.exceptions.ChunkedEncodingError,
requests.exceptions.SSLError,
exception.FDUnrecognizedStatusCode, StopIteration):
if not info['url'].startswith("http://dl.platformio.org"):
def install(self, name, requirements, silent=False, trigger_event=True):
installed = self.is_installed(name, requirements)
if not installed or not silent:
click.echo("Installing package %s @ %s:" % (
click.style(name, fg="cyan"),
requirements if requirements else "latest"))
if installed:
if not silent:
click.secho("Already installed", fg="yellow")
return
if not self._install_from_piorepo(name, requirements):
raise exception.PackageInstallError(
name, requirements, util.get_systype())
self.reset_cache()
if trigger_event:
telemetry.on_event(
category="PackageManager", action="Install", label=name)
def _install_from_piorepo(self, name, requirements):
pkg_dir = None
success = False
pkgdata = None
versions = None
for versions in PackageRepoIterator(name, self.repositories):
dlpath = None
pkgdata = self.max_satisfying_version(versions, requirements)
if not pkgdata:
continue
pkg_dir = join(self.package_dir, name)
if isfile(join(pkg_dir, self.get_manifest_name())):
pkg_dir = join(
self.package_dir, "%s@%s" % (name, pkgdata['version']))
# remove previous/not-satisfied package
if isdir(pkg_dir):
rmtree(pkg_dir)
os.makedirs(pkg_dir)
try:
dlpath = self.download(
"http://dl.platformio.org/packages/%s" %
basename(info['url']), pkg_dir, info['sha1'])
pkgdata['url'], pkg_dir, pkgdata.get("sha1"))
assert isfile(dlpath)
self.unpack(dlpath, pkg_dir)
success = True
break
except Exception as e: # pylint: disable=broad-except
click.secho("Warning! Package Mirror: %s" % e, fg="yellow")
click.secho("Looking for other Package Mirror...", fg="yellow")
finally:
if dlpath and isfile(dlpath):
os.remove(dlpath)
assert isfile(dlpath)
if versions is None:
raise exception.UnknownPackage(name)
elif not pkgdata:
raise exception.UndefinedPackageVersion(
name, requirements, util.get_systype())
if self.unpack(dlpath, pkg_dir):
self._register(name, info['version'])
# remove archive
remove(dlpath)
return success
telemetry.on_event(
category="PackageManager", action="Install", label=name)
def uninstall(self, name, requirements=None, trigger_event=True):
click.echo("Uninstalling package %s @ %s: \t" % (
click.style(name, fg="cyan"),
requirements if requirements else "latest"), nl=False)
found = False
for manifest in self.get_installed():
if manifest['name'] != name:
continue
if (requirements and not semantic_version.match(
requirements, manifest['version'])):
continue
found = True
if isfile(manifest['_manifest_path']):
rmtree(dirname(manifest['_manifest_path']))
def uninstall(self, name):
click.echo("Uninstalling %s package: \t" %
click.style(name, fg="cyan"), nl=False)
if not self.is_installed(name):
if not found:
click.secho("Not installed", fg="yellow")
return False
else:
click.echo("[%s]" % click.style("OK", fg="green"))
if isdir(join(self._package_dir, name)):
rmtree(join(self._package_dir, name))
self._unregister(name)
click.echo("[%s]" % click.style("OK", fg="green"))
self.reset_cache()
if trigger_event:
telemetry.on_event(
category="PackageManager", action="Uninstall", label=name)
# report usage
telemetry.on_event(
category="PackageManager", action="Uninstall", label=name)
def update(self, name, requirements=None, keep_versions=None):
click.echo("Updating package %s @ %s:" % (
click.style(name, fg="yellow"),
requirements if requirements else "latest"))
def update(self, name):
click.echo("Updating %s package:" % click.style(name, fg="yellow"))
latest_version = self.get_latest_version(name, requirements)
if latest_version is None:
click.secho("Ignored! '%s' is not listed in "
"Package Repository" % name, fg="yellow")
return
installed = self.get_installed()
current_version = installed[name]['version']
latest_version = self.get_info(name)['version']
current = None
other_versions = []
for manifest in self.get_installed():
if manifest['name'] != name:
continue
other_versions.append(manifest['version'])
if (requirements and not semantic_version.match(
requirements, manifest['version'])):
continue
if (not current or semantic_version.compare(
manifest['version'], current['version']) == 1):
current = manifest
click.echo("Versions: Current=%d, Latest=%d \t " %
if current is None:
return
current_version = current['version']
click.echo("Versions: Current=%s, Latest=%s \t " %
(current_version, latest_version), nl=False)
if current_version == latest_version:
@ -152,21 +237,52 @@ class PackageManager(object):
else:
click.echo("[%s]" % (click.style("Out-of-date", fg="red")))
self.uninstall(name)
self.install(name)
for v in other_versions:
if not keep_versions or v not in keep_versions:
self.uninstall(name, v, trigger_event=False)
self.install(name, latest_version, trigger_event=False)
telemetry.on_event(
category="PackageManager", action="Update", label=name)
return True
def _register(self, name, version):
data = self.get_installed()
data[name] = {
"version": version,
"time": int(time())
}
set_state_item("installed_packages", data)
def _unregister(self, name):
data = self.get_installed()
del data[name]
set_state_item("installed_packages", data)
class PackageRepoIterator(object):
_MANIFEST_CACHE = {}
def __init__(self, package, repositories):
assert isinstance(repositories, list)
self.package = package
self.repositories = iter(repositories)
def __iter__(self):
return self
def __next__(self):
return self.next()
def next(self):
manifest = {}
repo = next(self.repositories)
if isinstance(repo, dict):
manifest = repo
elif repo in PackageRepoIterator._MANIFEST_CACHE:
manifest = PackageRepoIterator._MANIFEST_CACHE[repo]
else:
r = None
try:
r = requests.get(repo, headers=util.get_request_defheaders())
r.raise_for_status()
manifest = r.json()
except: # pylint: disable=bare-except
pass
finally:
if r:
r.close()
PackageRepoIterator._MANIFEST_CACHE[repo] = manifest
if self.package in manifest:
return manifest[self.package]
else:
return self.next()

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -18,251 +18,234 @@ import re
import sys
from imp import load_source
from multiprocessing import cpu_count
from os.path import isdir, isfile, join
from os.path import basename, dirname, isdir, isfile, join
import click
import semantic_version
from platformio import app, exception, util
from platformio.app import get_state_item, set_state_item
from platformio.pkgmanager import PackageManager
PLATFORM_PACKAGES = {
"framework-arduinoavr": [
("Arduino Wiring-based Framework (AVR Core, 1.6)",
"http://arduino.cc/en/Reference/HomePage")
],
"framework-arduinosam": [
("Arduino Wiring-based Framework (SAM Core, 1.6)",
"http://arduino.cc/en/Reference/HomePage")
],
"framework-arduinoteensy": [
("Arduino Wiring-based Framework",
"http://arduino.cc/en/Reference/HomePage")
],
"framework-arduinomsp430": [
("Arduino Wiring-based Framework (MSP430 Core)",
"http://arduino.cc/en/Reference/HomePage")
],
"framework-arduinoespressif": [
("Arduino Wiring-based Framework (ESP8266 Core)",
"https://github.com/esp8266/Arduino")
],
"framework-arduinomicrochippic32": [
("Arduino Wiring-based Framework (PIC32 Core)",
"https://github.com/chipKIT32/chipKIT-core")
],
"framework-arduinointel": [
("Arduino Wiring-based Framework (Intel ARC Core)",
"https://github.com/01org/corelibs-arduino101")
],
"framework-arduinonordicnrf51": [
("Arduino Wiring-based Framework (RFduino Core)",
"https://github.com/RFduino/RFduino")
],
"framework-energiamsp430": [
("Energia Wiring-based Framework (MSP430 Core)",
"http://energia.nu/reference/")
],
"framework-energiativa": [
("Energia Wiring-based Framework (LM4F Core)",
"http://energia.nu/reference/")
],
"framework-cmsis": [
("Vendor-independent hardware abstraction layer for the Cortex-M "
"processor series",
"http://www.arm.com/products/processors/"
"cortex-m/cortex-microcontroller-software-interface-standard.php")
],
"framework-spl": [
("Standard Peripheral Library for STM32 MCUs",
"http://www.st.com"
"/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257890")
],
"framework-libopencm3": [
("libOpenCM3 Framework", "http://www.libopencm3.org/")
],
"framework-mbed": [
("mbed Framework", "http://mbed.org")
],
"framework-wiringpi": [
("GPIO Interface library for the Raspberry Pi", "http://wiringpi.com")
],
"framework-simba": [
("Simba Framework", "https://github.com/eerimoq/simba")
],
"sdk-esp8266": [
("ESP8266 SDK", "http://bbs.espressif.com")
],
"ldscripts": [
("Linker Scripts",
"https://sourceware.org/binutils/docs/ld/Scripts.html")
],
"toolchain-atmelavr": [
("avr-gcc", "https://gcc.gnu.org/wiki/avr-gcc"),
("GDB", "http://www.gnu.org/software/gdb/"),
("AVaRICE", "http://avarice.sourceforge.net/"),
("SimulAVR", "http://www.nongnu.org/simulavr/")
],
"toolchain-gccarmnoneeabi": [
("gcc-arm-embedded", "https://launchpad.net/gcc-arm-embedded"),
("GDB", "http://www.gnu.org/software/gdb/")
],
"toolchain-gccarmlinuxgnueabi": [
("GCC for Linux ARM GNU EABI", "https://gcc.gnu.org"),
("GDB", "http://www.gnu.org/software/gdb/")
],
"toolchain-gccmingw32": [
("MinGW", "http://www.mingw.org")
],
"toolchain-gcclinux32": [
("GCC for Linux i686", "https://gcc.gnu.org")
],
"toolchain-gcclinux64": [
("GCC for Linux x86_64", "https://gcc.gnu.org")
],
"toolchain-xtensa": [
("xtensa-gcc", "https://github.com/jcmvbkbc/gcc-xtensa"),
("GDB", "http://www.gnu.org/software/gdb/")
],
"toolchain-timsp430": [
("msp-gcc", "http://sourceforge.net/projects/mspgcc/"),
("GDB", "http://www.gnu.org/software/gdb/")
],
"toolchain-icestorm": [
("GCC for FPGA IceStorm", "http://www.clifford.at/icestorm/")
],
"toolchain-microchippic32": [
("GCC for Microchip PIC32", "https://github.com/chipKIT32/chipKIT-cxx")
],
"toolchain-intelarc32": [
("GCC for Intel ARC",
"https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain")
],
"tool-scons": [
("SCons software construction tool", "http://www.scons.org")
],
"tool-avrdude": [
("AVRDUDE", "http://www.nongnu.org/avrdude/")
],
"tool-micronucleus": [
("Micronucleus", "https://github.com/micronucleus/micronucleus")
],
"tool-bossac": [
("BOSSA CLI", "https://sourceforge.net/projects/b-o-s-s-a/")
],
"tool-openocd": [
("OpenOCD", "http://openocd.org")
],
"tool-stlink": [
("ST-Link", "https://github.com/texane/stlink")
],
"tool-teensy": [
("Teensy Loader", "https://www.pjrc.com/teensy/loader.html")
],
"tool-lm4flash": [
("Flash Programmer", "http://www.ti.com/tool/lmflashprogrammer")
],
"tool-mspdebug": [
("MSPDebug", "http://mspdebug.sourceforge.net/")
],
"tool-esptool": [
("esptool-ck", "https://github.com/igrr/esptool-ck")
],
"tool-rfdloader": [
("rfdloader", "https://github.com/RFduino/RFduino")
],
"tool-mkspiffs": [
("Tool to build and unpack SPIFFS images",
"https://github.com/igrr/mkspiffs")
],
"tool-pic32prog": [
("pic32prog", "https://github.com/sergev/pic32prog")
],
"tool-arduino101load": [
("Genuino101 uploader", "https://github.com/01org/intel-arduino-tools")
]
}
from platformio import exception, util
from platformio.managers.package import PackageManager
def get_packages():
return PLATFORM_PACKAGES
class PlatformManager(PackageManager):
def __init__(self):
PackageManager.__init__(
self,
join(util.get_home_dir(), "platforms"),
["http://dl.platformio.org/misc/platforms_manifest.json"]
)
@staticmethod
def get_manifest_name():
return "platform.json"
def find_best_platform(self, name, requirements=None):
best = None
for manifest in self.get_installed():
if manifest['name'] != name:
continue
elif requirements and not semantic_version.match(
requirements, manifest['version']):
continue
elif (not best or semantic_version.compare(
manifest['version'], best['version']) == 1):
best = manifest
return best
def install(self, # pylint: disable=too-many-arguments,arguments-differ
name, requirements=None, with_packages=None,
without_packages=None, skip_default_packages=False):
PackageManager.install(self, name, requirements)
return PlatformFactory.newPlatform(
name, requirements).install_packages(
with_packages, without_packages, skip_default_packages)
def uninstall(self, # pylint: disable=arguments-differ
name, requirements=None):
if PlatformFactory.newPlatform(
name, requirements).uninstall_packages():
return PackageManager.uninstall(self, name, requirements)
return False
def update(self, name, version):
raise NotImplementedError()
def is_outdated(self, name, version):
raise NotImplementedError()
def get_installed_boards(self):
boards = []
for manifest in self.get_installed():
p = PlatformFactory.newPlatform(manifest['_manifest_path'])
for id_, config in p.get_boards().items():
manifest = config.get_manifest().copy()
manifest['id'] = id_
manifest['platform'] = p.get_name()
boards.append(manifest)
return boards
@staticmethod
@util.memoized
def get_registered_boards():
boards = util.get_api_result("/boards")
for item in boards:
# @TODO remove type from API
item['id'] = item['type']
del item['type']
return boards
class PlatformFactory(object):
@staticmethod
def get_clsname(type_):
return "%s%sPlatform" % (type_.upper()[0], type_.lower()[1:])
def get_clsname(name):
return "%s%sPlatform" % (name.upper()[0], name.lower()[1:])
@staticmethod
def load_module(type_, path):
def load_module(name, path):
module = None
try:
module = load_source(
"platformio.platforms.%s" % type_, path)
"platformio.managers.platform.%s" % name, path)
except ImportError:
raise exception.UnknownPlatform(type_)
raise exception.UnknownPlatform(name)
return module
@classmethod
@util.memoized
def _lookup_platforms(cls):
platforms = {}
for d in (util.get_home_dir(), util.get_source_dir()):
pdir = join(d, "platforms")
if not isdir(pdir):
continue
for p in sorted(os.listdir(pdir)):
if (p in ("__init__.py", "base.py") or not
p.endswith(".py")):
continue
type_ = p[:-3]
path = join(pdir, p)
try:
isplatform = hasattr(
cls.load_module(type_, path),
cls.get_clsname(type_)
)
if isplatform:
platforms[type_] = path
except exception.UnknownPlatform:
pass
return platforms
def newPlatform(cls, name, requirements=None):
platform_dir = None
if name.endswith("platform.json") and isfile(name):
platform_dir = dirname(name)
name = util.load_json(name)['name']
else:
_manifest = PlatformManager().find_best_platform(
name, requirements)
if _manifest:
platform_dir = dirname(_manifest['_manifest_path'])
if not platform_dir:
raise exception.UnknownPlatform(
name if not requirements else "%s@%s" % (name, requirements))
@classmethod
def get_platforms(cls, installed=False):
platforms = cls._lookup_platforms()
platform_cls = None
if isfile(join(platform_dir, "platform.py")):
platform_cls = getattr(
cls.load_module(name, join(platform_dir, "platform.py")),
cls.get_clsname(name)
)
else:
platform_cls = type(
str(cls.get_clsname(name)), (BasePlatform,), {})
if not installed:
return platforms
installed_platforms = {}
for type_ in get_state_item("installed_platforms", []):
if type_ in platforms:
installed_platforms[type_] = platforms[type_]
return installed_platforms
@classmethod
def newPlatform(cls, type_):
platforms = cls.get_platforms()
if type_ not in platforms:
raise exception.UnknownPlatform(type_)
_instance = getattr(
cls.load_module(type_, platforms[type_]),
cls.get_clsname(type_)
)()
_instance = platform_cls(join(platform_dir, "platform.json"))
assert isinstance(_instance, BasePlatform)
return _instance
class BasePlatform(object):
class PlatformPackagesMixin(object):
def get_installed_packages(self):
items = {}
installed = self.pm.get_installed()
for name, opts in self.get_packages().items():
manifest = None
for p in installed:
if (p['name'] != name or not semantic_version.match(
opts['version'], p['version'])):
continue
elif (not manifest or semantic_version.compare(
p['version'], manifest['version']) == 1):
manifest = p
if manifest:
items[name] = manifest
return items
def install_packages(self, with_packages=None, without_packages=None,
skip_default_packages=False, silent=False):
with_packages = set(
self.pkg_types_to_names(with_packages or []))
without_packages = set(
self.pkg_types_to_names(without_packages or []))
upkgs = with_packages | without_packages
ppkgs = set(self.get_packages().keys())
if not upkgs.issubset(ppkgs):
raise exception.UnknownPackage(", ".join(upkgs - ppkgs))
for name, opts in self.get_packages().items():
if name in without_packages:
continue
elif (name in with_packages or
not (skip_default_packages or opts.get("optional", False))):
self.pm.install(name, opts.get("version"), silent=silent)
return True
def uninstall_packages(self):
deppkgs = set()
for manifest in PlatformManager().get_installed():
if manifest['name'] == self.get_name():
continue
p = PlatformFactory.newPlatform(
manifest['name'], manifest['version'])
for pkgname, pkgmanifest in p.get_installed_packages().items():
deppkgs.add((pkgname, pkgmanifest['version']))
for manifest in self.pm.get_installed():
if manifest['name'] not in self.get_packages().keys():
continue
if (manifest['name'], manifest['version']) not in deppkgs:
self.pm.uninstall(manifest['name'], manifest['version'])
return True
def update_packages(self):
outdated = None
for pkgname, pkgmanifest in self.get_installed_packages().items():
requirements = self.get_packages()[pkgname]['version']
latest_version = self.pm.get_latest_version(
pkgname, requirements)
if (not latest_version or
pkgmanifest['version'] == latest_version):
continue
# check other platforms
keep_versions = set([latest_version])
for pfmanifest in PlatformManager().get_installed():
if pfmanifest['name'] == self.get_name():
continue
p = PlatformFactory.newPlatform(
pfmanifest['name'], pfmanifest['version'])
if pkgname not in p.get_packages():
continue
keep_versions.add(p.pm.get_latest_version(
pkgname, p.get_packages()[pkgname]['version']))
outdated = self.pm.update(
pkgname, requirements, keep_versions)
return outdated
def are_outdated_packages(self):
for name, opts in self.get_installed_packages().items():
if (opts['version'] != self.pm.get_latest_version(
name, self.get_packages()[name].get("version"))):
return True
return False
class BasePlatform(PlatformPackagesMixin):
_BOARDS_CACHE = {}
PACKAGES = {}
LINE_ERROR_RE = re.compile(r"(\s+error|error[:\s]+)", re.I)
def __init__(self):
def __init__(self, manifest_path):
self._BOARDS_CACHE = {}
self.manifest_path = manifest_path
self.manifest = util.load_json(manifest_path)
self.pm = PackageManager(
repositories=self.manifest.get("packageRepositories"))
self._found_error = False
self._last_echo_line = None
@ -271,182 +254,125 @@ class BasePlatform(object):
# 3 = 2 + others
self._verbose_level = 3
def get_type(self):
return self.__class__.__name__[:-8].lower()
def get_name(self):
return self.get_type().title()
return self.manifest['name']
def get_build_script(self):
builtin = join(util.get_source_dir(), "builder", "scripts", "%s.py" %
self.get_type())
if isfile(builtin):
return builtin
raise NotImplementedError()
def get_title(self):
return self.manifest['title']
def get_description(self):
if self.__doc__:
doclines = [l.strip() for l in self.__doc__.splitlines() if
l.strip()]
return " ".join(doclines[:-1]).strip()
else:
raise NotImplementedError()
return self.manifest['description']
def get_vendor_url(self):
if self.__doc__ and "http" in self.__doc__:
return self.__doc__[self.__doc__.index("http"):].strip()
else:
raise NotImplementedError()
def get_version(self):
return self.manifest['version']
def get_manifest(self):
return self.manifest
def get_dir(self):
return dirname(self.manifest_path)
def get_build_script(self):
main_script = join(self.get_dir(), "builder", "main.py")
if isfile(main_script):
return main_script
raise NotImplementedError()
def is_embedded(self):
for name, opts in self.get_packages().items():
if name == "framework-mbed" or opts.get("alias") == "uploader":
for opts in self.get_packages().values():
if opts.get("type") == "uploader":
return True
return False
def get_boards(self, id_=None):
if id_ is None:
boards_dir = join(self.get_dir(), "boards")
if not isdir(boards_dir):
return {}
for item in sorted(os.listdir(boards_dir)):
_id = item[:-5]
if _id in self._BOARDS_CACHE:
continue
self._BOARDS_CACHE[_id] = PlatformBoardConfig(
join(self.get_dir(), "boards", item)
)
else:
if id_ not in self._BOARDS_CACHE:
self._BOARDS_CACHE[id_] = PlatformBoardConfig(
join(self.get_dir(), "boards", "%s.json" % id_)
)
return self._BOARDS_CACHE[id_] if id_ else self._BOARDS_CACHE
def board_config(self, id_):
return self.get_boards(id_)
def get_packages(self):
return self.PACKAGES
return self.manifest.get("packages", {})
def get_package_alias(self, pkgname):
return self.PACKAGES[pkgname].get("alias")
def get_frameworks(self):
return self.get_manifest().get("frameworks")
def pkg_aliases_to_names(self, aliases):
def get_package_dir(self, name):
packages = self.get_installed_packages()
if name not in packages:
return None
return dirname(packages[name]['_manifest_path'])
def get_package_version(self, name):
packages = self.get_installed_packages()
if name not in packages:
return None
return packages[name]['version']
def get_package_type(self, name):
return self.get_packages()[name].get("type")
def pkg_types_to_names(self, types):
names = []
for alias in aliases:
name = alias
# lookup by package aliases
for type_ in types:
name = type_
# lookup by package types
for _name, _opts in self.get_packages().items():
if _opts.get("alias") == alias:
if _opts.get("type") == type_:
name = None
names.append(_name)
# if alias is the right name
# if type is the right name
if name:
names.append(name)
return names
def get_default_packages(self):
return [k for k, v in self.get_packages().items()
if v.get("default", False)]
def get_installed_packages(self):
pm = PackageManager()
return [n for n in self.get_packages().keys() if pm.is_installed(n)]
def install(self, with_packages=None, without_packages=None,
skip_default_packages=False):
with_packages = set(
self.pkg_aliases_to_names(with_packages or []))
without_packages = set(
self.pkg_aliases_to_names(without_packages or []))
upkgs = with_packages | without_packages
ppkgs = set(self.get_packages().keys())
if not upkgs.issubset(ppkgs):
raise exception.UnknownPackage(", ".join(upkgs - ppkgs))
requirements = []
for name, opts in self.get_packages().items():
if name in without_packages:
continue
elif (name in with_packages or (not skip_default_packages and
opts.get("default"))):
requirements.append(name)
pm = PackageManager()
for name in requirements:
pm.install(name)
# register installed platform
data = get_state_item("installed_platforms", [])
if self.get_type() not in data:
data.append(self.get_type())
set_state_item("installed_platforms", data)
return len(requirements)
def uninstall(self):
platform = self.get_type()
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if platform not in installed_platforms:
raise exception.PlatformNotInstalledYet(platform)
deppkgs = set()
for item in installed_platforms:
if item == platform:
continue
p = PlatformFactory.newPlatform(item)
deppkgs = deppkgs.union(set(p.get_packages().keys()))
pm = PackageManager()
for name in self.get_packages().keys():
if not pm.is_installed(name) or name in deppkgs:
continue
pm.uninstall(name)
# unregister installed platform
installed_platforms.remove(platform)
set_state_item("installed_platforms", installed_platforms)
return True
def update(self):
pm = PackageManager()
for name in self.get_installed_packages():
pm.update(name)
def is_outdated(self):
pm = PackageManager()
obsolated = pm.get_outdated()
return not set(self.get_packages().keys()).isdisjoint(set(obsolated))
def configure_default_packages(self, variables, targets):
# enbale used frameworks
for pkg_name in self.pkg_aliases_to_names(["framework"]):
for framework in variables.get("framework", "").split(","):
framework = framework.lower().strip()
if not framework:
continue
if framework in pkg_name:
self.PACKAGES[pkg_name]['default'] = True
frameworks = self.get_frameworks()
for framework in variables.get("framework", "").split(","):
framework = framework.lower().strip()
if not framework or framework not in frameworks:
continue
_pkg_name = frameworks[framework]['package']
self.get_packages()[_pkg_name]['optional'] = False
# append SCons tool
self.PACKAGES['tool-scons'] = {"default": True}
self.get_packages()['tool-scons'] = {
"version": self.manifest.get("engines", {}).get(
"scons", ">=2.3.0,<2.5.0"),
"optional": False
}
# enable upload tools for upload targets
if any(["upload" in t for t in targets] + ["program" in targets]):
for _name, _opts in self.PACKAGES.iteritems():
if _opts.get("alias") == "uploader":
self.PACKAGES[_name]['default'] = True
for _name, _opts in self.get_packages().iteritems():
if _opts.get("type") == "uploader":
self.get_packages()[_name]['optional'] = False
elif "uploadlazy" in targets:
# skip all packages, allow only upload tools
self.PACKAGES[_name]['default'] = False
def _install_default_packages(self):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if (self.get_type() in installed_platforms and
set(self.get_default_packages()) <=
set(self.get_installed_packages())):
return True
if (not app.get_setting("enable_prompts") or
self.get_type() in installed_platforms or
click.confirm(
"The platform '%s' has not been installed yet. "
"Would you like to install it now?" % self.get_type())):
return self.install()
else:
raise exception.PlatformNotInstalledYet(self.get_type())
self.get_packages()[_name]['optional'] = True
def run(self, variables, targets, verbose):
assert isinstance(variables, dict)
assert isinstance(targets, list)
self.configure_default_packages(variables, targets)
self._install_default_packages()
self.install_packages(silent=True)
self._verbose_level = int(verbose)
@ -454,18 +380,13 @@ class BasePlatform(object):
targets.remove("clean")
targets.append("-c")
variables['platform_manifest'] = self.manifest_path
if "build_script" not in variables:
variables['build_script'] = self.get_build_script()
if not isfile(variables['build_script']):
raise exception.BuildScriptNotFound(variables['build_script'])
# append aliases of the installed packages
installed_packages = PackageManager.get_installed()
for name, options in self.get_packages().items():
if "alias" not in options or name not in installed_packages:
continue
variables['piopackage_%s' % options['alias']] = name
self._found_error = False
result = self._run_scons(variables, targets)
assert "returncode" in result
@ -542,3 +463,34 @@ class BasePlatform(object):
return cpu_count()
except NotImplementedError:
return 1
class PlatformBoardConfig(object):
def __init__(self, manifest_path):
if not isfile(manifest_path):
raise exception.UnknownBoard(basename(manifest_path[:-5]))
self.manifest_path = manifest_path
self.manifest = util.load_json(manifest_path)
def get(self, path, default=None):
try:
value = self.manifest
for k in path.split("."):
value = value[k]
return value
except KeyError:
if default is not None:
return default
else:
raise KeyError("Invalid board option '%s'" % path)
def __contains__(self, key):
try:
self.get(key)
return True
except KeyError:
return False
def get_manifest(self):
return self.manifest

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -375,32 +375,6 @@ def get_api_result(path, params=None, data=None, skipdns=False):
return result
@memoized
def _lookup_boards():
boards = {}
bdirs = [join(get_source_dir(), "boards")]
if isdir(join(get_home_dir(), "boards")):
bdirs.append(join(get_home_dir(), "boards"))
for bdir in bdirs:
for json_file in sorted(os.listdir(bdir)):
if not json_file.endswith(".json"):
continue
boards.update(load_json(join(bdir, json_file)))
return boards
def get_boards(type_=None):
boards = _lookup_boards()
if type_ is None:
return boards
else:
if type_ not in boards:
raise exception.UnknownBoard(type_)
return boards[type_]
@memoized
def _lookup_frameworks():
frameworks = {}

View File

@ -1,4 +1,4 @@
# Copyright 2014-2016 Ivan Kravets <me@ikravets.com>
# Copyright 2014-present Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ install_requires = [
"click>=3.2,<6",
"lockfile>=0.9.1,<0.13",
"requests>=2.4.0,<3",
"semantic_version>=2.5.0",
"colorama",
"pyserial<4"
]
@ -45,7 +46,6 @@ setup(
package_data={
"platformio": [
"projectconftpl.ini",
"boards/*.json",
"ide/tpls/*/.*.tpl",
"ide/tpls/*/*.tpl",
"ide/tpls/*/*/*.tpl",