Merge branch 'release/v0.9.0'

This commit is contained in:
Ivan Kravets
2014-12-01 23:04:54 +02:00
58 changed files with 1527 additions and 562 deletions

View File

@ -38,7 +38,7 @@ load-plugins=
# --enable=similarities". If you want to run only the classes checker, but have # --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes # no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W" # --disable=W"
disable=C0103,C0111,E0611,F0401,I0011,R0801,R0903 disable=C0103,C0111,E0611,F0401,I0011,R0801,R0903,R0922
[REPORTS] [REPORTS]

View File

@ -1,18 +1,40 @@
Release History Release History
=============== ===============
0.9.0 (2014-12-01)
------------------
* Implemented `platformio settings <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_settings.html>`_ command
* Improved `platformio init <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_init.html>`_ command.
Added new option ``--project-dir`` where you can specify another path to
directory where new project will be initialized (`issue #31 <https://github.com/ivankravets/platformio/issues/31>`_)
* Added *Migration Manager* which simplifies process with upgrading to a
major release
* Added *Telemetry Service* which should help us make *PlatformIO* better
* Implemented *PlatformIO AppState Manager* which allow to have multiple
``.platformio`` states.
* Refactored *Package Manager*
* Download Manager: fixed SHA1 verification within *Cygwin Environment*
(`issue #26 <https://github.com/ivankravets/platformio/issues/26>`_)
* Fixed bug with code builder and built-in Arduino libraries
(`issue #28 <https://github.com/ivankravets/platformio/issues/28>`_)
0.8.0 (2014-10-19) 0.8.0 (2014-10-19)
------------------ ------------------
* Avoided trademark issues in ``library.json`` with new fields: * Avoided trademark issues in `library.json <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html>`_
``frameworks``, ``platforms`` and ``dependencies`` (`issue #17 <https://github.com/ivankravets/platformio/issues/17>`_) with the new fields: `frameworks <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html#frameworks>`_,
`platforms <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html#platforms>`_
and `dependencies <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html#dependencies>`_
(`issue #17 <https://github.com/ivankravets/platformio/issues/17>`_)
* Switched logic from "Library Name" to "Library Registry ID" for all * Switched logic from "Library Name" to "Library Registry ID" for all
``platformio lib`` commands (install, uninstall, update and etc.) `platformio lib <http://docs.platformio.ikravets.com/en/latest/userguide/lib/index.html>`_
* Renamed ``author`` field to ``authors`` and allowed to setup multiple authors commands (install, uninstall, update and etc.)
per library in ``library.json`` * Renamed ``author`` field to `authors <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html#authors>`_
* Added option to specify "maintainer" status in ``authors`` field and allowed to setup multiple authors per library in `library.json <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html>`_
* New filters/options for ``platformio lib search`` command: ``--framework`` * Added option to specify "maintainer" status in `authors <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html#authors>`_ field
and ``--platform`` * New filters/options for `platformio lib search <http://docs.platformio.ikravets.com/en/latest/userguide/lib/cmd_search.html>`_
command: ``--framework`` and ``--platform``
0.7.1 (2014-10-06) 0.7.1 (2014-10-06)
------------------ ------------------
@ -25,14 +47,15 @@ Release History
0.7.0 (2014-09-24) 0.7.0 (2014-09-24)
------------------ ------------------
* Implemented new ``[platformio]`` section for Configuration File with ``home_dir`` * Implemented new `[platformio] <http://docs.platformio.ikravets.com/en/latest/projectconf.html#platformio>`_
section for Configuration File with `home_dir <http://docs.platformio.ikravets.com/en/latest/projectconf.html#home-dir>`_
option (`issue #14 <https://github.com/ivankravets/platformio/issues/14>`_) option (`issue #14 <https://github.com/ivankravets/platformio/issues/14>`_)
* Implemented *Library Manager* (`issue #6 <https://github.com/ivankravets/platformio/issues/6>`_) * Implemented *Library Manager* (`issue #6 <https://github.com/ivankravets/platformio/issues/6>`_)
0.6.0 (2014-08-09) 0.6.0 (2014-08-09)
------------------ ------------------
* Implemented ``serialports monitor`` (`issue #10 <https://github.com/ivankravets/platformio/issues/10>`_) * Implemented `platformio serialports monitor <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_serialports.html#platformio-serialports-monitor>`_ (`issue #10 <https://github.com/ivankravets/platformio/issues/10>`_)
* Fixed an issue ``ImportError: No module named platformio.util`` (`issue #9 <https://github.com/ivankravets/platformio/issues/9>`_) * Fixed an issue ``ImportError: No module named platformio.util`` (`issue #9 <https://github.com/ivankravets/platformio/issues/9>`_)
* Fixed bug with auto-conversation from Arduino \*.ino to \*.cpp * Fixed bug with auto-conversation from Arduino \*.ino to \*.cpp
@ -44,27 +67,31 @@ Release History
* Added auto-conversation from \*.ino to valid \*.cpp for Arduino/Energia * Added auto-conversation from \*.ino to valid \*.cpp for Arduino/Energia
frameworks (`issue #7 <https://github.com/ivankravets/platformio/issues/7>`_) frameworks (`issue #7 <https://github.com/ivankravets/platformio/issues/7>`_)
* Added `Arduino example <https://github.com/ivankravets/platformio/tree/develop/examples/arduino-adafruit-library>`_ * Added `Arduino example <https://github.com/ivankravets/platformio/tree/develop/examples/arduino-adafruit-library>`_
with external library (Adafruit CC3000) with external library (*Adafruit CC3000*)
* Implemented ``platformio upgrade`` command and "auto-check" for the latest * Implemented `platformio upgrade <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_upgrade.html>`_
command and "auto-check" for the latest
version (`issue #8 <https://github.com/ivankravets/platformio/issues/8>`_) version (`issue #8 <https://github.com/ivankravets/platformio/issues/8>`_)
* Fixed an issue with "auto-reset" for Raspduino board * Fixed an issue with "auto-reset" for *Raspduino* board
* Fixed a bug with nested libs building * Fixed a bug with nested libs building
0.4.0 (2014-07-31) 0.4.0 (2014-07-31)
------------------ ------------------
* Implemented ``serialports`` command * Implemented `platformio serialports <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_serialports.html>`_ command
* Allowed to put special build flags only for ``src`` files via * Allowed to put special build flags only for ``src`` files via
``srcbuild_flags`` environment option `srcbuild_flags <http://docs.platformio.ikravets.com/en/latest/projectconf.html#srcbuild-flags>`_
environment option
* Allowed to override some of settings via system environment variables * Allowed to override some of settings via system environment variables
such as: ``$PIOSRCBUILD_FLAGS`` and ``$PIOENVS_DIR`` such as: ``$PIOSRCBUILD_FLAGS`` and ``$PIOENVS_DIR``
* Added ``--upload-port`` option for ``platformio run`` command * Added ``--upload-port`` option for `platformio run <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_run.html#cmdoption--upload-port>`_ command
* Implemented (especially for `SmartAnthill <http://smartanthill.ikravets.com/>`_) * Implemented (especially for `SmartAnthill <http://smartanthill.ikravets.com/>`_)
``platformio run -t uploadlazy`` target (no dependencies to framework libs, `platformio run -t uploadlazy <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_run.html>`_
ELF and etc.) target (no dependencies to framework libs, ELF and etc.)
* Allowed to skip default packages via ``platformio install --skip-default-package`` flag * Allowed to skip default packages via `platformio install --skip-default-package <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_install.html#cmdoption--skip-default>`_
* Added tools for Raspberry Pi platform option
* Added support for Microduino and Raspduino boards in ``atmelavr`` platform * Added tools for *Raspberry Pi* platform
* Added support for *Microduino* and *Raspduino* boards in
`atmelavr <http://docs.platformio.ikravets.com/en/latest/platforms/atmelavr.html>`_ platform
0.3.1 (2014-06-21) 0.3.1 (2014-06-21)

View File

@ -17,61 +17,107 @@ PlatformIO
:target: https://pypi.python.org/pypi/platformio/ :target: https://pypi.python.org/pypi/platformio/
:alt: License :alt: License
`Website <http://platformio.ikravets.com>`_ | `Website + Library Search <http://platformio.ikravets.com>`_ |
`Documentation <http://docs.platformio.ikravets.com>`_ | `Documentation <http://docs.platformio.ikravets.com>`_ |
`Project Examples <https://github.com/ivankravets/platformio/tree/develop/examples>`_ | `Project Examples <https://github.com/ivankravets/platformio/tree/develop/examples>`_ |
`Bugs/Questions <https://github.com/ivankravets/platformio/issues>`_ |
`Blog <http://www.ikravets.com/category/computer-life/platformio>`_ | `Blog <http://www.ikravets.com/category/computer-life/platformio>`_ |
`Twitter <https://twitter.com/smartanthill>`_ `Twitter <https://twitter.com/PlatformIOTool>`_
**PlatformIO** is a cross-platform code builder and library manager for .. image:: https://raw.githubusercontent.com/ivankravets/platformio/develop/docs/_static/platformio-logo.png
*Arduino, MSP430, ARM*. :target: http://platformio.ikravets.com
* `Website + Library Search <http://platformio.ikravets.com>`_ `PlatformIO <http://platformio.ikravets.com>`_ is a cross-platform code builder
* `Quickstart <http://docs.platformio.ikravets.com/en/latest/quickstart.html>`_ and the missing library manager.
* `Installation <http://docs.platformio.ikravets.com/en/latest/installation.html>`_
* `Project Configuration File <http://docs.platformio.ikravets.com/en/latest/projectconf.html>`_ * `Get Started <http://platformio.ikravets.com/#!/get-started>`_
* `Platforms & Embedded Boards <http://docs.platformio.ikravets.com/en/latest/platforms/index.html>`_ * `Web 2.0 Library Search <http://platformio.ikravets.com/#!/lib>`_
* `Development Platforms <http://platformio.ikravets.com/#!/platforms>`_
* `Embedded Boards <http://platformio.ikravets.com/#!/boards>`_
* `Library Manager <http://docs.platformio.ikravets.com/en/latest/librarymanager/index.html>`_
* `User Guide <http://docs.platformio.ikravets.com/en/latest/userguide/index.html>`_ * `User Guide <http://docs.platformio.ikravets.com/en/latest/userguide/index.html>`_
* `IDE Integration <http://docs.platformio.ikravets.com/en/latest/ide.html>`_ * `IDE Integration <http://docs.platformio.ikravets.com/en/latest/ide.html>`_
* `Release History <http://docs.platformio.ikravets.com/en/latest/history.html>`_ * `Release History <http://docs.platformio.ikravets.com/en/latest/history.html>`_
You have no need to install any *IDE* or compile any tool chains. *PlatformIO* You have **no need** to install any *IDE* or compile any tool chains. *PlatformIO*
has pre-built different development platforms including: compiler, debugger, has pre-built different development platforms including: compiler, debugger,
uploader (for embedded boards) and many other useful tools. uploader (for embedded boards) and many other useful tools.
**PlatformIO** allows developer to compile the same code with different Use whenever. *Run everywhere.*
platforms using only one command -------------------------------
*PlatformIO* is written in pure *Python* and **doesn't depend** on any
additional libraries/tools from an operation system. It allows you to use
*PlatformIO* beginning from *PC (Mac, Linux, Win)* and ending with credit-card
sized computers (like *Raspberry Pi*).
Embedded Development. *Easier Than Ever.*
-----------------------------------------
*PlatformIO* is well suited for embedded development and has pre-configured
settings for most popular `Embedded Boards <http://platformio.ikravets.com/#!/boards>`_.
* Colourful `command-line output <https://raw.githubusercontent.com/ivankravets/platformio/develop/examples/platformio-examples.png>`_
* Built-in `Serial Port Monitor <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_serialports.html#platformio-serialports-monitor>`_
* Configurable `build -flags/-options <http://docs.platformio.ikravets.com/en/latest/projectconf.html#build-flags>`_
* Automatic **firmware uploading**
* Integration with `development environments (IDE) <http://docs.platformio.ikravets.com/en/latest/ide.html>`_
* Ready for **cloud compilers**
* Pre-built tool chains, frameworks for the popular `Hardware Platforms <http://platformio.ikravets.com/#!/platforms>`_
.. image:: https://raw.githubusercontent.com/ivankravets/platformio-web/develop/app/images/platformio-embedded-development.png
:target: http://platformio.ikravets.com
:alt: PlatformIO Embedded Development Process
The Missing Library Manager. *It's here!*
-----------------------------------------
*PlatformIO Library Manager* is the missing library manager for development
platforms which allows you to organize and have up-to-date external libraries.
* Friendly `Command-Line Interface <http://docs.platformio.ikravets.com/en/latest/librarymanager/index.html>`_
* Modern `Web 2.0 Library Search <http://platformio.ikravets.com/#!/lib>`_
* Open Source `Library Registry API <https://github.com/ivankravets/platformio-api>`_
* Library Crawler based on `library.json <http://docs.platformio.ikravets.com/en/latest/librarymanager/config.html>`_
specification
* Library **dependency management**
* Automatic library updating
.. image:: https://raw.githubusercontent.com/ivankravets/platformio-web/develop/app/images/platformio-library-manager.png
:target: http://platformio.ikravets.com
:alt: PlatformIO Library Manager Architecture
Smart Code Builder. *Fast and Reliable.*
----------------------------------------
*PlatformIO Code Builder* is built-on a next-generation software construction
tool named `SCons <http://www.scons.org/>`_. Think of *SCons* as an improved,
cross-platform substitute for the classic *Make* utility.
* Reliable, automatic *dependency analysis*
* Reliable detection of *build changes*
* Improved support for *parallel builds*
* Ability to share *built files in a cache*
* Lookup for external libraries which are installed via `Library Manager <http://docs.platformio.ikravets.com/en/latest/librarymanager/index.html>`_
.. image:: https://raw.githubusercontent.com/ivankravets/platformio-web/develop/app/images/platformio-scons-builder.png
:target: http://platformio.ikravets.com
:alt: PlatformIO Code Builder Architecture
Single source code. *Multiple platforms.*
-----------------------------------------
*PlatformIO* allows developer to compile the same code with different
development platforms using the *Only One Command*
`platformio run <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_run.html>`_. `platformio run <http://docs.platformio.ikravets.com/en/latest/userguide/cmd_run.html>`_.
This happens due to This happens due to
`Project Configuration File <http://docs.platformio.ikravets.com/en/latest/projectconf.html>`_ `Project Configuration File (platformio.ini) <http://docs.platformio.ikravets.com/en/latest/projectconf.html>`_
where you can setup different environments with specific where you can setup different environments with specific options (platform
options: platform type, firmware uploading settings, pre-built framework type, firmware uploading settings, pre-built framework, build flags and many
and many more. more).
.. image:: examples/platformio-examples.png
:target: https://github.com/ivankravets/platformio/raw/develop/examples/platformio-examples.png
:alt: Examples
:width: 730px
**PlatformIO** is well suited for **embedded development**. It can:
* Automatically analyse dependency
* Reliably detect build changes
* Build framework or library source code to static library
* Build *ELF* (executable and linkable firmware)
* Convert *ELF* to *HEX* or *BIN* file
* Extract *EEPROM* data
* Upload firmware to your device
It has support for many popular embedded platforms like these: It has support for many popular embedded platforms like these:
* ``atmelavr`` `Atmel AVR <http://en.wikipedia.org/wiki/Atmel_AVR>`_ * ``atmelavr`` `Atmel AVR <http://platformio.ikravets.com/#!/platforms/atmelavr>`_
(including `Arduino <http://www.arduino.cc>`_ based boards) (including *Arduino*-based boards, *Microduino, Raspduino, Teensy*)
* ``timsp430`` `TI MSP430 <http://www.ti.com/lsds/ti/microcontroller/16-bit_msp430/overview.page>`_ * ``timsp430`` `TI MSP430 <http://platformio.ikravets.com/#!/platforms/timsp430>`_
(including `MSP430 LaunchPads <http://www.ti.com/ww/en/launchpad/launchpads-msp430.html>`_) (including *MSP430* LaunchPads)
* ``titiva`` `TI TIVA C <http://www.ti.com/lsds/ti/microcontroller/tiva_arm_cortex/c_series/overview.page>`_ * ``titiva`` `TI TIVA C <http://platformio.ikravets.com/#!/platforms/titiva>`_
(including `TIVA C Series LaunchPads <http://www.ti.com/ww/en/launchpad/launchpads-connected.html>`_) (including *TIVA C* Series LaunchPads)
Licence Licence
@ -80,4 +126,3 @@ Licence
Copyright (C) 2014 Ivan Kravets Copyright (C) 2014 Ivan Kravets
Licenced under the MIT Licence. Licenced under the MIT Licence.

