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] [settings]
line_length=79 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 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 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -152,7 +152,7 @@ Examples
- sudo pip install -U platformio - sudo pip install -U platformio
# pre-install PlatformIO development platforms, they will be cached # 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: # 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -41,11 +41,11 @@ Platform Manager
Used in demo Used in demo
~~~~~~~~~~~~ ~~~~~~~~~~~~
1. :ref:`userguide_platforms` 1. :ref:`userguide_platform`
2. :ref:`cmd_platforms_list` command 2. :ref:`cmd_platform_list` command
3. :ref:`platformio platforms search avr <cmd_platforms_search>` command 3. :ref:`platformio platform search avr <cmd_platform_search>` command
4. :ref:`platformio platforms show teensy <cmd_platforms_show>` command 4. :ref:`platformio platform show teensy <cmd_platform_show>` command
5. :ref:`cmd_platforms_update` command. 5. :ref:`cmd_platform_update` command.
Library Manager 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -58,7 +58,7 @@ Embedded Development. *Easier Than Ever.*
* Built-in :ref:`Serial Port Monitor <cmd_serialports_monitor>` and * Built-in :ref:`Serial Port Monitor <cmd_serialports_monitor>` and
configurable build :ref:`-flags/-options <projectconf_build_flags>` configurable build :ref:`-flags/-options <projectconf_build_flags>`
* Pre-built toolchains, :ref:`frameworks` for the * Pre-built toolchains, :ref:`frameworks` for the
:ref:`Development Platforms <platforms>` :ref:`platforms`
Smart Build System. *Fast and Reliable.* Smart Build System. *Fast and Reliable.*
---------------------------------------- ----------------------------------------
@ -108,7 +108,7 @@ Contents
:caption: Instruments :caption: Instruments
:maxdepth: 3 :maxdepth: 3
Platforms & Boards <platforms/index> platforms/index
frameworks/index frameworks/index
.. toctree:: .. 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -33,10 +33,10 @@ JSON Structure
The key fields: 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 :ref:`frameworks` builders
* ``frameworks`` is the list with supported :ref:`frameworks` * ``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`` * ``upload`` upload settings which depend on the ``platform``
.. code-block:: json .. 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -27,7 +27,7 @@ different/own build scripts, uploader and etc.
.. note:: .. note::
If you want to change some build flags for the existing 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. development platforms! Please use :ref:`projectconf_build_flags` option.
**Step-by-Step Manual** **Step-by-Step Manual**
@ -361,9 +361,9 @@ Installation
1. Create ``platforms`` directory in :ref:`projectconf_pio_home_dir` if it 1. Create ``platforms`` directory in :ref:`projectconf_pio_home_dir` if it
doesn't exist. doesn't exist.
2. Copy ``test.py`` and ``test-builder.py`` files to ``platforms`` directory. 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. ``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 Now, you can use ``test`` for the :ref:`projectconf_env_platform` option in
:ref:`projectconf`. :ref:`projectconf`.
@ -480,6 +480,6 @@ and copy there two files:
Default([target_firm, target_size]) Default([target_firm, target_size])
Now, we should see ``ststm32gdb`` platform using :ref:`cmd_platforms_search` command output Now, we should see ``ststm32gdb`` platform using :ref:`cmd_platform_search` command output
and can install it via :ref:`platformio platforms install ststm32gdb <cmd_platforms_install>` command. 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -11,8 +11,8 @@
.. _platforms: .. _platforms:
Platforms & Embedded Boards Development Platforms
=========================== =====================
*PlatformIO* has pre-built different development platforms for popular OS *PlatformIO* has pre-built different development platforms for popular OS
(*Mac OS X, Linux (+ARM) and Windows*). Each of them include compiler, (*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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -194,7 +194,7 @@ General options
``platform`` ``platform``
^^^^^^^^^^^^ ^^^^^^^^^^^^
:ref:`Platform <platforms>` type. :ref:`platforms` name.
.. _projectconf_env_framework: .. _projectconf_env_framework:
@ -202,7 +202,7 @@ General options
``framework`` ``framework``
^^^^^^^^^^^^^ ^^^^^^^^^^^^^
:ref:`Framework <frameworks>` type. :ref:`frameworks` name.
The multiple frameworks are allowed, split them with comma ``,`` separator. 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -33,6 +33,11 @@ Options
.. program:: platformio boards .. program:: platformio boards
.. option::
--installed
List boards only from the installed platforms
.. option:: .. option::
--json-output --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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -27,7 +27,7 @@ Usage
Description Description
----------- -----------
Check or update installed :ref:`Platforms <platforms>` and Check or update installed :ref:`platforms` and
:ref:`Libraries <librarymanager>` :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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -62,7 +62,7 @@ Commands
cmd_boards cmd_boards
cmd_ci cmd_ci
cmd_init cmd_init
platformio platforms <platforms/index> platformio platform <platforms/index>
cmd_run cmd_run
cmd_serialports cmd_serialports
cmd_settings 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_install: .. _cmd_platform_install:
platformio platforms install platformio platform install
============================ ===========================
.. contents:: .. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms install [OPTIONS] [PLATFORMS] platformio platform install [OPTIONS] [PLATFORMS]
Description Description
----------- -----------
Install pre-built development :ref:`Platforms <platforms>` with related Install pre-built development :ref:`platforms` with related
packages. packages.
There are several predefined aliases for packages, such as: There are several predefined aliases for packages, such as:
@ -38,7 +38,7 @@ There are several predefined aliases for packages, such as:
Options Options
------- -------
.. program:: platformio platforms install .. program:: platformio platform install
.. option:: .. option::
--with-package --with-package
@ -63,7 +63,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio platforms install timsp430 $ platformio platform install timsp430
Installing toolchain-timsp430 package: Installing toolchain-timsp430 package:
Downloading [####################################] 100% Downloading [####################################] 100%
Unpacking [####################################] 100% Unpacking [####################################] 100%
@ -81,7 +81,7 @@ Examples
.. code-block:: bash .. 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: Installing tool-mspdebug package:
Downloading [####################################] 100% Downloading [####################################] 100%
Unpacking [####################################] 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_list: .. _cmd_platform_list:
platformio platforms list platformio platform list
========================= ========================
.. contents:: .. contents::
@ -21,18 +21,18 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms list [OPTIONS] platformio platform list [OPTIONS]
Description Description
----------- -----------
List installed :ref:`Platforms <platforms>` List installed :ref:`platforms`
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio platforms list .. program:: platformio platform list
.. option:: .. option::
--json-output --json-output
@ -44,13 +44,28 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio platforms list $ platformio platform list
atmelavr with packages: toolchain-atmelavr, tool-avrdude, framework-arduinoavr, tool-micronucleus atmelavr ~ Atmel AVR
atmelsam with packages: framework-arduinosam, ldscripts, toolchain-gccarmnoneeabi, tool-bossac ====================
freescalekinetis with packages: framework-mbed, toolchain-gccarmnoneeabi 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.
nordicnrf51 with packages: framework-mbed, toolchain-gccarmnoneeabi
nxplpc with packages: framework-mbed, toolchain-gccarmnoneeabi Home: http://platformio.org/platforms/atmelavr
ststm32 with packages: framework-libopencm3, toolchain-gccarmnoneeabi, tool-stlink, framework-spl, framework-cmsis, framework-mbed, ldscripts Packages: toolchain-atmelavr, framework-simba
teensy with packages: toolchain-atmelavr, ldscripts, framework-arduinoteensy, toolchain-gccarmnoneeabi, tool-teensy Version: 0.0.0
timsp430 with packages: toolchain-timsp430, tool-mspdebug, framework-energiamsp430, framework-arduinomsp430
titiva with packages: ldscripts, framework-libopencm3, toolchain-gccarmnoneeabi, tool-lm4flash, framework-energiativa 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_search: .. _cmd_platform_search:
platformio platforms search platformio platform search
=========================== ==========================
.. contents:: .. contents::
@ -21,18 +21,18 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms search QUERY [OPTIONS] platformio platform search QUERY [OPTIONS]
Description Description
----------- -----------
Search for development :ref:`Platforms <platforms>` Search for development :ref:`platforms`
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio platforms search .. program:: platformio platform search
.. option:: .. option::
--json-output --json-output
@ -47,73 +47,100 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio platforms search $ platformio platform search
atmelavr (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) atmelavr ~ Atmel AVR
-------- ====================
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance... 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) Home: http://platformio.org/platforms/atmelavr
-------- Packages: toolchain-atmelavr, framework-simba
Atmel | SMART offers Flash- based ARM products based on the ... Version: 0.0.0
freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) atmelsam ~ Atmel SAM
---------------- ====================
Freescale Kinetis Microcontrollers is family of multiple hardware- and ... 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) Home: http://platformio.org/platforms/atmelsam
----------- Packages: framework-arduinosam, framework-mbed, framework-simba, toolchain-gccarmnoneeabi, tool-bossac
The Nordic nRF51 Series is a family of highly flexible, multi-protocol ... Version: 0.0.0
nxplpc (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) espressif ~ Espressif
------ =====================
The NXP LPC is a family of 32-bit microcontroller integrated circuits ... 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) Home: http://platformio.org/platforms/espressif
------- Packages: framework-simba, tool-esptool, framework-arduinoespressif, sdk-esp8266, toolchain-xtensa
The STM32 family of 32-bit Flash MCUs based on the ARM Cortex-M ... Version: 0.0.0
...
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 ...
2. Search for TI development platforms 2. Search for TI development platforms
.. code-block:: bash .. code-block:: bash
$ platformio platforms search ti $ platformio platform search texas
timsp430 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) timsp430 ~ TI MSP430
-------- ====================
MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are ... 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) Home: http://platformio.org/platforms/timsp430
------ Packages: toolchain-timsp430, tool-mspdebug, framework-energiamsp430, framework-arduinomsp430
Texas Instruments TM4C12x MCUs offer the industrys most popular ...
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 .. code-block:: bash
$ platformio platforms search mbed $ platformio platform search framework-mbed
freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) atmelsam ~ Atmel SAM
---------------- ====================
Freescale Kinetis Microcontrollers is family of multiple hardware- and ... 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) Home: http://platformio.org/platforms/atmelsam
----------- Packages: toolchain-gccarmnoneeabi, framework-arduinosam, framework-simba, tool-openocd, framework-mbed, ldscripts, tool-bossac
The Nordic nRF51 Series is a family of highly flexible, multi-protocol ...
nxplpc (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) freescalekinetis ~ Freescale Kinetis
------ ====================================
The NXP LPC is a family of 32-bit microcontroller integrated circuits ... 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) Home: http://platformio.org/platforms/freescalekinetis
------- Packages: framework-mbed, toolchain-gccarmnoneeabi
The STM32 family of 32-bit Flash MCUs based on the ARM Cortex-M ...
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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_show: .. _cmd_platform_show:
platformio platforms show platformio platform show
========================= ========================
.. contents:: .. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms show PLATFORM platformio platform show PLATFORM
Description Description
----------- -----------
Show details about the installed :ref:`Platforms <platforms>` Show details about the installed :ref:`platforms`
Examples Examples
@ -35,22 +35,53 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio platforms show atmelavr $ platformio platform show atmelavr
atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework) atmelavr ~ Atmel AVR
---------- ====================
Package: toolchain-atmelavr 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.
Alias: toolchain
Version: 1 Version: 0.0.0
Installed: 2014-12-13 23:58:48 Home: http://platformio.org/platforms/atmelavr
---------- License: Apache-2.0
Package: tool-avrdude Frameworks: simba, arduino
Version: 2
Installed: 2015-02-13 22:23:17 Package toolchain-atmelavr
---------- --------------------------
Package: framework-arduinoavr Type: toolchain
Version: 12 Optional: No
Installed: 2015-02-23 20:57:40 Requirements: ~1.40801.0
---------- Installed: Yes
Package: tool-micronucleus Description: avr-gcc
Version: 1 Url: https://gcc.gnu.org/wiki/avr-gcc
Installed: 2015-02-23 21:20:14 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_uninstall: .. _cmd_platform_uninstall:
platformio platforms uninstall platformio platform uninstall
============================== =============================
.. contents:: .. contents::
@ -21,13 +21,13 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms uninstall PLATFORM platformio platform uninstall PLATFORM
Description Description
----------- -----------
Uninstall specified :ref:`Platforms <platforms>` Uninstall specified :ref:`platforms`
Examples Examples
@ -35,7 +35,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio platforms uninstall timsp430 $ platformio platform uninstall timsp430
Uninstalling toolchain-timsp430 package: [OK] Uninstalling toolchain-timsp430 package: [OK]
Uninstalling tool-mspdebug package: [OK] Uninstalling tool-mspdebug package: [OK]
Uninstalling framework-energiamsp430 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,10 +9,10 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _cmd_platforms_update: .. _cmd_platform_update:
platformio platforms update platformio platform update
=========================== ==========================
.. contents:: .. contents::
@ -21,90 +21,100 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio platforms update platformio platform update
Description 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 Examples
-------- --------
.. code-block:: bash .. code-block:: bash
$ platformio platforms update $ platformio platform update
Platform atmelavr Platform atmelavr
-------- --------
Updating toolchain-atmelavr package: Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-avrdude package: Updating tool-avrdude package:
Versions: Current=2, Latest=2 [Up-to-date] Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-arduinoavr package: Updating framework-arduinoavr package:
Versions: Current=12, Latest=12 [Up-to-date] Versions: Current=12, Latest=12 [Up-to-date]
Updating tool-micronucleus package: Updating tool-micronucleus package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Platform atmelsam Platform atmelsam
-------- --------
Updating framework-arduinosam package: Updating framework-arduinosam package:
Versions: Current=3, Latest=3 [Up-to-date] Versions: Current=3, Latest=3 [Up-to-date]
Updating ldscripts package: Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package: Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-bossac package: Updating tool-bossac package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Platform stm32 Platform stm32
-------- --------
Updating toolchain-gccarmnoneeabi package: Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-stlink package: Updating tool-stlink package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-spl package: Updating framework-spl package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-cmsis package: Updating framework-cmsis package:
Versions: Current=2, Latest=2 [Up-to-date] Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-opencm3 package: Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package: Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Platform teensy Platform teensy
-------- --------
Updating toolchain-atmelavr package: Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package: Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-arduinoteensy package: Updating framework-arduinoteensy package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package: Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-teensy package: Updating tool-teensy package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Platform timsp430 Platform timsp430
-------- --------
Updating toolchain-timsp430 package: Updating toolchain-timsp430 package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-mspdebug package: Updating tool-mspdebug package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiamsp430 package: Updating framework-energiamsp430 package:
Versions: Current=2, Latest=2 [Up-to-date] Versions: Current=2, Latest=2 [Up-to-date]
Platform titiva Platform titiva
-------- --------
Updating ldscripts package: Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package: Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-lm4flash package: Updating tool-lm4flash package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-opencm3 package: Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date] Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiativa package: 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -9,7 +9,7 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
.. _userguide_platforms: .. _userguide_platform:
Platform Manager Platform Manager
================ ================
@ -18,8 +18,8 @@ To print all available commands and options use:
.. code-block:: bash .. code-block:: bash
$ platformio platforms --help $ platformio platform --help
$ platformio platforms COMMAND --help $ platformio platform COMMAND --help
.. image:: ../../_static/platformio-demo-platforms.gif .. 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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
@ -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 importantly, from development perspective at least, is a list of supported
boards and MCUs. To keep things short: PlatformIO supports approximately 200 boards and MCUs. To keep things short: PlatformIO supports approximately 200
`Embedded Boards <http://platformio.org/boards>`_ and all major `Embedded Boards <http://platformio.org/boards>`_ and all major
:ref:`Development Platforms <platforms>`. :ref:`platforms`.
User SHOULD have a choice 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
import sys import sys
VERSION = (2, 9, "2.dev0") VERSION = (3, 0, "0.dev0")
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -51,15 +51,9 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
@staticmethod @staticmethod
def _handle_obsolate_command(name): def _handle_obsolate_command(name):
if name in ("install", "list", "search", "show", "uninstall"): if name == "platforms":
click.secho( from platformio.commands import platform
"Warning! `platformio %s` command is deprecated and will be " return platform.cli
"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)
raise AttributeError() 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -22,23 +22,18 @@ from time import time
from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, Variables from SCons.Script import COMMAND_LINE_TARGETS, DefaultEnvironment, Variables
from platformio import util from platformio import util
from platformio.exception import UnknownBoard
# AllowSubstExceptions() # AllowSubstExceptions()
# allow common variables from INI file # allow common variables from INI file
commonvars = Variables(None) commonvars = Variables(None)
commonvars.AddVariables( commonvars.AddVariables(
("PLATFORM_MANIFEST",),
("BUILD_SCRIPT",), ("BUILD_SCRIPT",),
("EXTRA_SCRIPT",), ("EXTRA_SCRIPT",),
("PIOENV",), ("PIOENV",),
("PLATFORM",), ("PLATFORM",),
# package aliases
("PIOPACKAGE_TOOLCHAIN",),
("PIOPACKAGE_FRAMEWORK",),
("PIOPACKAGE_UPLOADER",),
# options # options
("FRAMEWORK",), ("FRAMEWORK",),
("BUILD_FLAGS",), ("BUILD_FLAGS",),
@ -67,9 +62,9 @@ commonvars.AddVariables(
DefaultEnvironment( DefaultEnvironment(
tools=[ tools=[
"gcc", "g++", "as", "ar", "gnulink", "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, variables=commonvars,
# Propagating External Environment # Propagating External Environment
@ -85,15 +80,11 @@ DefaultEnvironment(
PROJECTDATA_DIR=util.get_projectdata_dir(), PROJECTDATA_DIR=util.get_projectdata_dir(),
PIOENVS_DIR=util.get_pioenvs_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"), BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"),
BUILDSRC_DIR=join("$BUILD_DIR", "src"), BUILDSRC_DIR=join("$BUILD_DIR", "src"),
LIBSOURCE_DIRS=[ LIBSOURCE_DIRS=[
"$PROJECTLIB_DIR", "$PROJECTLIB_DIR",
util.get_lib_dir(), util.get_lib_dir()
join("$PLATFORMFW_DIR", "libraries")
], ],
PYTHONEXE=normpath(sys.executable) PYTHONEXE=normpath(sys.executable)
@ -106,58 +97,27 @@ for k in commonvars.keys():
if k in env: if k in env:
env[k] = base64.b64decode(env[k]) env[k] = base64.b64decode(env[k])
env.Prepend(LIBPATH=[join("$PIOPACKAGES_DIR", "ldscripts")]) env.LoadDevPlatform(commonvars)
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")))
# Parse library names
for opt in ("LIB_IGNORE", "LIB_USE"): for opt in ("LIB_IGNORE", "LIB_USE"):
if opt not in env: if opt not in env:
continue continue
env[opt] = [l.strip() for l in env[opt].split(",") if l.strip()] env[opt] = [l.strip() for l in env[opt].split(",") if l.strip()]
if env.subst("$PIOPACKAGE_TOOLCHAIN"): # Handle custom variables from system environment
env.PrependENVPath(
"PATH",
env.subst(join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN", "bin"))
)
# handle custom variable from system environment
for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPT", for var in ("BUILD_FLAGS", "SRC_BUILD_FLAGS", "SRC_FILTER", "EXTRA_SCRIPT",
"UPLOAD_PORT", "UPLOAD_FLAGS"): "UPLOAD_PORT", "UPLOAD_FLAGS"):
k = "PLATFORMIO_%s" % var k = "PLATFORMIO_%s" % var
if environ.get(k): if environ.get(k):
env[var] = environ.get(k) env[var] = environ.get(k)
env.SConscriptChdir(0) env.SConscriptChdir(0)
env.SConsignFile(join("$PIOENVS_DIR", ".sconsign.dblite")) env.SConsignFile(join("$PIOENVS_DIR", ".sconsign.dblite"))
env.SConscript("$BUILD_SCRIPT") env.SConscript("$BUILD_SCRIPT")
if "UPLOAD_FLAGS" in env: if "UPLOAD_FLAGS" in env:
env.Append(UPLOADERFLAGS=["$UPLOAD_FLAGS"]) 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -20,7 +20,7 @@ from glob import glob
from os import environ, listdir, remove from os import environ, listdir, remove
from os.path import isdir, isfile, join from os.path import isdir, isfile, join
from platformio.util import exec_command, where_is_program from platformio import util
class InoToCPPConverter(object): class InoToCPPConverter(object):
@ -143,8 +143,6 @@ def ConvertInoToCpp(env):
def DumpIDEData(env): def DumpIDEData(env):
BOARD_CORE = env.get("BOARD_OPTIONS", {}).get("build", {}).get("core")
def get_includes(env_): def get_includes(env_):
includes = [] includes = []
# includes from used framework and libs # includes from used framework and libs
@ -164,15 +162,18 @@ def DumpIDEData(env):
lsd_dir = env_.subst(d) lsd_dir = env_.subst(d)
_append_lib_includes(env_, lsd_dir, includes) _append_lib_includes(env_, lsd_dir, includes)
# includes from toolchain # includes from toolchains
toolchain_dir = env_.subst( p = env.DevPlatform()
join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN")) for name in p.get_installed_packages().keys():
toolchain_incglobs = [ if p.get_package_type(name) != "toolchain":
join(toolchain_dir, "*", "include*"), continue
join(toolchain_dir, "lib", "gcc", "*", "*", "include*") toolchain_dir = p.get_package_dir(name)
] toolchain_incglobs = [
for g in toolchain_incglobs: join(toolchain_dir, "*", "include*"),
includes.extend(glob(g)) join(toolchain_dir, "lib", "gcc", "*", "*", "include*")
]
for g in toolchain_incglobs:
includes.extend(glob(g))
return includes return includes
@ -186,9 +187,10 @@ def DumpIDEData(env):
if name in env_.get("LIB_IGNORE", []): if name in env_.get("LIB_IGNORE", []):
continue continue
if name == "__cores__": 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( _append_lib_includes(
env_, join(libs_dir, name, BOARD_CORE), includes) env_, join(libs_dir, name, board_core), includes)
return return
include = ( include = (
@ -208,10 +210,9 @@ def DumpIDEData(env):
defines.append(env_.subst(item).replace('\\"', '"')) defines.append(env_.subst(item).replace('\\"', '"'))
# special symbol for Atmel AVR MCU # special symbol for Atmel AVR MCU
board = env_.get("BOARD_OPTIONS", {}) if env.subst("$PLATFORM") == "atmelavr":
if board and board['platform'] == "atmelavr":
defines.append( defines.append(
"__AVR_%s__" % board['build']['mcu'].upper() "__AVR_%s__" % env.BoardConfig().get("build.mcu").upper()
.replace("ATMEGA", "ATmega") .replace("ATMEGA", "ATmega")
.replace("ATTINY", "ATtiny") .replace("ATTINY", "ATtiny")
) )
@ -226,7 +227,7 @@ def DumpIDEData(env):
"includes": get_includes(env_), "includes": get_includes(env_),
"cc_flags": env_.subst(LINTCCOM), "cc_flags": env_.subst(LINTCCOM),
"cxx_flags": env_.subst(LINTCXXCOM), "cxx_flags": env_.subst(LINTCXXCOM),
"cxx_path": where_is_program( "cxx_path": util.where_is_program(
env_.subst("$CXX"), env_.subst("${ENV['PATH']}")) env_.subst("$CXX"), env_.subst("${ENV['PATH']}"))
} }
@ -254,7 +255,7 @@ def GetCompilerType(env):
try: try:
sysenv = environ.copy() sysenv = environ.copy()
sysenv['PATH'] = str(env['ENV']['PATH']) 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: except OSError:
return None return None
if result['returncode'] != 0: 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -83,14 +83,16 @@ def AutodetectUploadPort(env):
env.Replace(UPLOAD_PORT=item['disk']) env.Replace(UPLOAD_PORT=item['disk'])
break break
else: 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(): for item in get_serialports():
if "VID:PID" not in item['hwid']: if "VID:PID" not in item['hwid']:
continue continue
env.Replace(UPLOAD_PORT=item['port']) env.Replace(UPLOAD_PORT=item['port'])
for hwid in board_build_opts.get("hwid", []): for hwid in board_hwids:
board_hwid = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "") hwid_str = ("%s:%s" % (hwid[0], hwid[1])).replace("0x", "")
if board_hwid in item['hwid']: if hwid_str in item['hwid']:
break break
if "UPLOAD_PORT" in env: 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -43,9 +43,8 @@ def BuildProgram(env):
) )
# process extra flags from board # process extra flags from board
env.ProcessFlags([ if "BOARD" in env and "build.extra_flags" in env.BoardConfig():
env.get("BOARD_OPTIONS", {}).get("build", {}).get("extra_flags") env.ProcessFlags([env.BoardConfig().get("build.extra_flags")])
])
# remove base flags # remove base flags
env.ProcessUnFlags(env.get("BUILD_UNFLAGS")) env.ProcessUnFlags(env.get("BUILD_UNFLAGS"))
# apply user flags # apply user flags
@ -208,20 +207,21 @@ def BuildFrameworks(env, frameworks):
if not frameworks or "uploadlazy" in COMMAND_LINE_TARGETS: if not frameworks or "uploadlazy" in COMMAND_LINE_TARGETS:
return 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 frameworks == ["platformio"]:
if board_frameworks: if board_frameworks:
frameworks.insert(0, board_frameworks[0]) frameworks.insert(0, board_frameworks[0])
else: else:
env.Exit("Error: Please specify board type") env.Exit("Error: Please specify `board` in `platformio.ini`")
for f in frameworks: for f in frameworks:
if f in ("arduino", "energia"): if f in ("arduino", "energia"):
env.ConvertInoToCpp() env.ConvertInoToCpp()
if f in board_frameworks: if f in board_frameworks:
SConscript(env.subst( SConscript(env.GetFrameworkScript(f))
join("$PIOBUILDER_DIR", "scripts", "frameworks", "%s.py" % f)))
else: else:
env.Exit("Error: This board doesn't support %s framework!" % f) 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -16,30 +16,30 @@ import json
import click 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.argument("query", required=False)
@click.option("--installed", is_flag=True)
@click.option("--json-output", 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: if json_output:
return ouput_boards_json(query) return _ouput_boards_json(query, installed)
BOARDLIST_TPL = ("{type:<30} {mcu:<14} {frequency:<8} " BOARDLIST_TPL = ("{type:<30} {mcu:<14} {frequency:<8} "
" {flash:<7} {ram:<6} {name}") " {flash:<7} {ram:<6} {name}")
terminal_width, _ = click.get_terminal_size() terminal_width, _ = click.get_terminal_size()
grpboards = {} grpboards = {}
for type_, data in get_boards().items(): for board in _get_boards(installed):
if data['platform'] not in grpboards: if board['platform'] not in grpboards:
grpboards[data['platform']] = {} grpboards[board['platform']] = []
grpboards[data['platform']][type_] = data grpboards[board['platform']].append(board)
for (platform, boards) in sorted(grpboards.items()): for (platform, pboards) in sorted(grpboards.items()):
if query: if query:
search_data = json.dumps(boards).lower() search_data = json.dumps(pboards).lower()
if query.lower() not in search_data.lower(): if query.lower() not in search_data.lower():
continue continue
@ -48,45 +48,56 @@ def cli(query, json_output): # pylint: disable=R0912
click.secho(platform, bold=True) click.secho(platform, bold=True)
click.echo("-" * terminal_width) click.echo("-" * terminal_width)
click.echo(BOARDLIST_TPL.format( 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")) frequency="Frequency", flash="Flash", ram="RAM", name="Name"))
click.echo("-" * terminal_width) 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: 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(): if query.lower() not in search_data.lower():
continue continue
flash_size = "" flash_size = "%dkB" % (board['rom'] / 1024)
if "maximum_size" in data.get("upload", None):
flash_size = int(data['upload']['maximum_size'])
flash_size = "%dkB" % (flash_size / 1024)
ram_size = "" ram_size = board['ram']
if "maximum_ram_size" in data.get("upload", None): if ram_size >= 1024:
ram_size = int(data['upload']['maximum_ram_size']) if ram_size % 1024:
if ram_size >= 1024: ram_size = "%.1fkB" % (ram_size / 1024.0)
if ram_size % 1024:
ram_size = "%.1fkB" % (ram_size / 1024.0)
else:
ram_size = "%dkB" % (ram_size / 1024)
else: else:
ram_size = "%dB" % ram_size ram_size = "%dkB" % (ram_size / 1024)
else:
ram_size = "%dB" % ram_size
click.echo(BOARDLIST_TPL.format( click.echo(BOARDLIST_TPL.format(
type=click.style(type_, fg="cyan"), mcu=data['build']['mcu'], type=click.style(board['id'], fg="cyan"),
frequency="%dMhz" % ( mcu=board['mcu'],
int(data['build']['f_cpu'][:-1]) / 1000000), frequency="%dMhz" % (board['fcpu'] / 1000000),
flash=flash_size, ram=ram_size, name=data['name'])) flash=flash_size, ram=ram_size, name=board['name']))
def ouput_boards_json(query): def _get_boards(installed=False):
result = {} boards = PlatformManager.get_registered_boards()
for type_, data in get_boards().items(): 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: 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(): if query.lower() not in search_data.lower():
continue continue
result[type_] = data result.append(board)
click.echo(json.dumps(result)) 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -23,9 +23,9 @@ import click
from platformio import app from platformio import app
from platformio.commands.init import cli as cmd_init 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.commands.run import cli as cmd_run
from platformio.exception import CIBuildEnvsEmpty from platformio.exception import CIBuildEnvsEmpty
from platformio.util import get_boards
def validate_path(ctx, param, value): # pylint: disable=W0613 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) 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.command("ci", short_help="Continuous Integration")
@click.argument("src", nargs=-1, callback=validate_path) @click.argument("src", nargs=-1, callback=validate_path)
@click.option("--lib", "-l", multiple=True, callback=validate_path) @click.option("--lib", "-l", multiple=True, callback=validate_path)
@click.option("--exclude", multiple=True) @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, @click.option("--build-dir", default=mkdtemp,
type=click.Path(exists=True, file_okay=False, dir_okay=True, type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -19,21 +19,26 @@ from shutil import copyfile
import click import click
from platformio import app, exception, util from platformio import app, exception, util
from platformio.commands.platforms import \ from platformio.commands.platform import \
platforms_install as cli_platforms_install platform_install as cli_platform_install
from platformio.ide.projectgenerator import ProjectGenerator from platformio.ide.projectgenerator import ProjectGenerator
from platformio.platforms.base import PlatformFactory from platformio.managers.platform import PlatformManager
from platformio.util import get_boards, get_source_dir
def validate_boards(ctx, param, value): # pylint: disable=W0613 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: try:
assert not unknown_boards assert not unknown_boards
return value return value
except AssertionError: except AssertionError:
raise click.BadParameter( 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)) "`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, @click.option("--project-dir", "-d", default=getcwd,
type=click.Path(exists=True, file_okay=False, dir_okay=True, type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=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) callback=validate_boards)
@click.option("--ide", @click.option("--ide",
type=click.Choice(ProjectGenerator.get_supported_ides())) type=click.Choice(ProjectGenerator.get_supported_ides()))
@ -90,9 +95,9 @@ def cli(ctx, project_dir, board, ide, # pylint: disable=R0913
click.secho( click.secho(
"Warning! You have initialised project with more than 1 board" "Warning! You have initialised project with more than 1 board"
" for the specified IDE.\n" " for the specified IDE.\n"
"However, the IDE features (code autocompletion, syntax lint)" "However, the IDE features (code autocompletion, syntax "
" have been configured for the first board '%s' from your list" "linter) have been configured for the first board '%s' from "
" '%s'." % (board[0], ", ".join(board)), "your list '%s'." % (board[0], ", ".join(board)),
fg="yellow" fg="yellow"
) )
pg = ProjectGenerator( pg = ProjectGenerator(
@ -115,7 +120,7 @@ def cli(ctx, project_dir, board, ide, # pylint: disable=R0913
def init_base_project(project_dir): def init_base_project(project_dir):
platformio_ini = join(project_dir, "platformio.ini") platformio_ini = join(project_dir, "platformio.ini")
if not isfile(platformio_ini): if not isfile(platformio_ini):
copyfile(join(get_source_dir(), "projectconftpl.ini"), copyfile(join(util.get_source_dir(), "projectconftpl.ini"),
platformio_ini) platformio_ini)
lib_dir = join(project_dir, "lib") lib_dir = join(project_dir, "lib")
@ -246,7 +251,7 @@ def init_ci_conf(project_dir):
# - pip install -U platformio # - pip install -U platformio
# #
# script: # 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 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): env_prefix, force_download):
builtin_boards = get_boards() installed_boards = PlatformManager().get_installed_boards()
content = [] content = []
used_boards = [] used_boards = []
used_platforms = [] used_platforms = []
@ -272,23 +277,30 @@ def fill_project_envs( # pylint: disable=too-many-arguments,too-many-locals
continue continue
used_boards.append(config.get(section, "board")) used_boards.append(config.get(section, "board"))
for type_ in board_types: for id_ in board_ids:
data = builtin_boards[type_] manifest = None
used_platforms.append(data['platform']) 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 continue
content.append("") content.append("")
content.append("[env:%s%s]" % (env_prefix, type_)) content.append("[env:%s%s]" % (env_prefix, id_))
content.append("platform = %s" % data['platform']) content.append("platform = %s" % manifest['platform'])
# find default framework for board # find default framework for board
frameworks = data.get("frameworks") frameworks = manifest.get("frameworks")
if frameworks: if frameworks:
content.append("framework = %s" % frameworks[0]) content.append("framework = %s" % frameworks[0])
content.append("board = %s" % type_) content.append("board = %s" % id_)
if enable_auto_uploading: if enable_auto_uploading:
content.append("targets = upload") 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): 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): if set(platforms) <= set(installed_platforms):
return return
ctx.invoke( ctx.invoke(
cli_platforms_install, cli_platform_install,
platforms=list(set(platforms) - set(installed_platforms)) 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -13,31 +13,76 @@
# limitations under the License. # limitations under the License.
import json import json
from datetime import datetime
import click import click
from platformio import app from platformio import app, exception, util
from platformio.exception import PlatformNotInstalledYet from platformio.managers.platform import PlatformFactory, PlatformManager
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory
@click.group(short_help="Platforms and Packages Manager") @click.group(short_help="Platform Manager")
def cli(): def cli():
pass 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") @cli.command("install", short_help="Install new platforms")
@click.argument("platforms", nargs=-1, required=True) @click.argument("platforms", nargs=-1, required=True)
@click.option("--with-package", multiple=True, metavar="<package>") @click.option("--with-package", multiple=True, metavar="<package>")
@click.option("--without-package", multiple=True, metavar="<package>") @click.option("--without-package", multiple=True, metavar="<package>")
@click.option("--skip-default-package", is_flag=True) @click.option("--skip-default-package", is_flag=True)
def platforms_install(platforms, with_package, without_package, def platform_install(platforms, with_package, without_package,
skip_default_package): skip_default_package):
for platform in platforms: for platform in platforms:
p = PlatformFactory.newPlatform(platform) _platform = platform
if p.install(with_package, without_package, skip_default_package): _version = None
if "@" in platform:
_platform, _version = platform.rsplit("@", 1)
if PlatformManager().install(_platform, _version, with_package,
without_package, skip_default_package):
click.secho( click.secho(
"The platform '%s' has been successfully installed!\n" "The platform '%s' has been successfully installed!\n"
"The rest of packages will be installed automatically " "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") @cli.command("list", short_help="List installed platforms")
@click.option("--json-output", is_flag=True) @click.option("--json-output", is_flag=True)
def platforms_list(json_output): def platform_list(json_output):
platforms = []
installed_platforms = PlatformFactory.get_platforms( for manifest in PlatformManager().get_installed():
installed=True).keys() p = PlatformFactory.newPlatform(manifest['_manifest_path'])
installed_platforms.sort() platforms.append({
"name": p.get_name(),
data = [] "title": p.get_title(),
for platform in installed_platforms: "description": p.get_description(),
p = PlatformFactory.newPlatform(platform) "version": p.get_version(),
data.append({ "packages": p.get_installed_packages().keys()
"name": platform,
"packages": p.get_installed_packages()
}) })
if json_output: if json_output:
click.echo(json.dumps(data)) click.echo(json.dumps(platforms))
else: else:
for item in data: _print_platforms(platforms)
click.echo("{name:<20} with packages: {pkgs}".format(
name=click.style(item['name'], fg="cyan"),
pkgs=", ".join(item['packages'])
))
@cli.command("search", short_help="Search for development platforms") @cli.command("show", short_help="Show details about installed Platform")
@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")
@click.argument("platform") @click.argument("platform")
@click.pass_context @click.pass_context
def platforms_show(ctx, platform): def platform_show(ctx, platform):
try:
installed_platforms = PlatformFactory.get_platforms( p = PlatformFactory.newPlatform(platform)
installed=True).keys() except exception.UnknownPlatform:
if platform not in installed_platforms:
if (not app.get_setting("enable_prompts") or if (not app.get_setting("enable_prompts") or
click.confirm("The platform '%s' has not been installed yet. " click.confirm("The platform '%s' has not been installed yet. "
"Would you like to install it now?" % platform)): "Would you like to install it now?" % platform)):
ctx.invoke(platforms_install, platforms=[platform]) ctx.invoke(platform_install, platforms=[platform])
else: else:
raise PlatformNotInstalledYet(platform) raise exception.PlatformNotInstalledYet(platform)
p = PlatformFactory.newPlatform(platform) click.echo("{name} ~ {title}".format(
click.echo("{name:<20} - {description} [ {url} ]".format( name=click.style(p.get_name(), fg="cyan"), title=p.get_title()))
name=click.style(p.get_type(), fg="cyan"), click.echo("=" * (3 + len(p.get_name() + p.get_title())))
description=p.get_description(), url=p.get_vendor_url())) 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() if not p.get_packages():
for name in p.get_installed_packages(): return
data = installed_packages[name]
pkgalias = p.get_package_alias(name) installed_pkgs = p.get_installed_packages()
click.echo("----------") for name, opts in p.get_packages().items():
click.echo("Package: %s" % click.style(name, fg="yellow")) click.echo()
if pkgalias: click.echo("Package %s" % click.style(name, fg="yellow"))
click.echo("Alias: %s" % pkgalias) click.echo("-" * (8 + len(name)))
click.echo("Version: %d" % int(data['version'])) if p.get_package_type(name):
click.echo("Installed: %s" % datetime.fromtimestamp( click.echo("Type: %s" % p.get_package_type(name))
data['time']).strftime("%Y-%m-%d %H:%M:%S")) 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") @cli.command("uninstall", short_help="Uninstall platforms")
@click.argument("platforms", nargs=-1, required=True) @click.argument("platforms", nargs=-1, required=True)
def platforms_uninstall(platforms): def platform_uninstall(platforms):
for platform in platforms: for platform in platforms:
p = PlatformFactory.newPlatform(platform) _platform = platform
if p.uninstall(): _version = None
if "@" in platform:
_platform, _version = platform.rsplit("@", 1)
if PlatformManager().uninstall(_platform, _version):
click.secho("The platform '%s' has been successfully " click.secho("The platform '%s' has been successfully "
"uninstalled!" % platform, fg="green") "uninstalled!" % platform, fg="green")
@cli.command("update", short_help="Update installed Platforms and Packages") @cli.command("update", short_help="Update installed Platforms")
def platforms_update(): @click.option("--only-packages", is_flag=True)
def platform_update(only_packages):
installed_platforms = PlatformFactory.get_platforms( for manifest in PlatformManager().get_installed():
installed=True).keys() click.echo("Platform %s @ %s" % (
installed_platforms.sort() click.style(manifest['name'], fg="cyan"), manifest['version']))
for platform in installed_platforms:
click.echo("\nPlatform %s" % click.style(platform, fg="cyan"))
click.echo("--------") click.echo("--------")
p = PlatformFactory.newPlatform(platform) if only_packages:
p.update() 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -24,7 +24,7 @@ import click
from platformio import app, exception, telemetry, util from platformio import app, exception, telemetry, util
from platformio.commands.lib import lib_install as cmd_lib_install from platformio.commands.lib import lib_install as cmd_lib_install
from platformio.libmanager import LibraryManager 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") @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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -15,14 +15,13 @@
import click import click
from platformio.commands.lib import lib_update as cmd_lib_update from platformio.commands.lib import lib_update as cmd_lib_update
from platformio.commands.platforms import \ from platformio.commands.platform import platform_update as cmd_platform_update
platforms_update as cmd_platforms_update
@click.command("update", @click.command("update",
short_help="Update installed Platforms, Packages and Libraries") short_help="Update installed Platforms, Packages and Libraries")
@click.pass_context @click.pass_context
def cli(ctx): def cli(ctx):
ctx.invoke(cmd_platforms_update) ctx.invoke(cmd_platform_update)
click.echo() click.echo()
ctx.invoke(cmd_lib_update) 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -57,7 +57,7 @@ class BoardNotDefined(PlatformioException):
class UnknownBoard(PlatformioException): class UnknownBoard(PlatformioException):
MESSAGE = "Unknown board type '{0}'" MESSAGE = "Unknown board ID '{0}'"
class UnknownFramework(PlatformioException): class UnknownFramework(PlatformioException):
@ -70,9 +70,16 @@ class UnknownPackage(PlatformioException):
MESSAGE = "Detected unknown package '{0}'" 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): 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -14,23 +14,19 @@
import re import re
import struct import struct
from os import getenv, remove from os import getenv
from os.path import isdir, isfile, join
from shutil import rmtree
from time import time from time import time
import click import click
from platformio import __version__, app, exception, telemetry, util from platformio import __version__, app, exception, telemetry, util
from platformio.commands.lib import lib_update as cmd_libraries_update from platformio.commands.lib import lib_update as cmd_libraries_update
from platformio.commands.platforms import \ from platformio.commands.platform import \
platforms_install as cmd_platforms_install platform_install as cmd_platform_install
from platformio.commands.platforms import \ from platformio.commands.platform import platform_update as cmd_platform_update
platforms_update as cmd_platforms_update
from platformio.commands.upgrade import get_latest_version from platformio.commands.upgrade import get_latest_version
from platformio.libmanager import LibraryManager from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory from platformio.managers.platform import PlatformManager
from platformio.util import get_home_dir
def in_silence(ctx): def in_silence(ctx):
@ -72,10 +68,9 @@ class Upgrader(object):
self.from_version = self.version_to_int(from_version) self.from_version = self.version_to_int(from_version)
self.to_version = self.version_to_int(to_version) self.to_version = self.version_to_int(to_version)
self._upgraders = ( self._upgraders = [
(self.version_to_int("0.9.0"), self._upgrade_to_0_9_0), (self.version_to_int("3.0.0"), self._upgrade_to_3_0_0)
(self.version_to_int("1.0.0"), self._upgrade_to_1_0_0) ]
)
@staticmethod @staticmethod
def version_to_int(version): def version_to_int(version):
@ -91,38 +86,16 @@ class Upgrader(object):
result = [True] result = [True]
for item in self._upgraders: for item in self._upgraders:
if self.from_version >= item[0]: if self.from_version >= item[0] or self.to_version < item[0]:
continue continue
result.append(item[1](ctx)) result.append(item[1](ctx))
return all(result) return all(result)
def _upgrade_to_0_9_0(self, ctx): # pylint: disable=R0201 def _upgrade_to_3_0_0(self, ctx): # pylint: disable=R0201
prev_platforms = [] installed_platforms = app.get_state_item("installed_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()
if installed_platforms: if installed_platforms:
ctx.invoke(cmd_platforms_install, platforms=installed_platforms) ctx.invoke(cmd_platform_install, platforms=installed_platforms)
return True return True
@ -131,10 +104,28 @@ def after_upgrade(ctx):
if last_version == __version__: if last_version == __version__:
return 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 u = Upgrader(last_version, __version__)
click.echo("") 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("*" * terminal_width)
click.echo("If you like %s, please:" % ( click.echo("If you like %s, please:" % (
click.style("PlatformIO", fg="cyan") click.style("PlatformIO", fg="cyan")
@ -163,27 +154,6 @@ def after_upgrade(ctx):
click.echo("*" * terminal_width) click.echo("*" * terminal_width)
click.echo("") 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(): def check_platformio_upgrade():
last_check = app.get_state_item("last_check", {}) last_check = app.get_state_item("last_check", {})
@ -234,10 +204,11 @@ def check_internal_updates(ctx, what):
outdated_items = [] outdated_items = []
if what == "platforms": if what == "platforms":
for platform in PlatformFactory.get_platforms(installed=True).keys(): pm = PlatformManager()
p = PlatformFactory.newPlatform(platform) for manifest in pm.get_installed():
if p.is_outdated(): if pm.is_outdated(manifest['name'], manifest['version']):
outdated_items.append(platform) outdated_items.append(
"%s@%s" % (manifest['name'], manifest['version']))
elif what == "libraries": elif what == "libraries":
lm = LibraryManager() lm = LibraryManager()
outdated_items = lm.get_outdated() outdated_items = lm.get_outdated()
@ -255,13 +226,13 @@ def check_internal_updates(ctx, what):
if not app.get_setting("auto_update_" + what): if not app.get_setting("auto_update_" + what):
click.secho("Please update them via ", fg="yellow", nl=False) click.secho("Please update them via ", fg="yellow", nl=False)
click.secho("`platformio %s update`" % click.secho("`platformio %s update`" %
("lib" if what == "libraries" else "platforms"), ("lib" if what == "libraries" else "platform"),
fg="cyan", nl=False) fg="cyan", nl=False)
click.secho(" command.", fg="yellow") click.secho(" command.", fg="yellow")
else: else:
click.secho("Please wait while updating %s ..." % what, fg="yellow") click.secho("Please wait while updating %s ..." % what, fg="yellow")
if what == "platforms": if what == "platforms":
ctx.invoke(cmd_platforms_update) ctx.invoke(cmd_platform_update)
elif what == "libraries": elif what == "libraries":
ctx.invoke(cmd_libraries_update) ctx.invoke(cmd_libraries_update)
click.echo() 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -12,38 +12,41 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from os import makedirs, remove import os
from os.path import basename, isdir, isfile, join from os.path import dirname, isdir, isfile, join
from shutil import rmtree from shutil import rmtree
from time import time
import click import click
import requests import requests
import semantic_version
from platformio import exception, telemetry, util from platformio import exception, telemetry, util
from platformio.app import get_state_item, set_state_item
from platformio.downloader import FileDownloader from platformio.downloader import FileDownloader
from platformio.unpacker import FileUnpacker from platformio.unpacker import FileUnpacker
class PackageManager(object): class PackageManager(object):
def __init__(self): _INSTALLED_CACHE = {}
self._package_dir = join(util.get_home_dir(), "packages")
if not isdir(self._package_dir):
makedirs(self._package_dir)
assert isdir(self._package_dir)
@classmethod def __init__(self, package_dir=None, repositories=None):
@util.memoized self._INSTALLED_CACHE = {}
def get_manifest(cls): self.repositories = repositories
return util.get_api_result("/packages/manifest") 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 @staticmethod
def download(url, dest_dir, sha1=None): def download(url, dest_dir, sha1=None):
fd = FileDownloader(url, dest_dir) fd = FileDownloader(url, dest_dir)
fd.start() fd.start()
fd.verify(sha1) if sha1:
fd.verify(sha1)
return fd.get_filepath() return fd.get_filepath()
@staticmethod @staticmethod
@ -52,98 +55,180 @@ class PackageManager(object):
return fu.start() return fu.start()
@staticmethod @staticmethod
def get_installed(): def get_manifest_name():
return get_state_item("installed_packages", {}) return "package.json"
def get_outdated(self): @staticmethod
outdated = [] def max_satisfying_version(versions, requirements=None):
for name, data in self.get_installed().items(): item = None
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
systype = util.get_systype() systype = util.get_systype()
builds = ([b for b in manifest[name] if b['system'] == "all" or systype if requirements is not None:
in b['system']]) requirements = str(requirements)
if not builds: for v in versions:
raise exception.NonSystemPackage(name, systype) 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: def get_installed(self):
for b in builds: if self.package_dir in PackageManager._INSTALLED_CACHE:
if b['version'] == version: return PackageManager._INSTALLED_CACHE[self.package_dir]
return b items = []
raise exception.InvalidPackageVersion(name, version) for p in sorted(os.listdir(self.package_dir)):
else: manifest_path = join(self.package_dir, p, self.get_manifest_name())
return sorted(builds, key=lambda s: s['version'])[-1] 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): def is_installed(self, name, requirements=None):
click.echo("Installing %s package:" % click.style(name, fg="cyan")) installed = self.get_installed()
if requirements is None:
return any([p['name'] == name for p in installed])
if self.is_installed(name): for p in installed:
click.secho("Already installed", fg="yellow") if p['name'] != name:
return False continue
elif semantic_version.match(requirements, p['version']):
return True
return None
info = self.get_info(name) def get_latest_version(self, name, requirements):
pkg_dir = join(self._package_dir, name) for versions in PackageRepoIterator(name, self.repositories):
if not isdir(pkg_dir): pkgdata = self.max_satisfying_version(versions, requirements)
makedirs(pkg_dir) if pkgdata:
return pkgdata['version']
return None
dlpath = None def install(self, name, requirements, silent=False, trigger_event=True):
try: installed = self.is_installed(name, requirements)
dlpath = self.download(info['url'], pkg_dir, info['sha1']) if not installed or not silent:
except (requests.exceptions.ConnectionError, click.echo("Installing package %s @ %s:" % (
requests.exceptions.ChunkedEncodingError, click.style(name, fg="cyan"),
requests.exceptions.SSLError, requirements if requirements else "latest"))
exception.FDUnrecognizedStatusCode, StopIteration): if installed:
if not info['url'].startswith("http://dl.platformio.org"): 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( dlpath = self.download(
"http://dl.platformio.org/packages/%s" % pkgdata['url'], pkg_dir, pkgdata.get("sha1"))
basename(info['url']), pkg_dir, info['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): return success
self._register(name, info['version'])
# remove archive
remove(dlpath)
telemetry.on_event( def uninstall(self, name, requirements=None, trigger_event=True):
category="PackageManager", action="Install", label=name) 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): if not found:
click.echo("Uninstalling %s package: \t" %
click.style(name, fg="cyan"), nl=False)
if not self.is_installed(name):
click.secho("Not installed", fg="yellow") click.secho("Not installed", fg="yellow")
return False return False
else:
click.echo("[%s]" % click.style("OK", fg="green"))
if isdir(join(self._package_dir, name)): self.reset_cache()
rmtree(join(self._package_dir, name)) if trigger_event:
self._unregister(name) telemetry.on_event(
click.echo("[%s]" % click.style("OK", fg="green")) category="PackageManager", action="Uninstall", label=name)
# report usage def update(self, name, requirements=None, keep_versions=None):
telemetry.on_event( click.echo("Updating package %s @ %s:" % (
category="PackageManager", action="Uninstall", label=name) click.style(name, fg="yellow"),
requirements if requirements else "latest"))
def update(self, name): latest_version = self.get_latest_version(name, requirements)
click.echo("Updating %s package:" % click.style(name, fg="yellow")) if latest_version is None:
click.secho("Ignored! '%s' is not listed in "
"Package Repository" % name, fg="yellow")
return
installed = self.get_installed() current = None
current_version = installed[name]['version'] other_versions = []
latest_version = self.get_info(name)['version'] 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) (current_version, latest_version), nl=False)
if current_version == latest_version: if current_version == latest_version:
@ -152,21 +237,52 @@ class PackageManager(object):
else: else:
click.echo("[%s]" % (click.style("Out-of-date", fg="red"))) click.echo("[%s]" % (click.style("Out-of-date", fg="red")))
self.uninstall(name) for v in other_versions:
self.install(name) 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( telemetry.on_event(
category="PackageManager", action="Update", label=name) 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): class PackageRepoIterator(object):
data = self.get_installed()
del data[name] _MANIFEST_CACHE = {}
set_state_item("installed_packages", data)
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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,251 +18,234 @@ import re
import sys import sys
from imp import load_source from imp import load_source
from multiprocessing import cpu_count from multiprocessing import cpu_count
from os.path import isdir, isfile, join from os.path import basename, dirname, isdir, isfile, join
import click import click
import semantic_version
from platformio import app, exception, util from platformio import exception, util
from platformio.app import get_state_item, set_state_item from platformio.managers.package import PackageManager
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")
]
}
def get_packages(): class PlatformManager(PackageManager):
return PLATFORM_PACKAGES
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): class PlatformFactory(object):
@staticmethod @staticmethod
def get_clsname(type_): def get_clsname(name):
return "%s%sPlatform" % (type_.upper()[0], type_.lower()[1:]) return "%s%sPlatform" % (name.upper()[0], name.lower()[1:])
@staticmethod @staticmethod
def load_module(type_, path): def load_module(name, path):
module = None module = None
try: try:
module = load_source( module = load_source(
"platformio.platforms.%s" % type_, path) "platformio.managers.platform.%s" % name, path)
except ImportError: except ImportError:
raise exception.UnknownPlatform(type_) raise exception.UnknownPlatform(name)
return module return module
@classmethod @classmethod
@util.memoized def newPlatform(cls, name, requirements=None):
def _lookup_platforms(cls): platform_dir = None
platforms = {} if name.endswith("platform.json") and isfile(name):
for d in (util.get_home_dir(), util.get_source_dir()): platform_dir = dirname(name)
pdir = join(d, "platforms") name = util.load_json(name)['name']
if not isdir(pdir): else:
continue _manifest = PlatformManager().find_best_platform(
for p in sorted(os.listdir(pdir)): name, requirements)
if (p in ("__init__.py", "base.py") or not if _manifest:
p.endswith(".py")): platform_dir = dirname(_manifest['_manifest_path'])
continue if not platform_dir:
type_ = p[:-3] raise exception.UnknownPlatform(
path = join(pdir, p) name if not requirements else "%s@%s" % (name, requirements))
try:
isplatform = hasattr(
cls.load_module(type_, path),
cls.get_clsname(type_)
)
if isplatform:
platforms[type_] = path
except exception.UnknownPlatform:
pass
return platforms
@classmethod platform_cls = None
def get_platforms(cls, installed=False): if isfile(join(platform_dir, "platform.py")):
platforms = cls._lookup_platforms() 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: _instance = platform_cls(join(platform_dir, "platform.json"))
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_)
)()
assert isinstance(_instance, BasePlatform) assert isinstance(_instance, BasePlatform)
return _instance 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) 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._found_error = False
self._last_echo_line = None self._last_echo_line = None
@ -271,182 +254,125 @@ class BasePlatform(object):
# 3 = 2 + others # 3 = 2 + others
self._verbose_level = 3 self._verbose_level = 3
def get_type(self):
return self.__class__.__name__[:-8].lower()
def get_name(self): def get_name(self):
return self.get_type().title() return self.manifest['name']
def get_build_script(self): def get_title(self):
builtin = join(util.get_source_dir(), "builder", "scripts", "%s.py" % return self.manifest['title']
self.get_type())
if isfile(builtin):
return builtin
raise NotImplementedError()
def get_description(self): def get_description(self):
if self.__doc__: return self.manifest['description']
doclines = [l.strip() for l in self.__doc__.splitlines() if
l.strip()]
return " ".join(doclines[:-1]).strip()
else:
raise NotImplementedError()
def get_vendor_url(self): def get_version(self):
if self.__doc__ and "http" in self.__doc__: return self.manifest['version']
return self.__doc__[self.__doc__.index("http"):].strip()
else: def get_manifest(self):
raise NotImplementedError() 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): def is_embedded(self):
for name, opts in self.get_packages().items(): for opts in self.get_packages().values():
if name == "framework-mbed" or opts.get("alias") == "uploader": if opts.get("type") == "uploader":
return True return True
return False 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): def get_packages(self):
return self.PACKAGES return self.manifest.get("packages", {})
def get_package_alias(self, pkgname): def get_frameworks(self):
return self.PACKAGES[pkgname].get("alias") 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 = [] names = []
for alias in aliases: for type_ in types:
name = alias name = type_
# lookup by package aliases # lookup by package types
for _name, _opts in self.get_packages().items(): for _name, _opts in self.get_packages().items():
if _opts.get("alias") == alias: if _opts.get("type") == type_:
name = None name = None
names.append(_name) names.append(_name)
# if alias is the right name # if type is the right name
if name: if name:
names.append(name) names.append(name)
return names 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): def configure_default_packages(self, variables, targets):
# enbale used frameworks # enbale used frameworks
for pkg_name in self.pkg_aliases_to_names(["framework"]): frameworks = self.get_frameworks()
for framework in variables.get("framework", "").split(","): for framework in variables.get("framework", "").split(","):
framework = framework.lower().strip() framework = framework.lower().strip()
if not framework: if not framework or framework not in frameworks:
continue continue
if framework in pkg_name: _pkg_name = frameworks[framework]['package']
self.PACKAGES[pkg_name]['default'] = True self.get_packages()[_pkg_name]['optional'] = False
# append SCons tool # 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 # enable upload tools for upload targets
if any(["upload" in t for t in targets] + ["program" in targets]): if any(["upload" in t for t in targets] + ["program" in targets]):
for _name, _opts in self.PACKAGES.iteritems(): for _name, _opts in self.get_packages().iteritems():
if _opts.get("alias") == "uploader": if _opts.get("type") == "uploader":
self.PACKAGES[_name]['default'] = True self.get_packages()[_name]['optional'] = False
elif "uploadlazy" in targets: elif "uploadlazy" in targets:
# skip all packages, allow only upload tools # skip all packages, allow only upload tools
self.PACKAGES[_name]['default'] = False self.get_packages()[_name]['optional'] = True
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())
def run(self, variables, targets, verbose): def run(self, variables, targets, verbose):
assert isinstance(variables, dict) assert isinstance(variables, dict)
assert isinstance(targets, list) assert isinstance(targets, list)
self.configure_default_packages(variables, targets) self.configure_default_packages(variables, targets)
self._install_default_packages() self.install_packages(silent=True)
self._verbose_level = int(verbose) self._verbose_level = int(verbose)
@ -454,18 +380,13 @@ class BasePlatform(object):
targets.remove("clean") targets.remove("clean")
targets.append("-c") targets.append("-c")
variables['platform_manifest'] = self.manifest_path
if "build_script" not in variables: if "build_script" not in variables:
variables['build_script'] = self.get_build_script() variables['build_script'] = self.get_build_script()
if not isfile(variables['build_script']): if not isfile(variables['build_script']):
raise exception.BuildScriptNotFound(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 self._found_error = False
result = self._run_scons(variables, targets) result = self._run_scons(variables, targets)
assert "returncode" in result assert "returncode" in result
@ -542,3 +463,34 @@ class BasePlatform(object):
return cpu_count() return cpu_count()
except NotImplementedError: except NotImplementedError:
return 1 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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -375,32 +375,6 @@ def get_api_result(path, params=None, data=None, skipdns=False):
return result 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 @memoized
def _lookup_frameworks(): def _lookup_frameworks():
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"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ install_requires = [
"click>=3.2,<6", "click>=3.2,<6",
"lockfile>=0.9.1,<0.13", "lockfile>=0.9.1,<0.13",
"requests>=2.4.0,<3", "requests>=2.4.0,<3",
"semantic_version>=2.5.0",
"colorama", "colorama",
"pyserial<4" "pyserial<4"
] ]
@ -45,7 +46,6 @@ setup(
package_data={ package_data={
"platformio": [ "platformio": [
"projectconftpl.ini", "projectconftpl.ini",
"boards/*.json",
"ide/tpls/*/.*.tpl", "ide/tpls/*/.*.tpl",
"ide/tpls/*/*.tpl", "ide/tpls/*/*.tpl",
"ide/tpls/*/*/*.tpl", "ide/tpls/*/*/*.tpl",