BIN
docs/_static/ide-platformio-arduino.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
docs/_static/ide-platformio-eclipse.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 KiB

BIN
docs/_static/ide-platformio-energia.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
docs/_static/ide-platformio-vim.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

BIN
docs/_static/platformio-logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -6,20 +6,33 @@ IDE Integration
Arduino IDE Arduino IDE
----------- -----------
`Integration of PlatformIO library manager to Arduino IDE <http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides>`_ .. image:: _static/ide-platformio-arduino.png
:target: http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides
* `Integration of PlatformIO library manager to Arduino IDE <http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides>`_
Eclipse Eclipse
------- -------
`Building and debugging Atmel AVR (Arduino-based) project using Eclipse IDE+PlatformIO <http://www.ikravets.com/computer-life/programming/2014/06/20/building-and-debugging-atmel-avr-arduino-based-project-using-eclipse-ideplatformio>`_
.. image:: _static/ide-platformio-eclipse.png
:target: http://www.ikravets.com/computer-life/programming/2014/06/20/building-and-debugging-atmel-avr-arduino-based-project-using-eclipse-ideplatformio
* `Building and debugging Atmel AVR (Arduino-based) project using Eclipse IDE+PlatformIO <http://www.ikravets.com/computer-life/programming/2014/06/20/building-and-debugging-atmel-avr-arduino-based-project-using-eclipse-ideplatformio>`_
Energia IDE Energia IDE
----------- -----------
`Integration of PlatformIO library manager to Energia IDE <http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides>`_ .. image:: _static/ide-platformio-energia.png
:target: http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides
* `Integration of PlatformIO library manager to Energia IDE <http://www.ikravets.com/computer-life/platformio/2014/10/07/integration-of-platformio-library-manager-to-arduino-and-energia-ides>`_
VIM VIM
--- ---
.. image:: _static/ide-platformio-vim.png
Recommended bundles: Recommended bundles:
* Syntax highlight - `Arduino-syntax-file <https://github.com/vim-scripts/Arduino-syntax-file>`_ * Syntax highlight - `Arduino-syntax-file <https://github.com/vim-scripts/Arduino-syntax-file>`_

View File

@ -1,12 +1,15 @@
PlatformIO: A cross-platform code builder and library manager for Arduino, MSP430, ARM PlatformIO: A cross-platform code builder and the missing library manager
====================================================================================== =========================================================================
.. image:: _static/platformio-logo.png
:target: http://platformio.ikravets.com
`Website + Library Search <http://platformio.ikravets.com>`_ | `Website + Library Search <http://platformio.ikravets.com>`_ |
`Project Examples <https://github.com/ivankravets/platformio/tree/develop/examples>`_ | `Project Examples <https://github.com/ivankravets/platformio/tree/develop/examples>`_ |
`Source Code <https://github.com/ivankravets/platformio>`_ | `Source Code <https://github.com/ivankravets/platformio>`_ |
`Bugs/Questions <https://github.com/ivankravets/platformio/issues>`_ | `Issues <https://github.com/ivankravets/platformio/issues>`_ |
`Blog <http://www.ikravets.com/category/computer-life/platformio>`_ | `Blog <http://www.ikravets.com/category/computer-life/platformio>`_ |
`Twitter <https://twitter.com/smartanthill>`_ `Twitter <https://twitter.com/PlatformIOTool>`_
You have no need to install any *IDE* or compile any tool chains. *PlatformIO* You have no need to install any *IDE* or compile any tool chains. *PlatformIO*
has pre-built different development platforms including: compiler, debugger, has pre-built different development platforms including: compiler, debugger,
@ -27,9 +30,7 @@ instruments.
* Automatically analyse dependency * Automatically analyse dependency
* Reliably detect build changes * Reliably detect build changes
* Build framework or library source code to static library * Build framework or library source code to static library
* Build *ELF* (executable and linkable firmware) * Lookup for external libraries which are installed via :ref:`librarymanager`
* Convert *ELF* to *HEX* or *BIN* file
* Extract *EEPROM* data
* Upload firmware to your device * Upload firmware to your device

View File

@ -3,31 +3,51 @@
Installation Installation
============ ============
*PlatformIO* is written in `Python <https://www.python.org>`_ and works with *PlatformIO* is written in `Python <http://python.org/download/>`_ and works
versions 2.6 and 2.7 on Unix/Linux, OS X, Windows and Credit-card ARM-based on *Mac OS X*, *Linux*, *Windows OS* and Credit-card *ARM*-based
computers (Raspberry Pi). computers (*Raspberry Pi*).
System requirements
-------------------
* **Operating systems:**
* Mac OS X
* Linux
* Windows
* `Python 2.6 or Python 2.7 <http://python.org/download/>`_
All commands below should be executed in All commands below should be executed in
`Command-line <http://en.wikipedia.org/wiki/Command-line_interface>`_ `Command-line <http://en.wikipedia.org/wiki/Command-line_interface>`_
application in your *OS*: application:
* *Unix/Linux/OS X* this is *Terminal* application. * *Mac OS X / Linux* this is *Terminal* application.
* *Windows* this is * *Windows* this is
`Command Prompt <http://en.wikipedia.org/wiki/Command_Prompt>`_ (``cmd.exe``) `Command Prompt <http://en.wikipedia.org/wiki/Command_Prompt>`_ (``cmd.exe``)
application. application.
Please *choose one of* the following:
Super-Quick Super-Quick (Mac / Linux)
----------- -------------------------
To install or upgrade *PlatformIO*, download To install or upgrade *PlatformIO* paste that at a *Terminal* prompt
`get-platformio.py <https://raw.githubusercontent.com/ivankravets/platformio/develop/scripts/get-platformio.py>`_ script. (you might need to run ``sudo`` first):
Then run the following (which may require administrator access):
.. code-block:: bash .. code-block:: bash
$ [sudo] python get-platformio.py python -c "$(curl -fsSL https://raw.githubusercontent.com/ivankravets/platformio/master/scripts/get-platformio.py)"
Installer Script (Mac / Linux / Windows)
----------------------------------------
To install or upgrade *PlatformIO*, download
`get-platformio.py <https://raw.githubusercontent.com/ivankravets/platformio/develop/scripts/get-platformio.py>`_
script. Then run the following (you might need to run ``sudo`` first):
.. code-block:: bash
python get-platformio.py
On *Windows OS* it may look like: On *Windows OS* it may look like:

View File

@ -1,21 +1,20 @@
.. _library_config:
.. |PIOAPICR| replace:: *PlatformIO Library Registry Crawler* .. |PIOAPICR| replace:: *PlatformIO Library Registry Crawler*
.. _library_config:
library.json library.json
============ ============
*PlatformIO*-suitable library should be defined by a manifest file ``library.json`` is a manifest file of development library.
``library.json`` in a `JSON-style <http://en.wikipedia.org/wiki/JSON>`_.
A data in ``library.json`` should be represented via
`associative array <http://en.wikipedia.org/wiki/Associative_array>`_
(name/value pairs). An order doesn't matter.
The allowable fields (names from pairs) are described below. The fields Initially it was
(:ref:`libjson_name`, :ref:`libjson_description`, :ref:`libjson_keywords` developed for :ref:`librarymanager`, but later was accepted by worldwide embedded
and :ref:`libjson_authors`) community like a **standard library specification**.
will be displayed in the search results at the :ref:`cmd_lib_search` (*CLI*)
and at the `WebSite <http://platformio.ikravets.com/#!/lib>`_. A data in ``library.json`` should be represented
Also, they can be used for searching for libraries. in `JSON-style <http://en.wikipedia.org/wiki/JSON>`_ via
`associative array <http://en.wikipedia.org/wiki/Associative_array>`_
(name/value pairs). An order doesn't matter. The allowable fields
(names from pairs) are described below.
.. contents:: .. contents::
@ -130,7 +129,7 @@ Example:
"repository": "repository":
{ {
"name": "git", "type": "git",
"url": "https://github.com/foo/bar.git" "url": "https://github.com/foo/bar.git"
} }

View File

@ -36,14 +36,14 @@ you **need to specify** only these fields in the :ref:`library_config`:
* :ref:`libjson_repository` * :ref:`libjson_repository`
|PIOAPICR| will populate the rest fields, like :ref:`libjson_version` or |PIOAPICR| will populate the rest fields, like :ref:`libjson_version` or
:ref:`libjson_author` with an actual information from *GitHub*. :ref:`libjson_authors` with an actual information from *GitHub*.
Example: Example:
.. code-block:: javascript .. code-block:: javascript
{ {
"name": "Arduino-IRremote", "name": "IRremote",
"keywords": "infrared, ir, remote", "keywords": "infrared, ir, remote",
"description": "Send and receive infrared signals with multiple protocols", "description": "Send and receive infrared signals with multiple protocols",
"repository": "repository":
@ -62,7 +62,7 @@ The list of **required** fields in the :ref:`library_config` will look like:
* :ref:`libjson_name` * :ref:`libjson_name`
* :ref:`libjson_keywords` * :ref:`libjson_keywords`
* :ref:`libjson_description` * :ref:`libjson_description`
* :ref:`libjson_author` * :ref:`libjson_authors`
* :ref:`libjson_repository` * :ref:`libjson_repository`
Example: Example:
@ -70,10 +70,10 @@ Example:
.. code-block:: javascript .. code-block:: javascript
{ {
"name": "Arduino-XBee", "name": "XBee",
"keywords": "xbee, protocol, radio", "keywords": "xbee, protocol, radio",
"description": "Arduino library for communicating with XBees in API mode", "description": "Arduino library for communicating with XBees in API mode",
"author": "authors":
{ {
"name": "Andrew Rapp", "name": "Andrew Rapp",
"email": "andrew.rapp@gmail.com", "email": "andrew.rapp@gmail.com",
@ -97,17 +97,17 @@ of **required** fields in the :ref:`library_config` will look like:
* :ref:`libjson_name` * :ref:`libjson_name`
* :ref:`libjson_keywords` * :ref:`libjson_keywords`
* :ref:`libjson_description` * :ref:`libjson_description`
* :ref:`libjson_author` * :ref:`libjson_authors`
* :ref:`libjson_version` * :ref:`libjson_version`
* :ref:`libjson_downloadurl` * :ref:`libjson_downloadurl`
.. code-block:: javascript .. code-block:: javascript
{ {
"name": "Arduino-OneWire", "name": "OneWire",
"keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton", "keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton",
"description": "Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)", "description": "Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)",
"author": "authors":
{ {
"name": "Paul Stoffregen", "name": "Paul Stoffregen",
"url": "http://www.pjrc.com/teensy/td_libs_OneWire.html" "url": "http://www.pjrc.com/teensy/td_libs_OneWire.html"

View File

@ -5,11 +5,11 @@ Library Manager
.. ..
*"A missing library manager for embedded platforms (Atmel AVR, MSP430 and ARM)"* [#]_ *"The missing library manager for development platforms"* [#]_
*PlatformIO Library Manager* allows you to organize external embedded libraries. *PlatformIO Library Manager* allows you to organize external embedded libraries.
You can search for new libraries via :ref:`Command Line <cmd_lib_search>` You can search for new libraries via :ref:`Command Line interface <cmd_lib_search>`
or `WebSite <http://platformio.ikravets.com/#!/lib>`_ interfaces. or `Web 2.0 Library Search <http://platformio.ikravets.com/#!/lib>`_.
You don't need to bother for finding the latest version of library. Due to You don't need to bother for finding the latest version of library. Due to
:ref:`cmd_lib_update` command you will have up-to-date external libraries. :ref:`cmd_lib_update` command you will have up-to-date external libraries.
@ -17,8 +17,9 @@ You don't need to bother for finding the latest version of library. Due to
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
creating
config config
creating
User Guide <../userguide/lib/index.rst>
.. [#] Inspired by `npm <https://www.npmjs.org>`_ and `bower .. [#] Inspired by `npm <https://www.npmjs.org>`_ and `bower
<http://bower.io>`_ package managers for web. <http://bower.io>`_ package managers for web.

View File

@ -246,10 +246,6 @@ Examples
framework = arduino framework = arduino
board = uno board = uno
upload_port = /dev/ttyUSB0
# for Windows OS
# upload_port = COM3
# enable auto-uploading # enable auto-uploading
targets = upload targets = upload
@ -265,10 +261,6 @@ Examples
framework = arduino framework = arduino
board = 168pa8m board = 168pa8m
upload_port = /dev/ttyUSB0
# for Windows OS
# upload_port = COM3
# enable auto-uploading # enable auto-uploading
targets = upload targets = upload

View File

@ -3,6 +3,10 @@
Quickstart Quickstart
========== ==========
.. note::
Please read `Get Started <http://platformio.ikravets.com/#!/get-started>`_
article from the official WebSite.
First, :ref:`Install PlatformIO <installation>`. First, :ref:`Install PlatformIO <installation>`.
Print all available development platforms for installing Print all available development platforms for installing

View File

@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio init platformio init [OPTIONS]
Description Description
@ -21,22 +21,50 @@ Initialize new PlatformIO based project.
This command will create: This command will create:
* ``.pioenvs`` - a temporary working directory.
* ``lib`` - a directory for project specific libraries. PlatformIO will
compile them to static libraries and link to executable file
* ``src`` - a source directory. Put your source code here.
* :ref:`projectconf` * :ref:`projectconf`
* ``src`` - a source directory. Put your source code here
* ``lib`` - a directory for the project specific libraries. PlatformIO will
compile them to static libraries and link to executable file
Options
-------
.. option::
--project-dir, -d
Specified path to the directory where *PlatformIO* will initialize new project.
Examples Examples
-------- --------
1. Create new project in the current working directory
.. code-block:: bash .. code-block:: bash
# Change directory to the future project
$ cd /path/to/empty/directory
$ platformio init $ platformio init
Project has been initialized! The current working directory *** will be used for the new project.
Please put your source code to `src` directory, external libraries to `lib` You can specify another project directory via
and setup environments in `platformio.ini` file. `platformio init -d %PATH_TO_PROJECT_DIR%` command.
Then process project with `platformio run` command.
The next files/directories will be created in ***
platformio.ini - Project Configuration File
src - a source directory. Put your source code here
lib - a directory for the project specific libraries
Do you want to continue? [y/N]: y
Project has been successfully initialized!
Now you can process it with `platformio run` command.
2. Create new project in the specified directory
.. code-block:: bash
$ platformio init -d %PATH_TO_DIR%
The next files/directories will be created in ***
platformio.ini - Project Configuration File
src - a source directory. Put your source code here
lib - a directory for the project specific libraries
Do you want to continue? [y/N]: y
Project has been successfully initialized!
Now you can process it with `platformio run` command.

View File

@ -11,7 +11,7 @@ Usage
.. code-block:: bash .. code-block:: bash
# Print all available development platforms # Print all available development platforms
platformio search all platformio search
# Filter platforms by "Query" # Filter platforms by "Query"
platformio search QUERY platformio search QUERY

View File

@ -0,0 +1,114 @@
.. _cmd_settings:
platformio settings
===================
Manage PlatformIO settings
.. contents::
platformio settings get
-----------------------
Usage
~~~~~
.. code-block:: bash
platformio settings get [NAME]
Description
~~~~~~~~~~~
Get/List existing settings
Examples
~~~~~~~~
1. List all settings and current their values
.. code-block:: bash
$ platformio settings get
Name Value [Default] Description
------------------------------------------------------------------------------------------
auto_update_libraries Yes Automatically update libraries (Yes/No)
auto_update_platforms Yes Automatically update platforms (Yes/No)
check_libraries_interval 7 Check for the library updates interval (days)
check_platformio_interval 3 Check for the new PlatformIO interval (days)
check_platforms_interval 7 Check for the platforms updates interval (days)
2. Show specified setting
.. code-block:: bash
$ platformio settings get auto_update_platforms
Name Value [Default] Description
------------------------------------------------------------------------------------------
auto_update_platforms Yes Automatically update platforms (Yes/No)
platformio settings set
-----------------------
Usage
~~~~~
.. code-block:: bash
platformio settings set NAME VALUE
Description
~~~~~~~~~~~
Set new value for the setting
Examples
~~~~~~~~
Change to check for the new PlatformIO each day
.. code-block:: bash
$ platformio settings set check_platformio_interval 1
The new value for the setting has been set!
Name Value [Default] Description
------------------------------------------------------------------------------------------
check_platformio_interval 1 [3] Check for the new PlatformIO interval (days)
platformio settings reset
-------------------------
Usage
~~~~~
.. code-block:: bash
platformio settings reset
Description
~~~~~~~~~~~
Reset settings to default
Examples
~~~~~~~~
.. code-block:: bash
$ platformio settings reset
The settings have been reseted!
Name Value [Default] Description
------------------------------------------------------------------------------------------
auto_update_libraries Yes Automatically update libraries (Yes/No)
auto_update_platforms Yes Automatically update platforms (Yes/No)
check_libraries_interval 7 Check for the library updates interval (days)
check_platformio_interval 3 Check for the new PlatformIO interval (days)
check_platforms_interval 7 Check for the platform updates interval (days)

View File

@ -21,6 +21,7 @@ To print all available commands and options use:
cmd_run cmd_run
cmd_search cmd_search
cmd_serialports cmd_serialports
cmd_settings
cmd_show cmd_show
cmd_uninstall cmd_uninstall
cmd_update cmd_update

View File

@ -35,38 +35,38 @@ Examples
.. code-block:: bash .. code-block:: bash
# IRremote: http://platformio.ikravets.com/#!/lib/show/4 # IRremote: http://platformio.ikravets.com/#!/lib/show/4/IRremote
$ platformio lib install 4 $ platformio lib install 4
Installing library [ 4 ]: # Installing library [ 4 ]:
Downloading [####################################] 100% # Downloading [####################################] 100%
Unpacking [####################################] 100% # Unpacking [####################################] 100%
The library #4 'IRremote' has been successfully installed! # The library #4 'IRremote' has been successfully installed!
2. Install specified version of library 2. Install specified version of library
.. code-block:: bash .. code-block:: bash
# XBee: http://platformio.ikravets.com/#!/lib/show/6 # XBee: http://platformio.ikravets.com/#!/lib/show/6/XBee
$ platformio lib install 6 --version=0.5 $ platformio lib install 6 --version=0.5
Installing library [ 6 ]: # Installing library [ 6 ]:
Downloading [####################################] 100% # Downloading [####################################] 100%
Unpacking [####################################] 100% # Unpacking [####################################] 100%
The library #6 'XBee' has been successfully installed! # The library #6 'XBee' has been successfully installed!
3. Install library with dependencies 3. Install library with dependencies
.. code-block:: bash .. code-block:: bash
# Adafruit-ST7735: http://platformio.ikravets.com/#!/lib/show/12 # Adafruit-ST7735: http://platformio.ikravets.com/#!/lib/show/12/Adafruit-ST7735
$ platformio lib install 12 $ platformio lib install 12
Installing library [ 12 ]: # Installing library [ 12 ]:
Downloading [####################################] 100% # Downloading [####################################] 100%
Unpacking [####################################] 100% # Unpacking [####################################] 100%
The library #12 'Adafruit-ST7735' has been successfully installed! # The library #12 'Adafruit-ST7735' has been successfully installed!
Installing dependencies: # Installing dependencies:
Installing library [ 13 ]: # Installing library [ 13 ]:
Downloading [####################################] 100% # Downloading [####################################] 100%
Unpacking [####################################] 100% # Unpacking [####################################] 100%
The library #13 'Adafruit-GFX' has been successfully installed! # The library #13 'Adafruit-GFX' has been successfully installed!

View File

@ -25,15 +25,15 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio lib list $ platformio lib list
#
[ ID ] Name Compatibility "Authors": Description # [ ID ] Name Compatibility "Authors": Description
------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------
[ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope # [ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope
[ 12 ] Adafruit-ST7735 arduino, atmelavr "Adafruit Industries": A library for the Adafruit 1.8" SPI display # [ 12 ] Adafruit-ST7735 arduino, atmelavr "Adafruit Industries": A library for the Adafruit 1.8" SPI display
[ 31 ] Adafruit-Unified-Sensor arduino, atmelavr "Adafruit Industries": Adafruit Unified Sensor Driver # [ 31 ] Adafruit-Unified-Sensor arduino, atmelavr "Adafruit Industries": Adafruit Unified Sensor Driver
[ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer) # [ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer)
[ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode # [ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode
[ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.) # [ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.)
[ 4 ] IRremote arduino, atmelavr "Ken Shirriff": Send and receive infrared signals with multiple protocols # [ 4 ] IRremote arduino, atmelavr "Ken Shirriff": Send and receive infrared signals with multiple protocols
[ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303) # [ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
... # ...

View File

@ -16,8 +16,8 @@ Usage
Description Description
----------- -----------
Search for library in *PlatformIO Library Registry* by Search for library in `PlatformIO Library Registry <http://platformio.ikravets.com/#!/lib>`_
:ref:`library_config` fields in the boolean mode. by :ref:`library_config` fields in the boolean mode.
The boolean search capability supports the following operators: The boolean search capability supports the following operators:
@ -90,102 +90,102 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio lib search "" $ platformio lib search
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
# [ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.)
# [ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope
# [ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer)
# [ 12 ] Adafruit-ST7735 arduino, atmelavr "Adafruit Industries": A library for the Adafruit 1.8" SPI display
# [ 31 ] Adafruit-Unified-Sensor arduino, atmelavr "Adafruit Industries": Adafruit Unified Sensor Driver
# [ 4 ] IRremote arduino, atmelavr "Ken Shirriff": Send and receive infrared signals with multiple protocols
# [ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)
# [ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode
# [ 15 ] Adafruit-ADXL345-Unified arduino, atmelavr "Adafruit Industries": Unified driver for the ADXL345 Accelerometer
# Show next libraries? [y/N]:
# ...
[ ID ] Name Compatibility "Authors": Description 2. Search for `1-Wire libraries <http://platformio.ikravets.com/#!/lib/search?query=%25221-wire%2522>`_
-------------------------------------------------------------------------------------
[ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
[ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.)
[ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope
[ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer)
[ 12 ] Adafruit-ST7735 arduino, atmelavr "Adafruit Industries": A library for the Adafruit 1.8" SPI display
[ 31 ] Adafruit-Unified-Sensor arduino, atmelavr "Adafruit Industries": Adafruit Unified Sensor Driver
[ 4 ] IRremote arduino, atmelavr "Ken Shirriff": Send and receive infrared signals with multiple protocols
[ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)
[ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode
[ 15 ] Adafruit-ADXL345-Unified arduino, atmelavr "Adafruit Industries": Unified driver for the ADXL345 Accelerometer
Show next libraries? [y/N]:
...
2. Search for "1-Wire" library
.. code-block:: bash .. code-block:: bash
$ platformio lib search 1-wire $ platformio lib search "1-wire"
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)
# ...
[ ID ] Name Compatibility "Authors": Description 3. Search for `Arduino-based "I2C" libraries <http://platformio.ikravets.com/#!/lib/search?query=framework%253Aarduino%2520i2c&page=1>`_
-------------------------------------------------------------------------------------
[ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)
...
3. Search for Arduino-based "I2C" libraries operator.
.. code-block:: bash .. code-block:: bash
$ platformio lib search "i2c" --framework=arduino $ platformio lib search "i2c" --framework="arduino"
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 11 ] I2Cdevlib-Core arduino, atmelavr "Jeff Rowberg": The I2C Device Library (I2Cdevlib) is a collection of uniform and well-documented classes to provide simple and intuitive interfaces to I2C devices.
# [ 24 ] Adafruit-L3GD20 arduino, atmelavr "Adafruit Industries": Driver for Adafruit's L3GD20 I2C Gyroscope Breakout
# [ 10 ] I2Cdevlib-AK8975 arduino, atmelavr "Jeff Rowberg": AK8975 is 3-axis electronic compass IC with high sensitive Hall sensor technology
# [ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
# ...
[ ID ] Name Compatibility "Authors": Description 4. Search for `libraries by "web" and "http" keywords <http://platformio.ikravets.com/#!/lib/search?query=keyword%253A%2522web%2522%2520keyword%253A%2522http%2522&page=1>`_.
-------------------------------------------------------------------------------------
[ 11 ] I2Cdevlib-Core arduino, atmelavr "Jeff Rowberg": The I2C Device Library (I2Cdevlib) is a collection of uniform and well-documented classes to provide simple and intuitive interfaces to I2C devices.
[ 24 ] Adafruit-L3GD20 arduino, atmelavr "Adafruit Industries": Driver for Adafruit's L3GD20 I2C Gyroscope Breakout
[ 10 ] I2Cdevlib-AK8975 arduino, atmelavr "Jeff Rowberg": AK8975 is 3-axis electronic compass IC with high sensitive Hall sensor technology
[ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
...
4. Search for libraries by "web" and "http" keywords. The ``""`` here is for
"empty" query argument.
.. code-block:: bash .. code-block:: bash
$ platformio lib search "" --keyword=web --keyword=http $ platformio lib search --keyword="web" --keyword="http"
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 5 ] Webduino arduino, atmelavr "Ben Combee": An extensible web server library (for use with the Arduino WizNet Ethernet Shield)
# [ 17 ] Adafruit-CC3000 arduino, atmelavr "Adafruit Industries": Library code for Adafruit's CC3000 Wi-Fi/WiFi breakouts
# ...
[ ID ] Name Compatibility "Authors": Description 5. Search for `libraries from "Adafruit Industries" author <http://platformio.ikravets.com/#!/lib/search?query=author%253A%2522Adafruit%20Industries%2522>`_
-------------------------------------------------------------------------------------
[ 5 ] Webduino arduino, atmelavr "Ben Combee": An extensible web server library (for use with the Arduino WizNet Ethernet Shield)
[ 17 ] Adafruit-CC3000 arduino, atmelavr "Adafruit Industries": Library code for Adafruit's CC3000 Wi-Fi/WiFi breakouts
...
5. Search for libraries from "Adafruit Industries" author.
.. code-block:: bash .. code-block:: bash
$ platformio lib search "" --author="Adafruit Industries" $ platformio lib search --author="Adafruit Industries"
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
# [ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.)
# [ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope
# [ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer)
# ...
[ ID ] Name Compatibility "Authors": Description 6. Search for `libraries that are compatible with Dallas temperature sensors <http://platformio.ikravets.com/#!/lib/search?query=DS*>`_
-------------------------------------------------------------------------------------
[ 14 ] Adafruit-9DOF-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the Adafruit 9DOF Breakout (L3GD20 / LSM303)
[ 13 ] Adafruit-GFX arduino, atmelavr "Adafruit Industries": A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.)
[ 23 ] Adafruit-L3GD20-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for the L3GD20 Gyroscope
[ 26 ] Adafruit-LSM303DLHC-Unified arduino, atmelavr "Adafruit Industries": Unified sensor driver for Adafruit's LSM303 Breakout (Accelerometer + Magnetometer)
...
6. Search for libraries that are compatible with Dallas temperature sensors
like DS18B20, DS18S20 and etc. like DS18B20, DS18S20 and etc.
.. code-block:: bash .. code-block:: bash
$ platformio lib search "DS*" $ platformio lib search "DS*"
Found N libraries: # Found N libraries:
#
# [ ID ] Name Compatibility "Authors": Description
# -------------------------------------------------------------------------------------
# [ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)
# ...
[ ID ] Name Compatibility "Authors": Description 7. Search for `Arduino-based *X10* or *XBee* libraries <http://platformio.ikravets.com/#!/lib/search?query=framework%253Aarduino%2520%252B(x10%2520xbee)&page=1>`_.
------------------------------------------------------------------------------------- The search query that is described below can be interpreted like
[ 1 ] OneWire arduino, atmelavr "Paul Stoffregen": Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc) ``arduino x10 OR arduino xbee``
...
7. Search for Arduino-based *X10* or *XBee* libraries. The search query that is
described below can be interpreted like ``arduino x10 OR arduino xbee``.
.. code-block:: bash .. code-block:: bash
$ platformio lib search --framework=arduino "+(x10 xbee)" $ platformio lib search "+(x10 xbee)" --framework="arduino"
Found 2 libraries: # Found 2 libraries:
#
[ ID ] Name Compatibility "Authors": Description # [ ID ] Name Compatibility "Authors": Description
------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------
[ 36 ] X10 arduino, atmelavr "Doug Clinton": Sending X10 signals over AC power lines (PL513, TW523 and etc) # [ 36 ] X10 arduino, atmelavr "Doug Clinton": Sending X10 signals over AC power lines (PL513, TW523 and etc)
[ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode # [ 6 ] XBee arduino, atmelavr "Andrew Rapp": Arduino library for communicating with XBees in API mode

View File

@ -24,14 +24,14 @@ Examples
.. code-block:: bash .. code-block:: bash
# OneWire: http://platformio.ikravets.com/#!/lib/show/1 # OneWire: http://platformio.ikravets.com/#!/lib/show/1/OneWire
$ platformio lib show 1 $ platformio lib show 1
OneWire # OneWire
------- # -------
Authors: Paul Stoffregen http://www.pjrc.com/teensy/td_libs_OneWire.html # Authors: Paul Stoffregen <paul@pjrc.com> http://www.pjrc.com/teensy/td_libs_OneWire.html (maintainer), Jim Studt, Jason Dangel <dangel.jason@gmail.com>, Derek Yerger, Tom Pollard <pollard@alum.mit.edu>, Robin James
Keywords: onewire, 1-wire, bus, sensor, temperature, ibutton # Keywords: onewire, 1-wire, bus, sensor, temperature, ibutton
Frameworks: arduino # Frameworks: arduino
Platforms: atmelavr # Platforms: atmelavr
Version: 2.2 # Version: 2.2
#
Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc) # Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)

View File

@ -24,6 +24,6 @@ Examples
.. code-block:: bash .. code-block:: bash
# XBee: http://platformio.ikravets.com/#!/lib/show/6 # XBee: http://platformio.ikravets.com/#!/lib/show/6/XBee
$ platformio lib uninstall 6 $ platformio lib uninstall 6
The library #6 'XBee' has been successfully uninstalled! # The library #6 'XBee' has been successfully uninstalled!

View File

@ -25,19 +25,19 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio lib update $ platformio lib update
Updating [ 23 ] Adafruit-L3GD20-Unified library: # Updating [ 23 ] Adafruit-L3GD20-Unified library:
Versions: Current=63de2eb9ea, Latest=63de2eb9ea [Up-to-date] # Versions: Current=63de2eb9ea, Latest=63de2eb9ea [Up-to-date]
Updating [ 12 ] Adafruit-ST7735 library: # Updating [ 12 ] Adafruit-ST7735 library:
Versions: Current=e880eb1687, Latest=e880eb1687 [Up-to-date] # Versions: Current=e880eb1687, Latest=e880eb1687 [Up-to-date]
Updating [ 31 ] Adafruit-Unified-Sensor library: # Updating [ 31 ] Adafruit-Unified-Sensor library:
Versions: Current=88ae805bce, Latest=88ae805bce [Up-to-date] # Versions: Current=88ae805bce, Latest=88ae805bce [Up-to-date]
Updating [ 26 ] Adafruit-LSM303DLHC-Unified library: # Updating [ 26 ] Adafruit-LSM303DLHC-Unified library:
Versions: Current=59767208a8, Latest=59767208a8 [Up-to-date] # Versions: Current=59767208a8, Latest=59767208a8 [Up-to-date]
Updating [ 13 ] Adafruit-GFX library: # Updating [ 13 ] Adafruit-GFX library:
Versions: Current=a9e5bc4707, Latest=a9e5bc4707 [Up-to-date] # Versions: Current=a9e5bc4707, Latest=a9e5bc4707 [Up-to-date]
Updating [ 1 ] OneWire library: # Updating [ 1 ] OneWire library:
Versions: Current=2.2, Latest=2.2 [Up-to-date] # Versions: Current=2.2, Latest=2.2 [Up-to-date]
Updating [ 4 ] IRremote library: # Updating [ 4 ] IRremote library:
Versions: Current=f2dafe5030, Latest=f2dafe5030 [Up-to-date] # Versions: Current=f2dafe5030, Latest=f2dafe5030 [Up-to-date]
Updating [ 14 ] Adafruit-9DOF-Unified library: # Updating [ 14 ] Adafruit-9DOF-Unified library:
Versions: Current=b2f07242ac, Latest=b2f07242ac [Up-to-date] # Versions: Current=b2f07242ac, Latest=b2f07242ac [Up-to-date]

View File

@ -1,12 +1,12 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
VERSION = (0, 8, 0) VERSION = (0, 9, 0)
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"
__description__ = ("A cross-platform code builder and library manager for " __description__ = ("A cross-platform code builder and "
"Arduino, MSP430, ARM") "the missing library manager")
__url__ = "http://platformio.ikravets.com" __url__ = "http://platformio.ikravets.com"
__author__ = "Ivan Kravets" __author__ = "Ivan Kravets"
@ -16,4 +16,3 @@ __license__ = "MIT License"
__copyright__ = "Copyright (C) 2014 Ivan Kravets" __copyright__ = "Copyright (C) 2014 Ivan Kravets"
__apiurl__ = "http://api.platformio.ikravets.com" __apiurl__ = "http://api.platformio.ikravets.com"
__pkgmanifesturl__ = "http://dl.platformio.ikravets.com/packages/manifest.json"

View File

@ -1,21 +1,19 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os import listdir, makedirs from os import listdir
from os.path import getmtime, isdir, isfile, join from os.path import join
from sys import exit as sys_exit from sys import exit as sys_exit
from time import time
from traceback import format_exc from traceback import format_exc
from click import command, MultiCommand, secho, version_option import click
from platformio import __version__ from platformio import __version__, maintenance
from platformio.commands.upgrade import get_latest_version
from platformio.exception import PlatformioException, UnknownCLICommand from platformio.exception import PlatformioException, UnknownCLICommand
from platformio.util import get_home_dir, get_source_dir from platformio.util import get_source_dir
class PlatformioCLI(MultiCommand): # pylint: disable=R0904 class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
def list_commands(self, ctx): def list_commands(self, ctx):
cmds = [] cmds = []
@ -28,6 +26,7 @@ class PlatformioCLI(MultiCommand): # pylint: disable=R0904
return cmds return cmds
def get_command(self, ctx, name): def get_command(self, ctx, name):
mod = None
try: try:
mod = __import__("platformio.commands." + name, mod = __import__("platformio.commands." + name,
None, None, ["cli"]) None, None, ["cli"])
@ -36,35 +35,27 @@ class PlatformioCLI(MultiCommand): # pylint: disable=R0904
return mod.cli return mod.cli
@command(cls=PlatformioCLI) @click.command(cls=PlatformioCLI)
@version_option(__version__, prog_name="PlatformIO") @click.version_option(__version__, prog_name="PlatformIO")
def cli(): @click.pass_context
pass def cli(ctx):
maintenance.on_platformio_start(ctx)
def autocheck_latest_version(): @cli.resultcallback()
check_interval = 3600 * 24 * 7 # 1 week @click.pass_context
checkfile = join(get_home_dir(), ".pioupgrade") def process_result(ctx, result):
if isfile(checkfile) and getmtime(checkfile) > (time() - check_interval): maintenance.on_platformio_end(ctx, result)
return False
if not isdir(get_home_dir()):
makedirs(get_home_dir())
with open(checkfile, "w") as f:
f.write(str(time()))
return get_latest_version() != __version__
def main(): def main():
try: try:
if autocheck_latest_version(): cli(None)
secho("\nThere is a new version of PlatformIO available.\n"
"Please upgrade it via `platformio upgrade` command.\n",
fg="yellow")
cli()
except Exception as e: # pylint: disable=W0703 except Exception as e: # pylint: disable=W0703
maintenance.on_platformio_exception(e)
if isinstance(e, PlatformioException): if isinstance(e, PlatformioException):
sys_exit("Error: " + str(e)) click.echo("Error: " + str(e))
sys_exit(1)
else: else:
print format_exc() print format_exc()

111
platformio/app.py Normal file
View File

@ -0,0 +1,111 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from os.path import isfile, join
from platformio import __version__
from platformio.exception import InvalidSettingName, InvalidSettingValue
from platformio.util import get_home_dir
DEFAULT_SETTINGS = {
"check_platformio_interval": {
"description": "Check for the new PlatformIO interval (days)",
"value": 3
},
"check_platforms_interval": {
"description": "Check for the platform updates interval (days)",
"value": 7
},
"check_libraries_interval": {
"description": "Check for the library updates interval (days)",
"value": 7
},
"auto_update_platforms": {
"description": "Automatically update platforms (Yes/No)",
"value": True
},
"auto_update_libraries": {
"description": "Automatically update libraries (Yes/No)",
"value": True
},
"enable_telemetry": {
"description": ("Shares commands, platforms and libraries usage"
" to help us make PlatformIO better (Yes/No)"),
"value": True
}
}
class State(object):
def __init__(self, path=None):
self.path = path
if not self.path:
self.path = join(get_home_dir(), "appstate.json")
self._state = {}
def __enter__(self):
try:
if isfile(self.path):
with open(self.path, "r") as fp:
self._state = json.load(fp)
except ValueError:
self._state = {}
return self._state
def __exit__(self, type_, value, traceback):
with open(self.path, "w") as fp:
if "dev" in __version__:
json.dump(self._state, fp, indent=4)
else:
json.dump(self._state, fp)
def get_state_item(name, default=None):
with State() as data:
return data.get(name, default)
def set_state_item(name, value):
with State() as data:
data[name] = value
def get_setting(name):
if name not in DEFAULT_SETTINGS:
raise InvalidSettingName(name)
with State() as data:
if "settings" in data and name in data['settings']:
return data['settings'][name]
return DEFAULT_SETTINGS[name]['value']
def set_setting(name, value):
if name not in DEFAULT_SETTINGS:
raise InvalidSettingName(name)
defdata = DEFAULT_SETTINGS[name]
try:
if "validator" in defdata:
value = defdata['validator']()
elif (isinstance(defdata['value'], bool)
and not isinstance(value, bool)):
value = str(value).lower() in ("yes", "y", "1")
elif isinstance(defdata['value'], int):
value = int(value)
except Exception:
raise InvalidSettingValue(value, name)
with State() as data:
if "settings" not in data:
data['settings'] = {}
data['settings'][name] = value
def reset_settings():
with State() as data:
if "settings" in data:
del data['settings']

View File

@ -11,10 +11,10 @@ except ImportError:
break break
from platformio.util import get_home_dir from platformio.util import get_home_dir
from os.path import isdir, join from os.path import join
from SCons.Script import (DefaultEnvironment, Exit, SConscript, from SCons.Script import (DefaultEnvironment, SConscript, SConscriptChdir,
SConscriptChdir, Variables) Variables)
from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir, from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir,
get_source_dir) get_source_dir)
@ -24,8 +24,16 @@ from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir,
# allow common variables from INI file # allow common variables from INI file
commonvars = Variables(None) commonvars = Variables(None)
commonvars.AddVariables( commonvars.AddVariables(
("BUILD_SCRIPT",),
("PIOENV",), ("PIOENV",),
("PLATFORM",), ("PLATFORM",),
# package aliases
("PIOPACKAGE_TOOLCHAIN",),
("PIOPACKAGE_UPLOADER",),
("PIOPACKAGE_FRAMEWORK",),
# options
("FRAMEWORK",), ("FRAMEWORK",),
("BUILD_FLAGS",), ("BUILD_FLAGS",),
("SRCBUILD_FLAGS",), ("SRCBUILD_FLAGS",),
@ -46,14 +54,13 @@ DefaultEnvironment(
toolpath=[join("$PIOBUILDER_DIR", "tools")], toolpath=[join("$PIOBUILDER_DIR", "tools")],
variables=commonvars, variables=commonvars,
PIOBUILDER_DIR=join(get_source_dir(), "builder"), PIOHOME_DIR=get_home_dir(),
PROJECT_DIR=get_project_dir(), PROJECT_DIR=get_project_dir(),
PIOENVS_DIR=get_pioenvs_dir(), PIOENVS_DIR=get_pioenvs_dir(),
PLATFORMIOHOME_DIR=get_home_dir(), PIOBUILDER_DIR=join(get_source_dir(), "builder"),
PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "$PLATFORM"), PIOPACKAGES_DIR=join("$PIOHOME_DIR", "packages"),
PLATFORMFW_DIR=join("$PLATFORM_DIR", "frameworks", "$FRAMEWORK"), PLATFORMFW_DIR=join("$PIOPACKAGES_DIR", "$PIOPACKAGE_FRAMEWORK"),
PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"),
BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"), BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"),
LIBSOURCE_DIRS=[ LIBSOURCE_DIRS=[
@ -64,14 +71,10 @@ DefaultEnvironment(
) )
env = DefaultEnvironment() env = DefaultEnvironment()
env.PrependENVPath(
if not isdir(env['PLATFORMIOHOME_DIR']): "PATH",
Exit("You haven't installed any platforms yet. Please use " env.subst(join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN", "bin"))
"`platformio install` command") )
elif not isdir(env.subst("$PLATFORM_DIR")):
Exit("An '%s' platform hasn't been installed yet. Please use "
"`platformio install %s` command" % (env['PLATFORM'],
env['PLATFORM']))
SConscriptChdir(0) SConscriptChdir(0)
SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", "${PLATFORM}.py"))) SConscript(env.subst("$BUILD_SCRIPT"))

View File

@ -53,13 +53,13 @@ env.Replace(
"-mmcu=$BOARD_MCU" "-mmcu=$BOARD_MCU"
], ],
UPLOADER=join("$PLATFORMTOOLS_DIR", "avrdude", "avrdude"), UPLOADER=join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude"),
UPLOADERFLAGS=[ UPLOADERFLAGS=[
"-V", # do not verify "-V", # do not verify
"-q", # suppress progress output "-q", # suppress progress output
"-D", # disable auto erase for flash memory "-D", # disable auto erase for flash memory
"-p", "$BOARD_MCU", "-p", "$BOARD_MCU",
"-C", join("$PLATFORMTOOLS_DIR", "avrdude", "avrdude.conf"), "-C", join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude.conf"),
"-c", "$UPLOAD_PROTOCOL", "-c", "$UPLOAD_PROTOCOL",
"-b", "$UPLOAD_SPEED", "-b", "$UPLOAD_SPEED",
"-P", "$UPLOAD_PORT" "-P", "$UPLOAD_PORT"

View File

@ -31,18 +31,19 @@ if "build.usb_product" in BOARD_OPTIONS:
# include board variant # include board variant
env.VariantDir( env.VariantDir(
join("$BUILD_DIR", "variant"), join("$BUILD_DIR", "FrameworkArduinoVariant"),
join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant']) join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant'])
) )
env.Append( env.Append(
CPPDEFINES=[ CPPDEFINES=[
"ARDUINO_ARCH_AVR", # @TODO Should be dynamic
"ARDUINO=%d" % ARDUINO_VERSION, "ARDUINO=%d" % ARDUINO_VERSION,
"ARDUINO_%s" % BOARD_OPTIONS['build.board'] "ARDUINO_%s" % BOARD_OPTIONS['build.board']
] + ARDUINO_USBDEFINES, ] + ARDUINO_USBDEFINES,
CPPPATH=[ CPPPATH=[
join("$BUILD_DIR", "core"), join("$BUILD_DIR", "FrameworkArduino"),
join("$BUILD_DIR", "variant") join("$BUILD_DIR", "FrameworkArduinoVariant")
] ]
) )
@ -63,7 +64,7 @@ libs = []
# #
libs.append(env.BuildLibrary( libs.append(env.BuildLibrary(
join("$BUILD_DIR", "core"), join("$BUILD_DIR", "FrameworkArduino"),
join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core']) join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core'])
)) ))

View File

@ -22,7 +22,7 @@ ENERGIA_VERSION = int(
# include board variant # include board variant
env.VariantDir( env.VariantDir(
join("$BUILD_DIR", "variant"), join("$BUILD_DIR", "FrameworkEnergiaVariant"),
join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant']) join("$PLATFORMFW_DIR", "variants", BOARD_OPTIONS['build.variant'])
) )
@ -32,8 +32,8 @@ env.Append(
"ENERGIA=%d" % ENERGIA_VERSION "ENERGIA=%d" % ENERGIA_VERSION
], ],
CPPPATH=[ CPPPATH=[
join("$BUILD_DIR", "core"), join("$BUILD_DIR", "FrameworkEnergia"),
join("$BUILD_DIR", "variant") join("$BUILD_DIR", "FrameworkEnergiaVariant")
] ]
) )
@ -60,7 +60,7 @@ libs = []
# #
libs.append(env.BuildLibrary( libs.append(env.BuildLibrary(
join("$BUILD_DIR", "core"), join("$BUILD_DIR", "FrameworkEnergia"),
join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core']) join("$PLATFORMFW_DIR", "cores", BOARD_OPTIONS['build.core'])
)) ))

View File

@ -51,7 +51,7 @@ env.Replace(
"-Wl,-gc-sections,-u,main" "-Wl,-gc-sections,-u,main"
], ],
UPLOADER=join("$PLATFORMTOOLS_DIR", "mspdebug", "mspdebug"), UPLOADER=join("$PIOPACKAGES_DIR", "tool-mspdebug", "mspdebug"),
UPLOADERFLAGS=[ UPLOADERFLAGS=[
"$UPLOAD_PROTOCOL" if system() != "Windows" else "tilib", "$UPLOAD_PROTOCOL" if system() != "Windows" else "tilib",
"--force-reset" "--force-reset"

View File

@ -71,7 +71,7 @@ env.Replace(
"-fsingle-precision-constant" "-fsingle-precision-constant"
], ],
UPLOADER=join("$PLATFORMTOOLS_DIR", "lm4flash", "lm4flash"), UPLOADER=join("$PIOPACKAGES_DIR", "tool-lm4flash", "lm4flash"),
UPLOADCMD="$UPLOADER $SOURCES" UPLOADCMD="$UPLOADER $SOURCES"
) )

View File

@ -14,11 +14,6 @@ def ProcessGeneral(env):
if "BUILD_FLAGS" in env: if "BUILD_FLAGS" in env:
env.MergeFlags(env['BUILD_FLAGS']) env.MergeFlags(env['BUILD_FLAGS'])
env.PrependENVPath(
"PATH",
join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin")
)
if "FRAMEWORK" in env: if "FRAMEWORK" in env:
if env['FRAMEWORK'] in ("arduino", "energia"): if env['FRAMEWORK'] in ("arduino", "energia"):
env.ConvertInotoCpp() env.ConvertInotoCpp()
@ -72,9 +67,9 @@ def BuildDependentLibraries(env, src_dir):
deplibs = env.GetDependentLibraries(src_dir) deplibs = env.GetDependentLibraries(src_dir)
env.Append(CPPPATH=[join("$BUILD_DIR", l) for (l, _) in deplibs]) env.Append(CPPPATH=[join("$BUILD_DIR", l) for (l, _) in deplibs])
for (libname, lsd_dir) in deplibs: for (libname, inc_dir) in deplibs:
lib = env.BuildLibrary( lib = env.BuildLibrary(
join("$BUILD_DIR", libname), join(lsd_dir, libname)) join("$BUILD_DIR", libname), inc_dir)
env.Clean(libname, lib) env.Clean(libname, lib)
libs.append(lib) libs.append(lib)
return libs return libs
@ -98,19 +93,24 @@ def GetDependentLibraries(env, src_dir):
def ParseIncludesRecurive(env, regexp, source_file, includes): def ParseIncludesRecurive(env, regexp, source_file, includes):
matches = regexp.findall(source_file.get_text_contents()) matches = regexp.findall(source_file.get_text_contents())
for inc_name in matches: for inc_fname in matches:
if inc_name in includes: if inc_fname in includes:
continue continue
for lsd_dir in env['LIBSOURCE_DIRS']: for lsd_dir in env['LIBSOURCE_DIRS']:
lsd_dir = env.subst(lsd_dir) lsd_dir = env.subst(lsd_dir)
if not isdir(lsd_dir): if not isdir(lsd_dir):
continue continue
for libname in listdir(lsd_dir): for libname in listdir(lsd_dir):
inc_path = join(lsd_dir, libname, inc_name) inc_dir = join(lsd_dir, libname)
if not isfile(inc_path): inc_file = join(inc_dir, inc_fname)
if not isfile(inc_file):
# if source code is in "src" dir
inc_dir = join(lsd_dir, libname, "src")
inc_file = join(inc_dir, inc_fname)
if not isfile(inc_file):
continue continue
includes[inc_name] = (len(includes) + 1, libname, lsd_dir) includes[inc_fname] = (len(includes) + 1, libname, inc_dir)
env.ParseIncludesRecurive(regexp, env.File(inc_path), includes) env.ParseIncludesRecurive(regexp, env.File(inc_file), includes)
def VariantDirRecursive(env, variant_dir, src_dir, duplicate=True): def VariantDirRecursive(env, variant_dir, src_dir, duplicate=True):

View File

@ -1,30 +1,58 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os import makedirs from os import getcwd, makedirs
from os.path import isdir, isfile, join from os.path import isdir, isfile, join
from shutil import copyfile from shutil import copyfile
from click import command, secho import click
from platformio.exception import ProjectInitialized from platformio.exception import ProjectInitialized
from platformio.util import get_source_dir from platformio.util import get_source_dir
@command("init", short_help="Initialize new PlatformIO based project") @click.command("init", short_help="Initialize new PlatformIO based project")
def cli(): @click.option("--project-dir", "-d", default=getcwd(),
type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True))
def cli(project_dir):
if isfile("platformio.ini") and isdir("src"): project_file = join(project_dir, "platformio.ini")
src_dir = join(project_dir, "src")
lib_dir = join(project_dir, "lib")
if all([isfile(project_file), isdir(src_dir), isdir(lib_dir)]):
raise ProjectInitialized() raise ProjectInitialized()
for d in ("lib", "src"):
if not isdir(d): if project_dir == getcwd():
makedirs(d) click.secho("The current working directory", fg="yellow", nl=False)
if not isfile("platformio.ini"): click.secho(" %s " % project_dir, fg="blue", nl=False)
copyfile(join(get_source_dir(), "projectconftpl.ini"), click.secho(
"platformio.ini") "will be used for the new project.\n"
secho("Project has been initialized!\n" "You can specify another project directory via\n"
"Please put your source code to `src` directory, " "`platformio init -d %PATH_TO_PROJECT_DIR%` command.\n",
"external libraries to `lib` and " fg="yellow"
"setup environments in `platformio.ini` file.\n" )
"Then process project with `platformio run` command.",
fg="green") click.echo("The next files/directories will be created in %s" %
click.style(project_dir, fg="blue"))
click.echo("%s - Project Configuration File" %
click.style("platformio.ini", fg="cyan"))
click.echo("%s - a source directory. Put your source code here" %
click.style("src", fg="cyan"))
click.echo("%s - a directory for the project specific libraries" %
click.style("lib", fg="cyan"))
if click.confirm("Do you want to continue?"):
for d in (src_dir, lib_dir):
if not isdir(d):
makedirs(d)
if not isfile(project_file):
copyfile(join(get_source_dir(), "projectconftpl.ini"),
project_file)
click.secho(
"Project has been successfully initialized!\n"
"Now you can process it with `platformio run` command.",
fg="green"
)
else:
click.secho("Aborted by user", fg="red")

View File

@ -8,7 +8,6 @@ from platformio.exception import (LibAlreadyInstalledError,
from platformio.libmanager import LibraryManager from platformio.libmanager import LibraryManager
from platformio.util import get_api_result, get_lib_dir from platformio.util import get_api_result, get_lib_dir
LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} " LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} "
"\"{authornames}\": {description}") "\"{authornames}\": {description}")
@ -47,8 +46,11 @@ def cli():
@click.option("-k", "--keyword", multiple=True) @click.option("-k", "--keyword", multiple=True)
@click.option("-f", "--framework", multiple=True) @click.option("-f", "--framework", multiple=True)
@click.option("-p", "--platform", multiple=True) @click.option("-p", "--platform", multiple=True)
@click.argument("query") @click.argument("query", required=False)
def lib_search(query, **filters): def lib_search(query, **filters):
if not query:
query = ""
for key, values in filters.iteritems(): for key, values in filters.iteritems():
for value in values: for value in values:
query += ' %s:"%s"' % (key, value) query += ' %s:"%s"' % (key, value)
@ -77,15 +79,12 @@ def lib_search(query, **filters):
@cli.command("install", short_help="Install library") @cli.command("install", short_help="Install library")
@click.argument("ids", type=click.INT, nargs=-1, metavar="[LIBRARY_ID]") @click.argument("libid", type=click.INT, nargs=-1, metavar="[LIBRARY_ID]")
@click.option("-v", "--version") @click.option("-v", "--version")
def lib_install_cli(ids, version): @click.pass_context
lib_install(ids, version) def lib_install(ctx, libid, version):
def lib_install(ids, version=None):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager(get_lib_dir())
for id_ in ids: for id_ in libid:
click.echo( click.echo(
"Installing library [ %s ]:" % click.style(str(id_), fg="green")) "Installing library [ %s ]:" % click.style(str(id_), fg="green"))
try: try:
@ -104,7 +103,7 @@ def lib_install(ids, version=None):
_dependencies = [_dependencies] _dependencies = [_dependencies]
for item in _dependencies: for item in _dependencies:
try: try:
lib_install_dependency(item) lib_install_dependency(ctx, item)
except AssertionError: except AssertionError:
raise LibInstallDependencyError(str(item)) raise LibInstallDependencyError(str(item))
@ -112,7 +111,7 @@ def lib_install(ids, version=None):
click.secho("Already installed", fg="yellow") click.secho("Already installed", fg="yellow")
def lib_install_dependency(data): def lib_install_dependency(ctx, data):
assert isinstance(data, dict) assert isinstance(data, dict)
query = [] query = []
for key in data.keys(): for key in data.keys():
@ -127,18 +126,14 @@ def lib_install_dependency(data):
result = get_api_result("/lib/search", dict(query=" ".join(query))) result = get_api_result("/lib/search", dict(query=" ".join(query)))
assert result['total'] == 1 assert result['total'] == 1
lib_install([result['items'][0]['id']]) ctx.invoke(lib_install, libid=[result['items'][0]['id']])
@cli.command("uninstall", short_help="Uninstall libraries") @cli.command("uninstall", short_help="Uninstall libraries")
@click.argument("ids", type=click.INT, nargs=-1) @click.argument("libid", type=click.INT, nargs=-1)
def lib_uninstall_cli(ids): def lib_uninstall(libid):
lib_uninstall(ids)
def lib_uninstall(ids):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager(get_lib_dir())
for id_ in ids: for id_ in libid:
info = lm.get_info(id_) info = lm.get_info(id_)
if lm.uninstall(id_): if lm.uninstall(id_):
click.secho("The library #%s '%s' has been successfully " click.secho("The library #%s '%s' has been successfully "
@ -193,15 +188,10 @@ def lib_show(libid):
@cli.command("update", short_help="Update installed libraries") @cli.command("update", short_help="Update installed libraries")
def lib_update(): @click.pass_context
def lib_update(ctx):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager(get_lib_dir())
for id_, latest_version in (lm.get_latest_versions() or {}).items():
lib_ids = [str(item['id']) for item in lm.get_installed().values()]
if not lib_ids:
return
versions = get_api_result("/lib/version/" + str(",".join(lib_ids)))
for id_ in lib_ids:
info = lm.get_info(int(id_)) info = lm.get_info(int(id_))
click.echo("Updating [ %s ] %s library:" % ( click.echo("Updating [ %s ] %s library:" % (
@ -209,8 +199,6 @@ def lib_update():
click.style(info['name'], fg="cyan"))) click.style(info['name'], fg="cyan")))
current_version = info['version'] current_version = info['version']
latest_version = versions[id_]
if latest_version is None: if latest_version is None:
click.secho("Unknown library", fg="red") click.secho("Unknown library", fg="red")
continue continue
@ -224,8 +212,8 @@ def lib_update():
else: else:
click.echo("[%s]" % (click.style("Out-of-date", fg="red"))) click.echo("[%s]" % (click.style("Out-of-date", fg="red")))
lib_uninstall([int(id_)]) ctx.invoke(lib_uninstall, libid=[int(id_)])
lib_install([int(id_)]) ctx.invoke(lib_install, libid=[int(id_)])
@cli.command("register", short_help="Register new library") @cli.command("register", short_help="Register new library")

View File

@ -3,14 +3,19 @@
from click import command, echo, style from click import command, echo, style
from platformio.pkgmanager import PackageManager from platformio.platforms.base import PlatformFactory
@command("list", short_help="List installed platforms") @command("list", short_help="List installed platforms")
def cli(): def cli():
for name, pkgs in PackageManager.get_installed().items(): installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
for platform in installed_platforms:
p = PlatformFactory().newPlatform(platform)
echo("{name:<20} with packages: {pkgs}".format( echo("{name:<20} with packages: {pkgs}".format(
name=style(name, fg="cyan"), name=style(p.get_name(), fg="cyan"),
pkgs=", ".join(pkgs.keys()) pkgs=", ".join(p.get_installed_packages())
)) ))

View File

@ -3,6 +3,7 @@
from click import command, echo, option, secho, style from click import command, echo, option, secho, style
from platformio import telemetry
from platformio.exception import (InvalidEnvName, ProjectEnvsNotAvaialable, from platformio.exception import (InvalidEnvName, ProjectEnvsNotAvaialable,
UndefinedEnvPlatform, UnknownEnvNames) UndefinedEnvPlatform, UnknownEnvNames)
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
@ -56,6 +57,8 @@ def cli(environment, target, upload_port):
if not config.has_option(section, "platform"): if not config.has_option(section, "platform"):
raise UndefinedEnvPlatform(envname) raise UndefinedEnvPlatform(envname)
telemetry.on_run_environment(config.items(section), envtargets)
p = PlatformFactory().newPlatform(config.get(section, "platform")) p = PlatformFactory().newPlatform(config.get(section, "platform"))
result = p.run(variables, envtargets) result = p.run(variables, envtargets)
secho(result['out'], fg="green") secho(result['out'], fg="green")

View File

@ -4,19 +4,21 @@
from click import argument, command, echo, style from click import argument, command, echo, style
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
from platformio.util import get_platforms
@command("search", short_help="Search for development platforms") @command("search", short_help="Search for development platforms")
@argument("query") @argument("query", required=False)
def cli(query): def cli(query):
for platform in get_platforms(): for platform in PlatformFactory.get_platforms().keys():
p = PlatformFactory().newPlatform(platform) p = PlatformFactory().newPlatform(platform)
name = p.get_name() name = p.get_name()
shinfo = p.get_short_info() shinfo = p.get_short_info()
if query == "all":
query = ""
search_data = "%s %s" % (name, shinfo) search_data = "%s %s" % (name, shinfo)
if query != "all" and query.lower() not in search_data.lower(): if query and query.lower() not in search_data.lower():
continue continue
echo("{name:<20} - {info}".format(name=style(name, fg="cyan"), echo("{name:<20} - {info}".format(name=style(name, fg="cyan"),

View File

@ -0,0 +1,68 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import click
from platformio import app
@click.group(short_help="Manage PlatformIO settings")
def cli():
pass
@cli.command("get", short_help="Get existing setting/-s")
@click.argument("name", required=False)
def settings_get(name):
list_tpl = "{name:<40} {value:<35} {description}"
click.echo(list_tpl.format(
name=click.style("Name", fg="cyan"),
value=(click.style("Value", fg="green") +
click.style(" [Default]", fg="yellow")),
description="Description"
))
click.echo("-" * 90)
for _name, _data in sorted(app.DEFAULT_SETTINGS.items()):
if name and name != _name:
continue
_value = app.get_setting(_name)
_value_str = str(_value)
if isinstance(_value, bool):
_value_str = "Yes" if _value else "No"
_value_str = click.style(_value_str, fg="green")
if _value != _data['value']:
_defvalue_str = str(_data['value'])
if isinstance(_data['value'], bool):
_defvalue_str = "Yes" if _data['value'] else "No"
_value_str += click.style(" [%s]" % _defvalue_str, fg="yellow")
else:
_value_str += click.style(" ", fg="yellow")
click.echo(list_tpl.format(
name=click.style(_name, fg="cyan"),
value=_value_str,
description=_data['description']
))
@cli.command("set", short_help="Set new value for the setting")
@click.argument("name")
@click.argument("value")
@click.pass_context
def settings_set(ctx, name, value):
app.set_setting(name, value)
click.secho("The new value for the setting has been set!", fg="green")
ctx.invoke(settings_get, name=name)
@cli.command("reset", short_help="Reset settings to default")
@click.pass_context
def settings_reset(ctx):
app.reset_settings()
click.secho("The settings have been reseted!", fg="green")
ctx.invoke(settings_get)

View File

@ -1,7 +1,7 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os.path import join from datetime import datetime
from click import argument, command, echo, style from click import argument, command, echo, style
@ -13,20 +13,25 @@ from platformio.platforms.base import PlatformFactory
@command("show", short_help="Show details about installed platforms") @command("show", short_help="Show details about installed platforms")
@argument("platform") @argument("platform")
def cli(platform): def cli(platform):
p = PlatformFactory().newPlatform(platform)
if platform not in PackageManager.get_installed(): installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if platform not in installed_platforms:
raise PlatformNotInstalledYet(platform) raise PlatformNotInstalledYet(platform)
# print info about platform p = PlatformFactory().newPlatform(platform)
echo("{name:<20} - {info}".format(name=style(p.get_name(), fg="cyan"), echo("{name:<20} - {info}".format(name=style(p.get_name(), fg="cyan"),
info=p.get_short_info())) info=p.get_short_info()))
pm = PackageManager(platform) installed_packages = PackageManager.get_installed()
for name, data in pm.get_installed(platform).items(): for name in p.get_installed_packages():
data = installed_packages[name]
pkgalias = p.get_pkg_alias(name) pkgalias = p.get_pkg_alias(name)
echo("----------") echo("----------")
echo("Package: %s" % style(name, fg="yellow")) echo("Package: %s" % style(name, fg="yellow"))
if pkgalias: if pkgalias:
echo("Alias: %s" % pkgalias) echo("Alias: %s" % pkgalias)
echo("Location: %s" % join(pm.get_platform_dir(), data['path']))
echo("Version: %d" % int(data['version'])) echo("Version: %d" % int(data['version']))
echo("Installed: %s" % datetime.fromtimestamp(
data['time']).strftime("%Y-%m-%d %H:%M:%S"))

View File

@ -3,8 +3,6 @@
from click import argument, command, secho from click import argument, command, secho
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
@ -13,10 +11,6 @@ from platformio.platforms.base import PlatformFactory
def cli(platforms): def cli(platforms):
for platform in platforms: for platform in platforms:
if platform not in PackageManager.get_installed():
raise PlatformNotInstalledYet(platform)
p = PlatformFactory().newPlatform(platform) p = PlatformFactory().newPlatform(platform)
if p.uninstall(): if p.uninstall():
secho("The platform '%s' has been successfully " secho("The platform '%s' has been successfully "

View File

@ -3,14 +3,17 @@
from click import command, echo, style from click import command, echo, style
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
@command("update", short_help="Update installed platforms") @command("update", short_help="Update installed platforms")
def cli(): def cli():
for platform in PackageManager.get_installed().keys(): installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
for platform in installed_platforms:
echo("\nPlatform %s" % style(platform, fg="cyan")) echo("\nPlatform %s" % style(platform, fg="cyan"))
echo("--------") echo("--------")
p = PlatformFactory().newPlatform(platform) p = PlatformFactory().newPlatform(platform)

View File

@ -67,17 +67,17 @@ class FileDownloader(object):
dlsha1 = None dlsha1 = None
try: try:
res = check_output(["sha1sum", self._destination]) dlsha1 = check_output(["sha1sum", self._destination])
dlsha1 = res[:40]
except OSError: except OSError:
try: try:
res = check_output(["shasum", "-a", "1", self._destination]) dlsha1 = check_output(["shasum", "-a", "1", self._destination])
dlsha1 = res[:40]
except OSError: except OSError:
pass pass
if dlsha1 and sha1 != dlsha1: if dlsha1:
raise FDSHASumMismatch(dlsha1, self._fname, sha1) dlsha1 = dlsha1[1:41] if dlsha1.startswith("\\") else dlsha1[:40]
if sha1 != dlsha1:
raise FDSHASumMismatch(dlsha1, self._fname, sha1)
def _preserve_filemtime(self, lmdate): def _preserve_filemtime(self, lmdate):
timedata = parsedate_tz(lmdate) timedata = parsedate_tz(lmdate)

View File

@ -124,3 +124,23 @@ class LibNotInstalledError(PlatformioException):
class LibInstallDependencyError(PlatformioException): class LibInstallDependencyError(PlatformioException):
MESSAGE = "Error has been occurred for library dependency '%s'" MESSAGE = "Error has been occurred for library dependency '%s'"
class BuildScriptNotFound(PlatformioException):
MESSAGE = "Invalid path '%s' to build script"
class InvalidSettingName(PlatformioException):
MESSAGE = "Invalid setting with the name '%s'"
class InvalidSettingValue(PlatformioException):
MESSAGE = "Invalid value '%s' for the setting '%s'"
class UpgraderFailed(PlatformioException):
MESSAGE = "An error occurred while upgrading PlatformIO"

View File

@ -8,6 +8,7 @@ from os.path import isdir, isfile, join
from shutil import rmtree from shutil import rmtree
from tempfile import gettempdir from tempfile import gettempdir
from platformio import telemetry
from platformio.downloader import FileDownloader from platformio.downloader import FileDownloader
from platformio.exception import LibAlreadyInstalledError, LibNotInstalledError from platformio.exception import LibAlreadyInstalledError, LibNotInstalledError
from platformio.unpacker import FileUnpacker from platformio.unpacker import FileUnpacker
@ -44,6 +45,20 @@ class LibraryManager(object):
items[dirname] = json.load(f) items[dirname] = json.load(f)
return items return items
def get_latest_versions(self):
lib_ids = [str(item['id']) for item in self.get_installed().values()]
if not lib_ids:
return None
return get_api_result("/lib/version/" + str(",".join(lib_ids)))
def get_outdated(self):
outdated = []
for id_, latest_version in (self.get_latest_versions() or {}).items():
info = self.get_info(int(id_))
if latest_version != info['version']:
outdated.append(info['name'])
return outdated
def get_info(self, id_): def get_info(self, id_):
for item in self.get_installed().values(): for item in self.get_installed().values():
if "id" in item and item['id'] == id_: if "id" in item and item['id'] == id_:
@ -76,11 +91,21 @@ class LibraryManager(object):
info = self.get_info(id_) info = self.get_info(id_)
rename(tmplib_dir, join(self.lib_dir, "%s_ID%d" % ( rename(tmplib_dir, join(self.lib_dir, "%s_ID%d" % (
re.sub(r"[^\da-z]+", "_", info['name'], flags=re.I), id_))) re.sub(r"[^\da-z]+", "_", info['name'], flags=re.I), id_)))
telemetry.on_event(
category="LibraryManager", action="Install",
label="#%d %s" % (id_, info['name'])
)
return True return True
def uninstall(self, id_): def uninstall(self, id_):
for libdir, item in self.get_installed().iteritems(): for libdir, item in self.get_installed().iteritems():
if "id" in item and item['id'] == id_: if "id" in item and item['id'] == id_:
rmtree(join(self.lib_dir, libdir)) rmtree(join(self.lib_dir, libdir))
telemetry.on_event(
category="LibraryManager", action="Uninstall",
label="#%d %s" % (id_, item['name'])
)
return True return True
raise LibNotInstalledError(id_) raise LibNotInstalledError(id_)

187
platformio/maintenance.py Normal file
View File

@ -0,0 +1,187 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import re
from os import remove
from os.path import isdir, isfile, join
from shutil import rmtree
from time import time
import click
from platformio import __version__, app, telemetry
from platformio.commands.install import cli as cli_install
from platformio.commands.lib import lib_update as cli_libraries_update
from platformio.commands.update import cli as cli_platforms_update
from platformio.commands.upgrade import get_latest_version
from platformio.exception import UpgraderFailed
from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory
from platformio.util import get_home_dir, get_lib_dir
def on_platformio_start(ctx):
telemetry.on_command(ctx)
after_upgrade(ctx)
check_platformio_upgrade()
check_internal_updates(ctx, "platforms")
check_internal_updates(ctx, "libraries")
def on_platformio_end(ctx, result): # pylint: disable=W0613
pass
def on_platformio_exception(e):
telemetry.on_exception(e)
class Upgrader(object):
def __init__(self, from_version, to_version):
self.from_version = self.version_to_int(from_version)
self.to_version = self.version_to_int(to_version)
@staticmethod
def version_to_int(version):
return int(re.sub(r"[^\d]+", "", version))
def run(self, ctx):
if self.from_version > self.to_version:
return True
result = [True]
for v in (90, ):
if self.from_version >= v:
continue
result.append(getattr(self, "_upgrade_to_%d" % v)(ctx))
return all(result)
def _upgrade_to_90(self, ctx): # pylint: disable=R0201
prev_platforms = []
# remove platform's folder (obsoleted 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(cli_install, platforms=prev_platforms)
return True
def after_upgrade(ctx):
if app.get_state_item("last_version", None) == __version__:
return
# promotion
click.echo("\nIf you like %s, please:" % (
click.style("PlatformIO", fg="cyan")
))
click.echo(
"- %s us on Twitter to stay up-to-date "
"on the latest project news > %s" %
(click.style("follow", fg="cyan"),
click.style("https://twitter.com/platformiotool", fg="blue"))
)
click.echo("- %s us a star on GitHub > %s" % (
click.style("give", fg="cyan"),
click.style("https://github.com/ivankravets/platformio", fg="blue")
))
click.secho("Thanks a lot!\n", fg="green", blink=True)
if not isdir(get_home_dir()):
return
click.secho("Please wait while upgrading PlatformIO ...",
fg="yellow")
last_version = app.get_state_item("last_version", "0.0.0")
u = Upgrader(last_version, __version__)
if u.run(ctx):
app.set_state_item("last_version", __version__)
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 UpgraderFailed()
click.echo("")
def check_platformio_upgrade():
last_check = app.get_state_item("last_check", {})
interval = int(app.get_setting("check_platformio_interval")) * 3600 * 24
if (time() - interval) < last_check.get("platformio_upgrade", 0):
return
last_check['platformio_upgrade'] = int(time())
app.set_state_item("last_check", last_check)
latest_version = get_latest_version()
if (latest_version == __version__ or
Upgrader.version_to_int(latest_version) <
Upgrader.version_to_int(__version__)):
return
click.secho("There is a new version %s of PlatformIO available.\n"
"Please upgrade it via " % latest_version,
fg="yellow", nl=False)
click.secho("`platformio upgrade`", fg="cyan", nl=False)
click.secho(" command.\nChanges: ", fg="yellow", nl=False)
click.secho("http://docs.platformio.ikravets.com/en/latest/history.html\n",
fg="blue")
def check_internal_updates(ctx, what):
last_check = app.get_state_item("last_check", {})
interval = int(app.get_setting("check_%s_interval" % what)) * 3600 * 24
if (time() - interval) < last_check.get(what + "_update", 0):
return
last_check[what + '_update'] = int(time())
app.set_state_item("last_check", last_check)
outdated_items = []
if what == "platforms":
for platform in PlatformFactory.get_platforms(installed=True).keys():
p = PlatformFactory().newPlatform(platform)
if p.is_outdated():
outdated_items.append(platform)
elif what == "libraries":
lm = LibraryManager(get_lib_dir())
outdated_items = lm.get_outdated()
if not outdated_items:
return
click.secho("There are the new updates for %s (%s)" %
(what, ", ".join(outdated_items)), fg="yellow")
if not app.get_setting("auto_update_" + what):
click.secho("Please update them via ", fg="yellow", nl=False)
click.secho("`platformio %supdate`" %
("lib " if what == "libraries" else ""),
fg="cyan", nl=False)
click.secho(" command.\n", fg="yellow")
else:
click.secho("Please wait while updating %s ..." % what, fg="yellow")
if what == "platforms":
ctx.invoke(cli_platforms_update)
elif what == "libraries":
ctx.invoke(cli_libraries_update)
click.echo()
telemetry.on_event(category="Auto", action="Update",
label=what.title())

View File

@ -1,40 +1,37 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
import json
from os import makedirs, remove from os import makedirs, remove
from os.path import isdir, isfile, join from os.path import isdir, join
from shutil import rmtree from shutil import rmtree
from time import time
from click import echo, secho, style from click import echo, secho, style
from requests import get
from requests.utils import default_user_agent
from platformio import __pkgmanifesturl__, __version__ from platformio import telemetry
from platformio.app import get_state_item, set_state_item
from platformio.downloader import FileDownloader from platformio.downloader import FileDownloader
from platformio.exception import (InvalidPackageVersion, NonSystemPackage, from platformio.exception import (InvalidPackageVersion, NonSystemPackage,
UnknownPackage) UnknownPackage)
from platformio.unpacker import FileUnpacker from platformio.unpacker import FileUnpacker
from platformio.util import get_home_dir, get_systype from platformio.util import get_api_result, get_home_dir, get_systype
class PackageManager(object): class PackageManager(object):
DBFILE_PATH = join(get_home_dir(), "installed.json") def __init__(self):
self._package_dir = join(get_home_dir(), "packages")
if not isdir(self._package_dir):
makedirs(self._package_dir)
assert isdir(self._package_dir)
def __init__(self, platform_name): @classmethod
self._platform_name = platform_name def get_manifest(cls):
@staticmethod
def get_manifest():
try: try:
return PackageManager._cached_manifest return cls._cached_manifest
except AttributeError: except AttributeError:
headers = {"User-Agent": "PlatformIO/%s %s" % ( cls._cached_manifest = get_api_result("/packages")
__version__, default_user_agent())} return cls._cached_manifest
PackageManager._cached_manifest = get(__pkgmanifesturl__,
headers=headers).json()
return PackageManager._cached_manifest
@staticmethod @staticmethod
def download(url, dest_dir, sha1=None): def download(url, dest_dir, sha1=None):
@ -49,20 +46,18 @@ class PackageManager(object):
return fu.start() return fu.start()
@staticmethod @staticmethod
def get_installed(platform=None): def get_installed():
data = {} return get_state_item("installed_packages", {})
if isfile(PackageManager.DBFILE_PATH):
with open(PackageManager.DBFILE_PATH) as fp:
data = json.load(fp)
return data.get(platform, None) if platform else data
def get_platform_dir(self): def get_outdated(self):
return join(get_home_dir(), self._platform_name) outdated = []
for name, data in self.get_installed().items():
if data['version'] != self.get_info(name)['version']:
outdated.append(name)
return outdated
def is_installed(self, name): def is_installed(self, name):
installed = self.get_installed() return name in self.get_installed()
return (self._platform_name in installed and name in
installed[self._platform_name])
def get_info(self, name, version=None): def get_info(self, name, version=None):
manifest = self.get_manifest() manifest = self.get_manifest()
@ -84,35 +79,47 @@ class PackageManager(object):
else: else:
return sorted(builds, key=lambda s: s['version'])[-1] return sorted(builds, key=lambda s: s['version'])[-1]
def install(self, name, path): def install(self, name):
echo("Installing %s package:" % style(name, fg="cyan")) echo("Installing %s package:" % style(name, fg="cyan"))
if self.is_installed(name): if self.is_installed(name):
secho("Already installed", fg="yellow") secho("Already installed", fg="yellow")
return return False
info = self.get_info(name) info = self.get_info(name)
pkg_dir = join(self.get_platform_dir(), path) pkg_dir = join(self._package_dir, name)
if not isdir(pkg_dir): if not isdir(pkg_dir):
makedirs(pkg_dir) makedirs(pkg_dir)
dlpath = self.download(info['url'], pkg_dir, info['sha1']) dlpath = self.download(info['url'], pkg_dir, info['sha1'])
if self.unpack(dlpath, pkg_dir): if self.unpack(dlpath, pkg_dir):
self._register(name, info['version'], path) self._register(name, info['version'])
# remove archive # remove archive
remove(dlpath) remove(dlpath)
def uninstall(self, name, path): telemetry.on_event(
category="PackageManager", action="Install", label=name)
def uninstall(self, name):
echo("Uninstalling %s package: \t" % style(name, fg="cyan"), echo("Uninstalling %s package: \t" % style(name, fg="cyan"),
nl=False) nl=False)
rmtree(join(self.get_platform_dir(), path))
if not self.is_installed(name):
secho("Not installed", fg="yellow")
return False
rmtree(join(self._package_dir, name))
self._unregister(name) self._unregister(name)
echo("[%s]" % style("OK", fg="green")) echo("[%s]" % style("OK", fg="green"))
# report usage
telemetry.on_event(
category="PackageManager", action="Uninstall", label=name)
def update(self, name): def update(self, name):
echo("Updating %s package:" % style(name, fg="yellow")) echo("Updating %s package:" % style(name, fg="yellow"))
installed = self.get_installed(self._platform_name) installed = self.get_installed()
current_version = installed[name]['version'] current_version = installed[name]['version']
latest_version = self.get_info(name)['version'] latest_version = self.get_info(name)['version']
@ -125,36 +132,21 @@ class PackageManager(object):
else: else:
echo("[%s]" % (style("Out-of-date", fg="red"))) echo("[%s]" % (style("Out-of-date", fg="red")))
self.uninstall(name, installed[name]['path']) self.uninstall(name)
self.install(name, installed[name]['path']) self.install(name)
def register_platform(self, name): telemetry.on_event(
data = self.get_installed() category="PackageManager", action="Update", label=name)
if name not in data:
data[name] = {}
self._update_db(data)
return data
def unregister_platform(self, name): def _register(self, name, version):
data = self.get_installed() data = self.get_installed()
del data[name] data[name] = {
self._update_db(data)
def _register(self, name, version, path):
data = self.get_installed()
if self._platform_name not in data:
data = self.register_platform(self._platform_name)
data[self._platform_name][name] = {
"version": version, "version": version,
"path": path "time": int(time())
} }
self._update_db(data) set_state_item("installed_packages", data)
def _unregister(self, name): def _unregister(self, name):
data = self.get_installed() data = self.get_installed()
del data[self._platform_name][name] del data[name]
self._update_db(data) set_state_item("installed_packages", data)
def _update_db(self, data):
with open(self.DBFILE_PATH, "w") as fp:
json.dump(data, fp)

View File

@ -1,8 +1,6 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os.path import join
from platformio.platforms.base import BasePlatform from platformio.platforms.base import BasePlatform
@ -15,26 +13,21 @@ class AtmelavrPlatform(BasePlatform):
PACKAGES = { PACKAGES = {
"toolchain-atmelavr": { "toolchain-atmelavr": {
"path": join("tools", "toolchain"),
"alias": "toolchain", "alias": "toolchain",
"default": True "default": True
}, },
"tool-avrdude": { "tool-avrdude": {
"path": join("tools", "avrdude"),
"alias": "uploader", "alias": "uploader",
"default": True "default": True
}, },
"framework-arduinoavr": { "framework-arduinoavr": {
"path": join("frameworks", "arduino"), "alias": "framework",
"default": True "default": True
} }
} }
def get_name(self):
return "atmelavr"
def after_run(self, result): def after_run(self, result):
# fix STDERR "flash written" for avrdude # fix STDERR "flash written" for avrdude
if "flash written" in result['err']: if "flash written" in result['err']:

View File

@ -1,29 +1,76 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os.path import join from imp import load_source
from shutil import rmtree from os import listdir
from os.path import isdir, isfile, join
from platformio.exception import UnknownPackage, UnknownPlatform from platformio.app import get_state_item, set_state_item
from platformio.exception import (BuildScriptNotFound, PlatformNotInstalledYet,
UnknownPackage, UnknownPlatform)
from platformio.pkgmanager import PackageManager from platformio.pkgmanager import PackageManager
from platformio.util import exec_command, get_platforms, get_source_dir from platformio.util import exec_command, get_home_dir, get_source_dir
class PlatformFactory(object): class PlatformFactory(object):
@staticmethod @staticmethod
def newPlatform(name): def get_clsname(name):
clsname = "%sPlatform" % name.title() return "%sPlatform" % name.title()
@staticmethod
def load_module(name, path):
module = None
try: try:
assert name in get_platforms() module = load_source(
mod = __import__("platformio.platforms." + name.lower(), "platformio.platforms.%s" % name, path)
None, None, [clsname]) except ImportError:
except (AssertionError, ImportError): raise UnknownPlatform(name)
return module
@classmethod
def get_platforms(cls, installed=False):
platforms = {}
for d in (get_home_dir(), get_source_dir()):
pdir = join(d, "platforms")
if not isdir(pdir):
continue
for p in listdir(pdir):
if p in ("__init__.py", "base.py") or not p.endswith(".py"):
continue
name = p[:-3]
path = join(pdir, p)
try:
isplatform = hasattr(
cls.load_module(name, path),
cls.get_clsname(name)
)
if isplatform:
platforms[name] = path
except UnknownPlatform:
pass
if not installed:
return platforms
installed_platforms = {}
for name in get_state_item("installed_platforms", []):
if name in platforms:
installed_platforms[name] = platforms[name]
return installed_platforms
@classmethod
def newPlatform(cls, name):
platforms = cls.get_platforms()
if name not in platforms:
raise UnknownPlatform(name) raise UnknownPlatform(name)
obj = getattr(mod, clsname)() _instance = getattr(
assert isinstance(obj, BasePlatform) cls.load_module(name, platforms[name]),
return obj cls.get_clsname(name)
)()
assert isinstance(_instance, BasePlatform)
return _instance
class BasePlatform(object): class BasePlatform(object):
@ -31,6 +78,13 @@ class BasePlatform(object):
PACKAGES = {} PACKAGES = {}
def get_name(self): def get_name(self):
return self.__class__.__name__[:-8].lower()
def get_build_script(self):
builtin = join(get_source_dir(), "builder", "scripts", "%s.py" %
self.get_name())
if isfile(builtin):
return builtin
raise NotImplementedError() raise NotImplementedError()
def get_short_info(self): def get_short_info(self):
@ -40,6 +94,9 @@ class BasePlatform(object):
else: else:
raise NotImplementedError() raise NotImplementedError()
def get_packages(self):
return self.PACKAGES
def get_pkg_alias(self, pkgname): def get_pkg_alias(self, pkgname):
return self.PACKAGES[pkgname].get("alias", None) return self.PACKAGES[pkgname].get("alias", None)
@ -47,62 +104,116 @@ class BasePlatform(object):
names = [] names = []
for alias in aliases: for alias in aliases:
name = alias name = alias
# lookup by packages alias # lookup by package aliases
if name not in self.PACKAGES: for _name, _opts in self.get_packages().items():
for _name, _opts in self.PACKAGES.items(): if _opts.get("alias", None) == alias:
if _opts.get("alias", None) == alias: name = _name
name = _name break
break
names.append(name) names.append(name)
return names return names
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, without_packages, skip_default_packages): def install(self, with_packages, without_packages, skip_default_packages):
with_packages = set(self.pkg_aliases_to_names(with_packages)) with_packages = set(self.pkg_aliases_to_names(with_packages))
without_packages = set(self.pkg_aliases_to_names(without_packages)) without_packages = set(self.pkg_aliases_to_names(without_packages))
upkgs = with_packages | without_packages upkgs = with_packages | without_packages
ppkgs = set(self.PACKAGES.keys()) ppkgs = set(self.get_packages().keys())
if not upkgs.issubset(ppkgs): if not upkgs.issubset(ppkgs):
raise UnknownPackage(", ".join(upkgs - ppkgs)) raise UnknownPackage(", ".join(upkgs - ppkgs))
requirements = [] requirements = []
for name, opts in self.PACKAGES.items(): for name, opts in self.get_packages().items():
if name in without_packages: if name in without_packages:
continue continue
elif (name in with_packages or (not skip_default_packages and elif (name in with_packages or (not skip_default_packages and
opts['default'])): opts['default'])):
requirements.append((name, opts['path'])) requirements.append(name)
pm = PackageManager()
for name in requirements:
pm.install(name)
# register installed platform
data = get_state_item("installed_platforms", [])
if self.get_name() not in data:
data.append(self.get_name())
set_state_item("installed_platforms", data)
pm = PackageManager(self.get_name())
for (package, path) in requirements:
pm.install(package, path)
return len(requirements) return len(requirements)
def uninstall(self): def uninstall(self):
platform = self.get_name() platform = self.get_name()
pm = PackageManager(platform) installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
for package, data in pm.get_installed(platform).items(): if platform not in installed_platforms:
pm.uninstall(package, data['path']) raise 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)
pm.unregister_platform(platform)
rmtree(pm.get_platform_dir())
return True return True
def update(self): def update(self):
platform = self.get_name() pm = PackageManager()
pm = PackageManager(platform) for name in self.get_installed_packages():
for package in pm.get_installed(platform).keys(): pm.update(name)
pm.update(package)
def is_outdated(self):
pm = PackageManager()
obsolated = pm.get_outdated()
return not set(self.get_packages().keys()).isdisjoint(set(obsolated))
def run(self, variables, targets): def run(self, variables, targets):
assert isinstance(variables, list) assert isinstance(variables, list)
assert isinstance(targets, list) assert isinstance(targets, list)
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_packages = PackageManager.get_installed()
if self.get_name() not in installed_platforms:
raise PlatformNotInstalledYet(self.get_name())
if "clean" in targets: if "clean" in targets:
targets.remove("clean") targets.remove("clean")
targets.append("-c") targets.append("-c")
if not any([v.startswith("BUILD_SCRIPT=") for v in variables]):
variables.append("BUILD_SCRIPT=%s" % self.get_build_script())
for v in variables:
if not v.startswith("BUILD_SCRIPT="):
continue
_, path = v.split("=", 2)
if not isfile(path):
raise BuildScriptNotFound(path)
# append aliases of installed packages
for name, options in self.get_packages().items():
if name not in installed_packages:
continue
variables.append(
"PIOPACKAGE_%s=%s" % (options['alias'].upper(), name))
result = exec_command([ result = exec_command([
"scons", "scons",
"-Q", "-Q",

View File

@ -1,8 +1,6 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os.path import join
from platformio.platforms.base import BasePlatform from platformio.platforms.base import BasePlatform
@ -15,22 +13,17 @@ class Timsp430Platform(BasePlatform):
PACKAGES = { PACKAGES = {
"toolchain-timsp430": { "toolchain-timsp430": {
"path": join("tools", "toolchain"),
"alias": "toolchain", "alias": "toolchain",
"default": True "default": True
}, },
"tool-mspdebug": { "tool-mspdebug": {
"path": join("tools", "mspdebug"),
"alias": "uploader", "alias": "uploader",
"default": True "default": True
}, },
"framework-energiamsp430": { "framework-energiamsp430": {
"path": join("frameworks", "energia"), "alias": "framework",
"default": True "default": True
} }
} }
def get_name(self):
return "timsp430"

View File

@ -1,8 +1,6 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
from os.path import join
from platformio.platforms.base import BasePlatform from platformio.platforms.base import BasePlatform
@ -15,22 +13,17 @@ class TitivaPlatform(BasePlatform):
PACKAGES = { PACKAGES = {
"toolchain-gccarmnoneeabi": { "toolchain-gccarmnoneeabi": {
"path": join("tools", "toolchain"),
"alias": "toolchain", "alias": "toolchain",
"default": True "default": True
}, },
"tool-lm4flash": { "tool-lm4flash": {
"path": join("tools", "lm4flash"),
"alias": "uploader", "alias": "uploader",
"default": True "default": True
}, },
"framework-energiativa": { "framework-energiativa": {
"path": join("frameworks", "energia"), "alias": "framework",
"default": True "default": True
} }
} }
def get_name(self):
return "titiva"

View File

@ -1,6 +1,3 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
# #
# Project Configuration File # Project Configuration File
# #

202
platformio/telemetry.py Normal file
View File

@ -0,0 +1,202 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import platform
import re
import uuid
from sys import argv as sys_argv
from time import time
import click
import requests
from platformio import __version__, app
from platformio.util import exec_command, get_systype
class TelemetryBase(object):
MACHINE_ID = str(uuid.uuid5(uuid.NAMESPACE_OID, str(uuid.getnode())))
def __init__(self):
self._params = {}
def __getitem__(self, name):
return self._params.get(name, None)
def __setitem__(self, name, value):
self._params[name] = value
def __delitem__(self, name):
if name in self._params:
del self._params[name]
def send(self, hittype):
raise NotImplementedError()
class MeasurementProtocol(TelemetryBase):
TRACKING_ID = "UA-1768265-9"
PARAMS_MAP = {
"screen_name": "cd",
"event_category": "ec",
"event_action": "ea",
"event_label": "el",
"event_value": "ev"
}
def __init__(self):
TelemetryBase.__init__(self)
self['v'] = 1
self['tid'] = self.TRACKING_ID
self['cid'] = self.MACHINE_ID
self['sr'] = "%dx%d" % click.get_terminal_size()
self._prefill_screen_name()
self._prefill_appinfo()
self._prefill_custom_data()
@classmethod
def session_instance(cls):
try:
return cls._session_instance
except AttributeError:
cls._session_instance = requests.Session()
return cls._session_instance
def __getitem__(self, name):
if name in self.PARAMS_MAP:
name = self.PARAMS_MAP[name]
return TelemetryBase.__getitem__(self, name)
def __setitem__(self, name, value):
if name in self.PARAMS_MAP:
name = self.PARAMS_MAP[name]
TelemetryBase.__setitem__(self, name, value)
def _prefill_appinfo(self):
self['av'] = __version__
# gather dependent packages
dpdata = []
dpdata.append("Click/%s" % click.__version__)
# dpdata.append("Requests/%s" % requests.__version__)
try:
result = exec_command(["scons", "--version"])
match = re.search(r"engine: v([\d\.]+)", result['out'])
if match:
dpdata.append("SCons/%s" % match.group(1))
except: # pylint: disable=W0702
pass
self['an'] = " ".join(dpdata)
def _prefill_custom_data(self):
self['cd1'] = get_systype()
self['cd2'] = "Python/%s %s" % (platform.python_version(),
platform.platform())
def _prefill_screen_name(self):
args = [str(s).lower() for s in sys_argv[1:]]
if not args:
return
if args[0] in ("lib", "settings"):
cmd_path = args[:2]
else:
cmd_path = args[:1]
self['screen_name'] = " ".join([p.title() for p in cmd_path])
self['cd3'] = " ".join(args)
def send(self, hittype):
self['t'] = hittype
# correct queue time
if "qt" in self._params and isinstance(self['qt'], float):
self['qt'] = int((time() - self['qt']) * 1000)
try:
r = self.session_instance().post(
"https://ssl.google-analytics.com/collect",
data=self._params
)
r.raise_for_status()
except: # pylint: disable=W0702
backup_report(self._params)
return False
return True
def on_command(ctx): # pylint: disable=W0613
mp = MeasurementProtocol()
if mp.send("screenview"):
resend_backuped_reports()
def on_run_environment(options, targets):
opts = ["%s=%s" % (opt, value) for opt, value in sorted(options)]
targets = [t.title() for t in targets or ["run"]]
on_event("Env", " ".join(targets), " ".join(opts))
def on_event(category, action, label=None, value=None, screen_name=None):
mp = MeasurementProtocol()
mp['event_category'] = category[:150]
mp['event_action'] = action[:500]
if label:
mp['event_label'] = label[:500]
if value:
mp['event_value'] = int(value)
if screen_name:
mp['screen_name'] = screen_name[:2048]
return mp.send("event")
def on_exception(e):
mp = MeasurementProtocol()
mp['exd'] = "%s: %s" % (type(e).__name__, e)
mp['exf'] = 1
return mp.send("exception")
def backup_report(params):
KEEP_MAX_REPORTS = 1000
tm = app.get_state_item("telemetry", {})
if "backup" not in tm:
tm['backup'] = []
# skip static options
for key in params.keys():
if key in ("v", "tid", "cid", "cd1", "cd2", "sr", "an"):
del params[key]
# store time in UNIX format
if "qt" not in params:
params['qt'] = time()
elif not isinstance(params['qt'], float):
params['qt'] = time() - (params['qt'] / 1000)
tm['backup'].append(params)
tm['backup'] = tm['backup'][KEEP_MAX_REPORTS*-1:]
app.set_state_item("telemetry", tm)
def resend_backuped_reports():
MAX_RESEND_REPORTS = 10
resent_nums = 0
while resent_nums < MAX_RESEND_REPORTS:
tm = app.get_state_item("telemetry", {})
if "backup" not in tm or not tm['backup']:
break
report = tm['backup'].pop()
app.set_state_item("telemetry", tm)
resent_nums += 1
mp = MeasurementProtocol()
for key, value in report.items():
mp[key] = value
if not mp.send(report['t']):
break

View File

@ -2,15 +2,13 @@
# See LICENSE for details. # See LICENSE for details.
from os import name as os_name from os import name as os_name
from os import getcwd, getenv, listdir, utime from os import getcwd, getenv, makedirs, utime
from os.path import dirname, expanduser, isfile, join, realpath from os.path import dirname, expanduser, isdir, isfile, join, realpath
from platform import system, uname from platform import system, uname
from subprocess import PIPE, Popen from subprocess import PIPE, Popen
from time import sleep from time import sleep
from requests import get, post import requests
from requests.exceptions import ConnectionError, HTTPError
from requests.utils import default_user_agent
from serial import Serial from serial import Serial
from platformio import __apiurl__, __version__ from platformio import __apiurl__, __version__
@ -31,14 +29,24 @@ def get_systype():
def get_home_dir(): def get_home_dir():
home_dir = None
try: try:
config = get_project_config() config = get_project_config()
if (config.has_section("platformio") and if (config.has_section("platformio") and
config.has_option("platformio", "home_dir")): config.has_option("platformio", "home_dir")):
return config.get("platformio", "home_dir") home_dir = config.get("platformio", "home_dir")
except NotPlatformProject: except NotPlatformProject:
pass pass
return expanduser("~/.platformio")
if not home_dir:
home_dir = expanduser("~/.platformio")
if not isdir(home_dir):
makedirs(home_dir)
assert isdir(home_dir)
return home_dir
def get_lib_dir(): def get_lib_dir():
@ -77,15 +85,6 @@ def get_project_config():
return cp return cp
def get_platforms():
platforms = []
for p in listdir(join(get_source_dir(), "platforms")):
if p in ("__init__.py", "base.py") or not p.endswith(".py"):
continue
platforms.append(p[:-3])
return platforms
def change_filemtime(path, time): def change_filemtime(path, time):
utime(path, (time, time)) utime(path, (time, time))
@ -121,22 +120,29 @@ def get_serialports():
def get_api_result(path, params=None, data=None): def get_api_result(path, params=None, data=None):
result = None result = None
r = None r = None
try: try:
headers = {"User-Agent": "PlatformIO/%s %s" % ( headers = {"User-Agent": "PlatformIO/%s %s" % (
__version__, default_user_agent())} __version__, requests.utils.default_user_agent())}
if data: # if packages - redirect to SF
r = post(__apiurl__ + path, params=params, data=data, if path == "/packages":
headers=headers) r = requests.get(
"https://sourceforge.net/projects/platformio-storage/files/"
"packages/manifest.json/download",
params=params, headers=headers)
elif data:
r = requests.post(__apiurl__ + path, params=params, data=data,
headers=headers)
else: else:
r = get(__apiurl__ + path, params=params, headers=headers) r = requests.get(__apiurl__ + path, params=params, headers=headers)
result = r.json() result = r.json()
r.raise_for_status() r.raise_for_status()
except HTTPError as e: except requests.exceptions.HTTPError as e:
if result and "errors" in result: if result and "errors" in result:
raise APIRequestError(result['errors'][0]['title']) raise APIRequestError(result['errors'][0]['title'])
else: else:
raise APIRequestError(e) raise APIRequestError(e)
except ConnectionError: except requests.exceptions.ConnectionError:
raise APIRequestError( raise APIRequestError(
"Could not connect to PlatformIO Registry Service") "Could not connect to PlatformIO Registry Service")
except ValueError: except ValueError:

View File

@ -23,8 +23,8 @@ deps =
sphinx_rtd_theme sphinx_rtd_theme
commands = commands =
sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html sphinx-build -W -b html -d {envtmpdir}/doctrees docs docs/_build/html
sphinx-build -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex sphinx-build -W -b latex -d {envtmpdir}/doctrees docs docs/_build/latex
/bin/bash -c "if [[ $CI != \\"true\\" ]]; then sphinx-build -W -b linkcheck docs docs/_build/html; fi" /bin/bash -c "if [[ $CI != \\"true\\" ]]; then sphinx-build -W -b linkcheck docs docs/_build/html; fi"
[testenv:lint] [testenv:lint]
deps = deps =