Merge branch 'feature/platformio_20' into develop

This commit is contained in:
Ivan Kravets
2015-05-15 15:23:10 +02:00
67 changed files with 1957 additions and 502 deletions

View File

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

View File

@ -1,6 +1,42 @@
Release History Release History
=============== ===============
2.0.0 (2015-??-??)
------------------
* PlatformIO CLI 2.0: "platform" related commands have been
moved to ``platformio platforms`` subcommand
(`issue #158 <https://github.com/platformio/platformio/issues/158>`_)
* PlatformIO as Continuous Integration (CI) tool for embedded projects
(`issue #108 <https://github.com/platformio/platformio/issues/108>`_)
* Created `PlatformIO gitter.im <https://gitter.im/platformio/platformio>`_ room
(`issue #174 <https://github.com/platformio/platformio/issues/174>`_)
* Added global ``-f, --force`` option which will force to accept any
confirmation prompts (`issue #152 <https://github.com/platformio/platformio/issues/152>`_)
* Allowed to run project with `platformio run --project-dir <http://docs.platformio.org/en/latest/userguide/cmd_run.html#cmdoption--project-dir>`_ option without changing the current working
directory
(`issue #192 <https://github.com/platformio/platformio/issues/192>`_)
* Allowed to add library dependencies for build environment using
`install_libs <http://docs.platformio.org/en/latest/projectconf.html#install-libs>`_
option in ``platformio.ini``
(`issue #134 <https://github.com/platformio/platformio/issues/134>`_)
* Allowed to specify libraries which are compatible with build environment using
`use_libs <http://docs.platformio.org/en/latest/projectconf.html#use-libs>`_
option in ``platformio.ini``
(`issue #148 <https://github.com/platformio/platformio/issues/148>`_)
* Allowed to add more boards to PlatformIO project with
`platformio init --board <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--board>`__
command
(`issue #167 <https://github.com/platformio/platformio/issues/167>`_)
* Allowed to choose which library to update
(`issue #168 <https://github.com/platformio/platformio/issues/168>`_)
* Allowed to specify `platformio init --env-prefix <http://docs.platformio.org/en/latest/userguide/cmd_init.html#cmdoption--env-prefix>`__ when initialise/update project
(`issue #182 <https://github.com/platformio/platformio/issues/182>`_)
* Disabled automatic updates by default for platforms, packages and libraries
(`issue #171 <https://github.com/platformio/platformio/issues/171>`_)
* Fixed bug with creating copies of source files
(`issue #177 <https://github.com/platformio/platformio/issues/177>`_)
1.5.0 (2015-05-15) 1.5.0 (2015-05-15)
------------------ ------------------
@ -42,8 +78,9 @@ Release History
1.6.3 version (`issue #156 <https://github.com/platformio/platformio/issues/156>`_) 1.6.3 version (`issue #156 <https://github.com/platformio/platformio/issues/156>`_)
* Upgraded `Energia Framework <http://docs.platformio.org/en/latest/frameworks/energia.html>`__ to * Upgraded `Energia Framework <http://docs.platformio.org/en/latest/frameworks/energia.html>`__ to
0101E0015 version (`issue #146 <https://github.com/platformio/platformio/issues/146>`_) 0101E0015 version (`issue #146 <https://github.com/platformio/platformio/issues/146>`_)
* Upgraded `Arduino Framework with Teensy Core <http://docs.platformio.org/en/latest/frameworks/arduino.html>`_ to * Upgraded `Arduino Framework with Teensy Core <http://docs.platformio.org/en/latest/frameworks/arduino.html>`_
1.22 version (`issue #162 <https://github.com/platformio/platformio/issues/162>`_, to 1.22 version
(`issue #162 <https://github.com/platformio/platformio/issues/162>`_,
`issue #170 <https://github.com/platformio/platformio/issues/170>`_) `issue #170 <https://github.com/platformio/platformio/issues/170>`_)
* Fixed exceptions with PlatformIO auto-updates when Internet connection isn't * Fixed exceptions with PlatformIO auto-updates when Internet connection isn't
active active

View File

@ -134,3 +134,4 @@ The registration requirements:
Now, you can :ref:`register <cmd_lib_register>` your library and allow others Now, you can :ref:`register <cmd_lib_register>` your library and allow others
to :ref:`install <cmd_lib_install>` it. to :ref:`install <cmd_lib_install>` it.

View File

@ -294,9 +294,124 @@ Installation
1. Create ``platforms`` directory in :ref:`projectconf_pio_home_dir` if it 1. Create ``platforms`` directory in :ref:`projectconf_pio_home_dir` if it
doesn't exists. doesn't exists.
2. Copy ``test.py`` and ``test-builder.py`` files to ``platforms`` directory. 2. Copy ``test.py`` and ``test-builder.py`` files to ``platforms`` directory.
3. Search available platforms via :ref:`cmd_search` command. You should see 3. Search available platforms via :ref:`cmd_platforms_search` command. You should see
``test`` platform. ``test`` platform.
4. Install ``test`` platform via :ref:`cmd_install` command. 4. Install ``test`` platform via :ref:`cmd_platforms_install` command.
Now, you can use ``test`` for the :ref:`projectconf_env_platform` option in Now, you can use ``test`` for the :ref:`projectconf_env_platform` option in
:ref:`projectconf`. :ref:`projectconf`.
Example
-------
Let's use the real example which was requested by our user in `issue 175 <https://github.com/platformio/platformio/issues/175>`_. Need to add support for uploading firmware using GDB to
:ref:`platform_ststm32`.
First of all, need to create new folder ``platforms`` in :ref:`projectconf_pio_home_dir`
and copy there two files:
1. Platform manifest file ``ststm32gdb.py`` with the next content:
.. code-block:: python
import os
from platformio.platforms.ststm32 import Ststm32Platform
class Ststm32gdbPlatform(Ststm32Platform):
"""
ST STM32 using GDB as uploader
http://www.st.com/web/en/catalog/mmc/FM141/SC1169?sc=stm32
"""
def get_build_script(self):
return os.path.join(
os.path.dirname(os.path.realpath(__file__)),
"ststm32gdb-builder.py"
)
2. Build script file ``ststm32gdb-builder.py`` with the next content:
.. code-block:: python
"""
Builder for ST STM32 Series ARM microcontrollers with GDB upload.
"""
from os.path import join
from SCons.Script import (COMMAND_LINE_TARGETS, AlwaysBuild, Default,
DefaultEnvironment, SConscript)
env = DefaultEnvironment()
SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", "basearm.py")))
env.Replace(
UPLOADER=join(
"$PIOPACKAGES_DIR", "toolchain-gccarmnoneeabi",
"bin", "arm-none-eabi-gdb"
),
UPLOADERFLAGS=[
join("$BUILD_DIR", "firmware.elf"),
"-batch",
"-x", join("$PROJECT_DIR", "upload.gdb")
],
UPLOADCMD="$UPLOADER $UPLOADERFLAGS"
)
env.Append(
CPPDEFINES=[
"${BOARD_OPTIONS['build']['variant'].upper()}"
],
LINKFLAGS=[
"-nostartfiles",
"-nostdlib"
]
)
#
# Target: Build executable and linkable firmware
#
target_elf = env.BuildFirmware()
#
# Target: Build the .bin file
#
if "uploadlazy" in COMMAND_LINE_TARGETS:
target_firm = join("$BUILD_DIR", "firmware.bin")
else:
target_firm = env.ElfToBin(join("$BUILD_DIR", "firmware"), target_elf)
#
# Target: Print binary size
#
target_size = env.Alias("size", target_elf, "$SIZEPRINTCMD")
AlwaysBuild(target_size)
#
# Target: Upload by default .bin file
#
upload = env.Alias(
["upload", "uploadlazy"], target_firm, "$UPLOADCMD")
AlwaysBuild(upload)
#
# Target: Define targets
#
Default([target_firm, target_size])
Now, we should see ``ststm32gdb`` platform using :ref:`cmd_platforms_search` command output
and can install it via :ref:`platformio platforms install ststm32gdb <cmd_platforms_install>` command.

View File

@ -226,7 +226,7 @@ processes:
* - Format * - Format
- Scope - Scope
- Description - Description
* - ``Wp,option`` * - ``-Wp,option``
- CPPFLAGS - CPPFLAGS
- Bypass the compiler driver and pass *option* directly through to the - Bypass the compiler driver and pass *option* directly through to the
preprocessor preprocessor
@ -309,6 +309,35 @@ but will be applied only for the project source code from
This option can be overridden by global environment variable This option can be overridden by global environment variable
:ref:`envvar_PLATFORMIO_SRCBUILD_FLAGS`. :ref:`envvar_PLATFORMIO_SRCBUILD_FLAGS`.
``install_libs``
^^^^^^^^^^^^^^^^
Specify dependent libraries which should be installed before environment
process. The only library IDs are allowed. Multiple libraries can be passed
using comma ``,`` sign.
You can obtain library IDs using :ref:`cmd_lib_search` command.
Example:
.. code-block:: ini
[env:depends_on_some_libs]
install_libs = 1,13,19
``use_libs``
^^^^^^^^^^^^
Specify libraries which should be used by ``Library Dependency Finder`` with
the highest priority.
Example:
.. code-block:: ini
[env:libs_with_highest_priority]
use_libs = OneWire_ID1
``ignore_libs`` ``ignore_libs``
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^

130
docs/userguide/cmd_ci.rst Normal file
View File

@ -0,0 +1,130 @@
.. _cmd_ci:
platformio ci
=============
.. contents::
Usage
-----
.. code-block:: bash
platformio ci [OPTIONS] [SRC]
Description
-----------
`Continuous integration (CI, wiki) <http://en.wikipedia.org/wiki/Continuous_integration>`_
is the practice, in software engineering, of merging all developer working
copies with a shared mainline several times a day.
:ref:`cmd_ci` command is conceived of as "hot key" for building project with
arbitrary source code structure. In a nutshell, using ``SRC`` and
:option:`platformio ci --lib` contents PlatformIO initialises via
:ref:`cmd_init` new project in :option:`platformio ci --build-dir`
with the build environments (using :option:`platformio ci --board` or
:option:`platformio ci --project-conf`) and processes them via :ref:`cmd_run`
command.
:ref:`cmd_ci` command is intended to be used in combination with the build
servers and the popular
`Continuous Integration Software <http://en.wikipedia.org/wiki/Comparison_of_continuous_integration_software>`_.
By integrating regularly, you can detect errors quickly, and locate them more
easily.
.. note::
:ref:`cmd_ci` command accepts **multiple** ``SRC`` arguments,
:option:`platformio ci --lib` and :option:`platformio ci --exclude` options
which can be a path to directory, file or
`Glob Pattern <http://en.wikipedia.org/wiki/Glob_(programming)>`_.
.. note::
You can omit ``SRC`` argument and set path (multiple paths are allowed
denoting with ``:``) to
``PLATFORMIO_CI_SRC`` `Environment variable <http://en.wikipedia.org/wiki/Environment_variable>`_
Options
-------
.. program:: platformio ci
.. option::
--lib, -l
Source code which will be copied to ``%build_dir%/lib`` directly.
If :option:`platformio ci --lib` is a path to file (not to directory), then
PlatformIO will create temporary directory within ``%build_dir%/lib`` and copy
the rest files into it.
.. option::
--exclude
Exclude directories and/-or files from :option:`platformio ci --build-dir`. The
path must be relative to PlatformIO project within
:option:`platformio ci --build-dir`.
For example, exclude from project ``src`` directory:
* ``examples`` folder
* ``*.h`` files from ``foo`` folder
.. code-block:: bash
platformio ci --exclude=src/examples --exclude=src/foo/*.h [SRC]
.. option::
--board, -b
Build project with automatically pre-generated environments based on board
settings.
For more details please look into :option:`platformio init --board`.
.. option::
--build-dir
Path to directory where PlatformIO will initialise new project. By default it's
temporary directory within your operation system.
.. note::
This directory will be removed at the end of build process. If you want to
keep it, please use :option:`platformio ci --keep-build-dir`.
.. option::
--keep-build-dir
Don't remove :option:`platformio ci --build-dir` after build process.
.. option::
--project-conf
Buid project using pre-configured :ref:`projectconf`.
Examples
--------
1. Integration `Travis.CI <http://travis-ci.org/>`_ for GitHub
`USB_Host_Shield_2.0 <https://github.com/felis/USB_Host_Shield_2.0>`_
project. The ``.travis.yml`` configuration file:
.. code-block:: yaml
language: python
python:
- "2.7"
env:
- PLATFORMIO_CI_SRC=examples/Bluetooth/PS3SPP/PS3SPP.ino
- PLATFORMIO_CI_SRC=examples/pl2303/pl2303_gps/pl2303_gps.ino
install:
- python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)"
script:
- platformio ci --lib="." --board=uno --board=teensy31 --board=due

View File

@ -29,6 +29,8 @@ This command will create:
Options Options
------- -------
.. program:: platformio init
.. option:: .. option::
--project-dir, -d --project-dir, -d
@ -50,10 +52,20 @@ The full list with pre-configured boards is available here :ref:`platforms`.
.. option:: .. option::
--disable-auto-uploading --disable-auto-uploading
If you initialise project with the specified ``--board``, then *PlatformIO* If you initialise project with the specified
:option:`platformio init --board``, then *PlatformIO*
will create environment with enabled firmware auto-uploading. This option will create environment with enabled firmware auto-uploading. This option
allows you to disable firmware auto-uploading by default. allows you to disable firmware auto-uploading by default.
.. option::
--env-prefix
An environment prefix which will be used with pair in board type.
For example, the default environment name for ``teensy_31`` board will
be ``[env:teensy_31]``.
Examples Examples
-------- --------

View File

@ -22,6 +22,8 @@ Process environments which are defined in :ref:`projectconf` file
Options Options
------- -------
.. program:: platformio run
.. option:: .. option::
-e, --environment -e, --environment
@ -39,6 +41,12 @@ Process specified targets
Upload port of embedded board. To print all available ports use Upload port of embedded board. To print all available ports use
:ref:`cmd_serialports` command :ref:`cmd_serialports` command
.. option::
--build-dir
Specify the path to project directory. By default, ``--build-dir`` is equal to
current working directory (``CWD``).
Examples Examples
-------- --------

View File

@ -24,6 +24,8 @@ List available `Serial Ports <http://en.wikipedia.org/wiki/Serial_port>`_
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio serialports list
.. option:: .. option::
--json-output --json-output
@ -99,6 +101,8 @@ To control *monitor* please use these "hot keys":
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio serialports monitor
.. option:: .. option::
-p, --port -p, --port

View File

@ -16,7 +16,8 @@ Usage
Description Description
----------- -----------
Check or update installed :ref:`Platforms <platforms>` Check or update installed :ref:`Platforms <platforms>` and
:ref:`Libraries <librarymanager>`
Examples Examples

View File

@ -3,7 +3,35 @@
User Guide User Guide
========== ==========
To print all available commands and options use: .. contents::
Usage
-----
.. code-block:: bash
platformio [OPTIONS] COMMAND
Options
-------
.. program:: platformio
.. option::
--force, - f
Force to accept any confirmation prompts. This option allows to avoid an issue
with :ref:`faq_troubleshooting_pioblocksprompt`
.. option::
--version
Show the version of PlatformIO
.. option::
--help
Show help for the available options and commands
.. code-block:: bash .. code-block:: bash
@ -11,19 +39,19 @@ To print all available commands and options use:
$ platformio COMMAND --help $ platformio COMMAND --help
Commands
--------
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
cmd_boards cmd_boards
cmd_ci
cmd_init cmd_init
cmd_install
platformio lib <lib/index> platformio lib <lib/index>
cmd_list platformio platforms <platforms/index>
cmd_run cmd_run
cmd_search
cmd_serialports cmd_serialports
cmd_settings cmd_settings
cmd_show
cmd_uninstall
cmd_update cmd_update
cmd_upgrade cmd_upgrade

View File

@ -22,6 +22,8 @@ Install new library by specified
Options Options
------- -------
.. program:: platformio lib install
.. option:: .. option::
-v, --version -v, --version

View File

@ -21,6 +21,8 @@ List installed libraries
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio lib list
.. option:: .. option::
--json-output --json-output

View File

@ -61,6 +61,8 @@ For more detail information please go to
Options Options
------- -------
.. program:: platformio lib search
.. option:: .. option::
-a, --author -a, --author

View File

@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio lib update platformio lib update [LIBRARY_ID]
Description Description
@ -22,6 +22,8 @@ Check or update installed libraries
Examples Examples
-------- --------
1. Update all installed libraries
.. code-block:: bash .. code-block:: bash
$ platformio lib update $ platformio lib update
@ -36,8 +38,23 @@ Examples
# 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]
2. Update specified libraries
.. code-block:: bash
$ platformio lib update 1 59
# Updating [ 1 ] OneWire library:
# Versions: Current=2.2, Latest=2.2 [Up-to-date]
# Updating [ 59 ] USB-Host-Shield-20 library:
# Versions: Current=fcab83dcb3, Latest=c61f9ce1c2 [Out-of-date]
# The library #59 'USB-Host-Shield-20' has been successfully uninstalled!
# Installing library [ 59 ]:
# Downloading [####################################] 100%
# Unpacking [####################################] 100%
# The library #59 'USB-Host-Shield-20' has been successfully installed!

View File

@ -1,7 +1,7 @@
.. _cmd_install: .. _cmd_platforms_install:
platformio install platformio platforms install
================== ============================
.. contents:: .. contents::
@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio install [OPTIONS] [PLATFORMS] platformio platforms install [OPTIONS] [PLATFORMS]
Description Description
@ -27,6 +27,8 @@ There are several predefined aliases for packages, such as:
Options Options
------- -------
.. program:: platformio platforms install
.. option:: .. option::
--with-package --with-package
@ -50,7 +52,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio install timsp430 $ platformio platforms install timsp430
Installing toolchain-timsp430 package: Installing toolchain-timsp430 package:
Downloading [####################################] 100% Downloading [####################################] 100%
Unpacking [####################################] 100% Unpacking [####################################] 100%
@ -68,7 +70,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio install timsp430 --skip-default-package --with-package=uploader $ platformio platforms install timsp430 --skip-default-package --with-package=uploader
Installing tool-mspdebug package: Installing tool-mspdebug package:
Downloading [####################################] 100% Downloading [####################################] 100%
Unpacking [####################################] 100% Unpacking [####################################] 100%

View File

@ -1,7 +1,7 @@
.. _cmd_list: .. _cmd_platforms_list:
platformio list platformio platforms list
=============== =========================
.. contents:: .. contents::
@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio list [OPTIONS] platformio platforms list [OPTIONS]
Description Description
@ -21,6 +21,8 @@ List installed :ref:`Platforms <platforms>`
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio platforms list
.. option:: .. option::
--json-output --json-output
@ -31,7 +33,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio list $ platformio platforms list
atmelavr with packages: toolchain-atmelavr, tool-avrdude, framework-arduinoavr, tool-micronucleus atmelavr with packages: toolchain-atmelavr, tool-avrdude, framework-arduinoavr, tool-micronucleus
atmelsam with packages: framework-arduinosam, ldscripts, toolchain-gccarmnoneeabi, tool-bossac atmelsam with packages: framework-arduinosam, ldscripts, toolchain-gccarmnoneeabi, tool-bossac
freescalekinetis with packages: framework-mbed, toolchain-gccarmnoneeabi freescalekinetis with packages: framework-mbed, toolchain-gccarmnoneeabi

View File

@ -1,7 +1,7 @@
.. _cmd_search: .. _cmd_platforms_search:
platformio search platformio platforms search
================= ===========================
.. contents:: .. contents::
@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio search QUERY [OPTIONS] platformio platforms search QUERY [OPTIONS]
Description Description
@ -21,6 +21,8 @@ Search for development :ref:`Platforms <platforms>`
Options Options
~~~~~~~ ~~~~~~~
.. program:: platformio platforms search
.. option:: .. option::
--json-output --json-output
@ -34,7 +36,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio search $ platformio platforms search
atmelavr (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) atmelavr (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-------- --------
Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance... Atmel AVR 8- and 32-bit MCUs deliver a unique combination of performance...
@ -75,7 +77,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio search ti $ platformio platforms search ti
timsp430 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) timsp430 (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
-------- --------
MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are ... MSP430 microcontrollers (MCUs) from Texas Instruments (TI) are ...
@ -88,7 +90,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio search mbed $ platformio platforms search mbed
freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa) freescalekinetis (available packages: ldscripts, toolchain-gccarmnoneeabi, tool-lm4flash, framework-opencm3, framework-energiativa)
---------------- ----------------
Freescale Kinetis Microcontrollers is family of multiple hardware- and ... Freescale Kinetis Microcontrollers is family of multiple hardware- and ...

View File

@ -1,7 +1,7 @@
.. _cmd_show: .. _cmd_platforms_show:
platformio show platformio platforms show
=============== =========================
.. contents:: .. contents::
@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio show PLATFORM platformio platforms show PLATFORM
Description Description
@ -24,7 +24,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio show atmelavr $ platformio platforms show atmelavr
atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework) atmelavr - An embedded platform for Atmel AVR microcontrollers (with Arduino Framework)
---------- ----------
Package: toolchain-atmelavr Package: toolchain-atmelavr

View File

@ -1,7 +1,7 @@
.. _cmd_uninstall: .. _cmd_platforms_uninstall:
platformio uninstall platformio platforms uninstall
==================== ==============================
.. contents:: .. contents::
@ -10,7 +10,7 @@ Usage
.. code-block:: bash .. code-block:: bash
platformio uninstall PLATFORM platformio platforms uninstall PLATFORM
Description Description
@ -24,7 +24,7 @@ Examples
.. code-block:: bash .. code-block:: bash
$ platformio uninstall timsp430 $ platformio platforms uninstall timsp430
Uninstalling toolchain-timsp430 package: [OK] Uninstalling toolchain-timsp430 package: [OK]
Uninstalling tool-mspdebug package: [OK] Uninstalling tool-mspdebug package: [OK]
Uninstalling framework-energiamsp430 package: [OK] Uninstalling framework-energiamsp430 package: [OK]

View File

@ -0,0 +1,99 @@
.. _cmd_platforms_update:
platformio platforms update
===========================
.. contents::
Usage
-----
.. code-block:: bash
platformio platforms update
Description
-----------
Check or update installed :ref:`Platforms <platforms>`
Examples
--------
.. code-block:: bash
$ platformio platforms update
Platform atmelavr
--------
Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-avrdude package:
Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-arduinoavr package:
Versions: Current=12, Latest=12 [Up-to-date]
Updating tool-micronucleus package:
Versions: Current=1, Latest=1 [Up-to-date]
Platform atmelsam
--------
Updating framework-arduinosam package:
Versions: Current=3, Latest=3 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-bossac package:
Versions: Current=1, Latest=1 [Up-to-date]
Platform stm32
--------
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-stlink package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-spl package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-cmsis package:
Versions: Current=2, Latest=2 [Up-to-date]
Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Platform teensy
--------
Updating toolchain-atmelavr package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-arduinoteensy package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-teensy package:
Versions: Current=1, Latest=1 [Up-to-date]
Platform timsp430
--------
Updating toolchain-timsp430 package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-mspdebug package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiamsp430 package:
Versions: Current=2, Latest=2 [Up-to-date]
Platform titiva
--------
Updating ldscripts package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating toolchain-gccarmnoneeabi package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating tool-lm4flash package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-opencm3 package:
Versions: Current=1, Latest=1 [Up-to-date]
Updating framework-energiativa package:
Versions: Current=4, Latest=4 [Up-to-date]

View File

@ -0,0 +1,22 @@
.. _userguide_platforms:
Platforms Manager
=================
To print all available commands and options use:
.. code-block:: bash
$ platformio platforms --help
$ platformio platforms COMMAND --help
.. toctree::
:maxdepth: 2
cmd_install
cmd_list
cmd_search
cmd_show
cmd_uninstall
cmd_update

View File

@ -5,22 +5,22 @@
; http://docs.platformio.org/en/latest/projectconf.html ; http://docs.platformio.org/en/latest/projectconf.html
; ;
[env:autogen_uno] [env:uno]
platform = atmelavr platform = atmelavr
framework = arduino framework = arduino
board = uno board = uno
[env:autogen_teensy31] [env:teensy31]
platform = teensy platform = teensy
framework = arduino framework = arduino
board = teensy31 board = teensy31
[env:autogen_lpmsp430g2553] [env:lpmsp430g2553]
platform = timsp430 platform = timsp430
framework = energia framework = energia
board = lpmsp430g2553 board = lpmsp430g2553
[env:autogen_lptm4c1230c3pm] [env:lptm4c1230c3pm]
platform = titiva platform = titiva
framework = energia framework = energia
board = lptm4c1230c3pm board = lptm4c1230c3pm

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.
VERSION = (1, 5, 0) VERSION = (2, 0, "0a1")
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"

View File

@ -31,20 +31,38 @@ class PlatformioCLI(click.MultiCommand): # pylint: disable=R0904
mod = __import__("platformio.commands." + name, mod = __import__("platformio.commands." + name,
None, None, ["cli"]) None, None, ["cli"])
except ImportError: except ImportError:
raise exception.UnknownCLICommand(name) try:
return self._handle_obsolate_command(name)
except AttributeError:
raise exception.UnknownCLICommand(name)
return mod.cli return mod.cli
@staticmethod
def _handle_obsolate_command(name):
if name in ("install", "list", "search", "show", "uninstall"):
click.secho(
"Warning! `platformio %s` command is obsoleted and will be "
"removed in the next release! Please use "
"`platformio platforms %s` instead." % (name, name),
fg="red"
)
from platformio.commands import platforms
return getattr(platforms, "platforms_" + name)
raise AttributeError()
@click.command(cls=PlatformioCLI) @click.command(cls=PlatformioCLI)
@click.version_option(__version__, prog_name="PlatformIO") @click.version_option(__version__, prog_name="PlatformIO")
@click.option("--force", "-f", is_flag=True,
help="Force to accept any confirmation prompts")
@click.pass_context @click.pass_context
def cli(ctx): def cli(ctx, force):
maintenance.on_platformio_start(ctx) maintenance.on_platformio_start(ctx, force)
@cli.resultcallback() @cli.resultcallback()
@click.pass_context @click.pass_context
def process_result(ctx, result): def process_result(ctx, result, force): # pylint: disable=W0613
maintenance.on_platformio_end(ctx, result) maintenance.on_platformio_end(ctx, result)
@ -54,7 +72,7 @@ def main():
# /en/latest/security.html#insecureplatformwarning # /en/latest/security.html#insecureplatformwarning
requests.packages.urllib3.disable_warnings() requests.packages.urllib3.disable_warnings()
cli(None) cli(None, None)
except Exception as e: # pylint: disable=W0703 except Exception as e: # pylint: disable=W0703
if not isinstance(e, exception.ReturnErrorCode): if not isinstance(e, exception.ReturnErrorCode):
maintenance.on_platformio_exception(e) maintenance.on_platformio_exception(e)

View File

@ -24,11 +24,11 @@ DEFAULT_SETTINGS = {
}, },
"auto_update_platforms": { "auto_update_platforms": {
"description": "Automatically update platforms (Yes/No)", "description": "Automatically update platforms (Yes/No)",
"value": True "value": False
}, },
"auto_update_libraries": { "auto_update_libraries": {
"description": "Automatically update libraries (Yes/No)", "description": "Automatically update libraries (Yes/No)",
"value": True "value": False
}, },
"enable_telemetry": { "enable_telemetry": {
"description": ("Shares commands, platforms and libraries usage" "description": ("Shares commands, platforms and libraries usage"
@ -47,6 +47,11 @@ DEFAULT_SETTINGS = {
} }
SESSION_VARS = {
"force_option": False
}
class State(object): class State(object):
def __init__(self, path=None): def __init__(self, path=None):
@ -101,9 +106,12 @@ def set_state_item(name, value):
def get_setting(name): def get_setting(name):
# disable prompts for Continuous Integration systems if name == "enable_prompts":
if name == "enable_prompts" and getenv("CI", "").lower() == "true": # disable prompts for Continuous Integration systems
return False # and when global "--force" option is set
if any([getenv("CI", "").lower() == "true",
get_session_var("force_option")]):
return False
_env_name = "PLATFORMIO_SETTING_%s" % name.upper() _env_name = "PLATFORMIO_SETTING_%s" % name.upper()
if _env_name in environ: if _env_name in environ:
@ -127,3 +135,12 @@ def reset_settings():
with State() as data: with State() as data:
if "settings" in data: if "settings" in data:
del data['settings'] del data['settings']
def get_session_var(name, default=None):
return SESSION_VARS.get(name, default)
def set_session_var(name, value):
assert name in SESSION_VARS
SESSION_VARS[name] = value

View File

@ -37,6 +37,7 @@ commonvars.AddVariables(
("BUILD_FLAGS",), ("BUILD_FLAGS",),
("SRCBUILD_FLAGS",), ("SRCBUILD_FLAGS",),
("IGNORE_LIBS",), ("IGNORE_LIBS",),
("USE_LIBS",),
# board options # board options
("BOARD",), ("BOARD",),

View File

@ -6,7 +6,8 @@ import re
from os import getenv, listdir, remove, sep, walk from os import getenv, listdir, remove, sep, walk
from os.path import basename, dirname, isdir, isfile, join, normpath from os.path import basename, dirname, isdir, isfile, join, normpath
from SCons.Script import Exit, SConscript, SConscriptChdir from SCons.Script import (COMMAND_LINE_TARGETS, Exit, SConscript,
SConscriptChdir)
from SCons.Util import case_sensitive_suffixes from SCons.Util import case_sensitive_suffixes
from platformio.util import pioversion_to_intstr from platformio.util import pioversion_to_intstr
@ -26,7 +27,7 @@ def BuildFirmware(env):
firmenv = env.Clone() firmenv = env.Clone()
vdirs = firmenv.VariantDirRecursive( vdirs = firmenv.VariantDirRecursive(
join("$BUILD_DIR", "src"), "$PROJECTSRC_DIR") join("$BUILD_DIR", "src"), "$PROJECTSRC_DIR", duplicate=False)
# build dependent libs # build dependent libs
deplibs = firmenv.BuildDependentLibraries("$PROJECTSRC_DIR") deplibs = firmenv.BuildDependentLibraries("$PROJECTSRC_DIR")
@ -55,6 +56,10 @@ def BuildFirmware(env):
*pioversion_to_intstr())] *pioversion_to_intstr())]
) )
if "envdump" in COMMAND_LINE_TARGETS:
print env.Dump()
Exit()
return firmenv.Program( return firmenv.Program(
join("$BUILD_DIR", "firmware"), join("$BUILD_DIR", "firmware"),
[firmenv.GlobCXXFiles(vdir) for vdir in vdirs], [firmenv.GlobCXXFiles(vdir) for vdir in vdirs],
@ -142,9 +147,11 @@ def BuildLibrary(env, variant_dir, library_dir, ignore_files=None):
def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914 def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914
INCLUDES_RE = re.compile(r"^\s*#include\s+(\<|\")([^\>\"\']+)(?:\>|\")", INCLUDES_RE = re.compile(
re.M) r"^\s*#include\s+(\<|\")([^\>\"\']+)(?:\>|\")", re.M)
LIBSOURCE_DIRS = [env.subst(d) for d in env.get("LIBSOURCE_DIRS", [])] LIBSOURCE_DIRS = [env.subst(d) for d in env.get("LIBSOURCE_DIRS", [])]
USE_LIBS = [l.strip() for l in env.get("USE_LIBS", "").split(",")
if l.strip()]
# start internal prototypes # start internal prototypes
@ -185,7 +192,10 @@ def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914
if not isdir(lsd_dir): if not isdir(lsd_dir):
continue continue
for ld in listdir(lsd_dir): for ld in USE_LIBS + listdir(lsd_dir):
if not isdir(join(lsd_dir, ld)):
continue
inc_path = normpath(join(lsd_dir, ld, self.name)) inc_path = normpath(join(lsd_dir, ld, self.name))
try: try:
lib_dir = inc_path[:inc_path.index( lib_dir = inc_path[:inc_path.index(
@ -216,6 +226,7 @@ def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914
"libs": set(), "libs": set(),
"ordered": set() "ordered": set()
} }
state = _process_src_dir(state, env.subst(src_dir)) state = _process_src_dir(state, env.subst(src_dir))
result = [] result = []
@ -371,7 +382,7 @@ def ConvertInoToCpp(env):
if not data: if not data:
return return
tmpcpp_file = join(env.subst("$PROJECTSRC_DIR"), "piomain.cpp") tmpcpp_file = join(env.subst("$PROJECTSRC_DIR"), "tmp_ino_to.cpp")
with open(tmpcpp_file, "w") as f: with open(tmpcpp_file, "w") as f:
f.write(data) f.write(data)

View File

@ -18,6 +18,7 @@ def cli(query, json_output): # pylint: disable=R0912
BOARDLIST_TPL = ("{type:<30} {mcu:<14} {frequency:<8} " BOARDLIST_TPL = ("{type:<30} {mcu:<14} {frequency:<8} "
" {flash:<7} {ram:<6} {name}") " {flash:<7} {ram:<6} {name}")
terminal_width, _ = click.get_terminal_size()
grpboards = {} grpboards = {}
for type_, data in get_boards().items(): for type_, data in get_boards().items():
@ -31,12 +32,14 @@ def cli(query, json_output): # pylint: disable=R0912
if query.lower() not in search_data.lower(): if query.lower() not in search_data.lower():
continue continue
click.echo("\nPlatform: %s" % platform) click.echo("")
click.echo("-" * 75) click.echo("Platform: ", nl=False)
click.secho(platform, bold=True)
click.echo("-" * terminal_width)
click.echo(BOARDLIST_TPL.format( click.echo(BOARDLIST_TPL.format(
type=click.style("Type", fg="cyan"), mcu="MCU", type=click.style("Type", fg="cyan"), mcu="MCU",
frequency="Frequency", flash="Flash", ram="RAM", name="Name")) frequency="Frequency", flash="Flash", ram="RAM", name="Name"))
click.echo("-" * 75) click.echo("-" * terminal_width)
for type_, data in sorted(boards.items(), key=lambda b: b[1]['name']): for type_, data in sorted(boards.items(), key=lambda b: b[1]['name']):
if query: if query:

141
platformio/commands/ci.py Normal file
View File

@ -0,0 +1,141 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from glob import glob
from os import environ, makedirs, remove
from os.path import abspath, basename, isdir, isfile, join
from shutil import copyfile, copytree, rmtree
from tempfile import mkdtemp
import click
from platformio import app
from platformio.commands.init import cli as cmd_init
from platformio.commands.run import cli as cmd_run
from platformio.exception import CIBuildEnvsEmpty
from platformio.util import get_boards
def validate_path(ctx, param, value): # pylint: disable=W0613
invalid_path = None
for p in value:
if not glob(p):
invalid_path = p
break
try:
assert invalid_path is None
return value
except AssertionError:
raise click.BadParameter("Found invalid path: %s" % invalid_path)
def validate_boards(ctx, param, value): # pylint: disable=W0613
unknown_boards = set(value) - set(get_boards().keys())
try:
assert not unknown_boards
return value
except AssertionError:
raise click.BadParameter(
"%s. Please search for the board types using "
"`platformio boards` command" % ", ".join(unknown_boards))
@click.command("ci", short_help="Continuous Integration")
@click.argument("src", nargs=-1, callback=validate_path)
@click.option("--lib", "-l", multiple=True, callback=validate_path)
@click.option("--exclude", multiple=True)
@click.option("--board", "-b", multiple=True, callback=validate_boards)
@click.option("--build-dir", default=mkdtemp,
type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True))
@click.option("--keep-build-dir", is_flag=True)
@click.option("--project-conf",
type=click.Path(exists=True, file_okay=True, dir_okay=False,
readable=True, resolve_path=True))
@click.pass_context
def cli(ctx, src, lib, exclude, board, # pylint: disable=R0913
build_dir, keep_build_dir, project_conf):
if not src:
src = environ.get("PLATFORMIO_CI_SRC", "").split(":")
if not src:
raise click.BadParameter("Missing argument 'src'")
try:
app.set_session_var("force_option", True)
_clean_dir(build_dir)
for dir_name, patterns in dict(lib=lib, src=src).iteritems():
if not patterns:
continue
contents = []
for p in patterns:
contents += glob(p)
_copy_contents(join(build_dir, dir_name), contents)
if project_conf and isfile(project_conf):
copyfile(project_conf, join(build_dir, "platformio.ini"))
elif not board:
raise CIBuildEnvsEmpty()
if exclude:
_exclude_contents(build_dir, exclude)
# initialise project
ctx.invoke(cmd_init, project_dir=build_dir, board=board,
disable_auto_uploading=True)
# process project
ctx.invoke(cmd_run, project_dir=build_dir)
finally:
if not keep_build_dir:
rmtree(build_dir)
def _clean_dir(dirpath):
rmtree(dirpath)
makedirs(dirpath)
def _copy_contents(dst_dir, contents):
items = {
"dirs": set(),
"files": set()
}
for path in contents:
path = abspath(path)
if isdir(path):
items['dirs'].add(path)
elif isfile(path):
items['files'].add(path)
dst_dir_name = basename(dst_dir)
if dst_dir_name == "src" and len(items['dirs']) == 1:
copytree(list(items['dirs']).pop(), dst_dir)
else:
makedirs(dst_dir)
for d in items['dirs']:
copytree(d, join(dst_dir, basename(d)))
if not items['files']:
return
if dst_dir_name == "lib":
dst_dir = join(dst_dir, mkdtemp(dir=dst_dir))
for f in items['files']:
copyfile(f, join(dst_dir, basename(f)))
def _exclude_contents(dst_dir, patterns):
contents = []
for p in patterns:
contents += glob(join(dst_dir, p))
for path in contents:
path = abspath(path)
if isdir(path):
rmtree(path)
elif isfile(path):
remove(path)

View File

@ -8,46 +8,53 @@ from shutil import copyfile
import click import click
from platformio import app, exception from platformio import app, exception
from platformio.ide.projectgenerator import ProjectGenerator
from platformio.util import get_boards, get_source_dir from platformio.util import get_boards, get_source_dir
def validate_boards(ctx, param, value): # pylint: disable=W0613
unknown_boards = set(value) - set(get_boards().keys())
try:
assert not unknown_boards
return value
except AssertionError:
raise click.BadParameter(
"%s. Please search for the board types using "
"`platformio boards` command" % ", ".join(unknown_boards))
@click.command("init", short_help="Initialize new PlatformIO based project") @click.command("init", short_help="Initialize new PlatformIO based project")
@click.option("--project-dir", "-d", default=getcwd, @click.option("--project-dir", "-d", default=getcwd,
type=click.Path(exists=True, file_okay=False, dir_okay=True, type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True)) writable=True, resolve_path=True))
@click.option("--board", "-b", multiple=True, metavar="TYPE") @click.option("--board", "-b", multiple=True, metavar="TYPE",
callback=validate_boards)
@click.option("--ide",
type=click.Choice(ProjectGenerator.get_supported_ides()))
@click.option("--disable-auto-uploading", is_flag=True) @click.option("--disable-auto-uploading", is_flag=True)
def cli(project_dir, board, disable_auto_uploading): @click.option("--env-prefix", default="")
def cli(project_dir, board, ide, disable_auto_uploading, env_prefix):
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 exception.ProjectInitialized()
builtin_boards = set(get_boards().keys())
if board and not set(board).issubset(builtin_boards):
raise exception.UnknownBoard(
", ".join(set(board).difference(builtin_boards)))
# ask about auto-uploading # ask about auto-uploading
if board and app.get_setting("enable_prompts"): if board and app.get_setting("enable_prompts"):
disable_auto_uploading = not click.confirm( disable_auto_uploading = not click.confirm(
"\nWould you like to enable firmware auto-uploading when project " "Would you like to enable firmware auto-uploading when project "
"is successfully built using `platformio run` command? \n" "is successfully built using `platformio run` command? \n"
"Don't forget that you can upload firmware manually using " "Don't forget that you can upload firmware manually using "
"`platformio run --target upload` command." "`platformio run --target upload` command."
) )
click.echo("")
if project_dir == getcwd(): if project_dir == getcwd():
click.secho("\nThe current working directory", fg="yellow", nl=False) click.secho("\nThe current working directory", fg="yellow", nl=False)
click.secho(" %s " % project_dir, fg="cyan", nl=False) click.secho(" %s " % project_dir, fg="cyan", nl=False)
click.secho( click.secho(
"will be used for the new project.\n" "will be used for project.\n"
"You can specify another project directory via\n" "You can specify another project directory via\n"
"`platformio init -d %PATH_TO_THE_PROJECT_DIR%` command.\n", "`platformio init -d %PATH_TO_THE_PROJECT_DIR%` command.",
fg="yellow" fg="yellow"
) )
click.echo("")
click.echo("The next files/directories will be created in %s" % click.echo("The next files/directories will be created in %s" %
click.style(project_dir, fg="cyan")) click.style(project_dir, fg="cyan"))
@ -58,51 +65,75 @@ def cli(project_dir, board, disable_auto_uploading):
click.echo("%s - Put here project specific or 3-rd party libraries" % click.echo("%s - Put here project specific or 3-rd party libraries" %
click.style("lib", fg="cyan")) click.style("lib", fg="cyan"))
if (not app.get_setting("enable_prompts") or if (app.get_setting("enable_prompts") and
click.confirm("Do you want to continue?")): not 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)
if board:
fill_project_envs(project_file, board, disable_auto_uploading)
click.secho(
"Project has been successfully initialized!\nUseful commands:\n"
"`platformio run` - process/build project from the current "
"directory\n"
"`platformio run --target upload` or `platformio run -t upload` "
"- upload firmware to embedded board\n"
"`platformio run --target clean` - clean project (remove compiled "
"files)",
fg="green"
)
else:
raise exception.AbortedByUser() raise exception.AbortedByUser()
project_file = join(project_dir, "platformio.ini")
src_dir = join(project_dir, "src")
lib_dir = join(project_dir, "lib")
def fill_project_envs(project_file, board_types, disable_auto_uploading): 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)
if board:
fill_project_envs(
project_file, board, disable_auto_uploading, env_prefix)
if ide:
pg = ProjectGenerator(project_dir, ide)
pg.generate()
click.secho(
"\nProject has been successfully initialized!\nUseful commands:\n"
"`platformio run` - process/build project from the current "
"directory\n"
"`platformio run --target upload` or `platformio run -t upload` "
"- upload firmware to embedded board\n"
"`platformio run --target clean` - clean project (remove compiled "
"files)",
fg="green"
)
def fill_project_envs(project_file, board_types, disable_auto_uploading,
env_prefix):
builtin_boards = get_boards() builtin_boards = get_boards()
content = [] content = []
for type_ in board_types: used_envs = []
if type_ not in builtin_boards:
continue
else:
content.append("")
with open(project_file) as f:
used_envs = [l.strip() for l in f.read().splitlines() if
l.strip().startswith("[env:")]
for type_ in board_types:
data = builtin_boards[type_] data = builtin_boards[type_]
env_name = "[env:%s%s]" % (env_prefix, type_)
if env_name in used_envs:
continue
content.append("")
content.append(env_name)
content.append("platform = %s" % data['platform'])
# find default framework for board # find default framework for board
frameworks = data.get("frameworks") frameworks = data.get("frameworks")
content.append("[env:autogen_%s]" % type_)
content.append("platform = %s" % data['platform'])
if frameworks: if frameworks:
content.append("framework = %s" % frameworks[0]) content.append("framework = %s" % frameworks[0])
content.append("board = %s" % type_)
content.append("board = %s" % type_)
content.append("%stargets = upload" % ("# " if disable_auto_uploading content.append("%stargets = upload" % ("# " if disable_auto_uploading
else "")) else ""))
if not content:
return
with open(project_file, "a") as f: with open(project_file, "a") as f:
content.append("")
f.write("\n".join(content)) f.write("\n".join(content))

View File

@ -1,20 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import click
from platformio.platforms.base import PlatformFactory
@click.command("install", short_help="Install new platforms")
@click.argument("platforms", nargs=-1)
@click.option("--with-package", multiple=True, metavar="<package>")
@click.option("--without-package", multiple=True, metavar="<package>")
@click.option("--skip-default-package", is_flag=True)
def cli(platforms, with_package, without_package, skip_default_package):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.install(with_package, without_package, skip_default_package):
click.secho("The platform '%s' has been successfully installed!" %
platform, fg="green")

View File

@ -7,7 +7,7 @@ import click
from platformio import app, exception from platformio import app, exception
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
LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} " LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} "
"\"{authornames}\": {description}") "\"{authornames}\": {description}")
@ -21,7 +21,9 @@ def echo_liblist_header():
authornames="Authors", authornames="Authors",
description="Description" description="Description"
)) ))
click.echo("-" * 85)
terminal_width, _ = click.get_terminal_size()
click.echo("-" * terminal_width)
def echo_liblist_item(item): def echo_liblist_item(item):
@ -98,7 +100,7 @@ def lib_search(query, **filters):
@click.option("-v", "--version") @click.option("-v", "--version")
@click.pass_context @click.pass_context
def lib_install(ctx, libid, version): def lib_install(ctx, libid, version):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
for id_ in libid: 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"))
@ -147,7 +149,7 @@ def lib_install_dependency(ctx, data):
@cli.command("uninstall", short_help="Uninstall libraries") @cli.command("uninstall", short_help="Uninstall libraries")
@click.argument("libid", type=click.INT, nargs=-1) @click.argument("libid", type=click.INT, nargs=-1)
def lib_uninstall(libid): def lib_uninstall(libid):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
for id_ in libid: for id_ in libid:
info = lm.get_info(id_) info = lm.get_info(id_)
if lm.uninstall(id_): if lm.uninstall(id_):
@ -158,7 +160,7 @@ def lib_uninstall(libid):
@cli.command("list", short_help="List installed libraries") @cli.command("list", short_help="List installed libraries")
@click.option("--json-output", is_flag=True) @click.option("--json-output", is_flag=True)
def lib_list(json_output): def lib_list(json_output):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
items = lm.get_installed().values() items = lm.get_installed().values()
if json_output: if json_output:
@ -177,7 +179,7 @@ def lib_list(json_output):
@cli.command("show", short_help="Show details about installed library") @cli.command("show", short_help="Show details about installed library")
@click.argument("libid", type=click.INT) @click.argument("libid", type=click.INT)
def lib_show(libid): def lib_show(libid):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
info = lm.get_info(libid) info = lm.get_info(libid)
click.secho(info['name'], fg="cyan") click.secho(info['name'], fg="cyan")
click.echo("-" * len(info['name'])) click.echo("-" * len(info['name']))
@ -209,13 +211,18 @@ def lib_show(libid):
@cli.command("update", short_help="Update installed libraries") @cli.command("update", short_help="Update installed libraries")
@click.argument("libid", type=click.INT, nargs=-1, required=False,
metavar="[LIBRARY_ID]")
@click.pass_context @click.pass_context
def lib_update(ctx): def lib_update(ctx, libid):
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
for id_, latest_version in (lm.get_latest_versions() or {}).items(): for id_, latest_version in (lm.get_latest_versions() or {}).items():
if libid and int(id_) not in libid:
continue
info = lm.get_info(int(id_)) info = lm.get_info(int(id_))
click.echo("Updating [ %s ] %s library:" % ( click.echo("Updating [ %s ] %s library:" % (
click.style(id_, fg="yellow"), click.style(id_, fg="yellow"),
click.style(info['name'], fg="cyan"))) click.style(info['name'], fg="cyan")))

View File

@ -1,34 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
import click
from platformio.platforms.base import PlatformFactory
@click.command("list", short_help="List installed platforms")
@click.option("--json-output", is_flag=True)
def cli(json_output):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
data = []
for platform in installed_platforms:
p = PlatformFactory.newPlatform(platform)
data.append({
"name": platform,
"packages": p.get_installed_packages()
})
if json_output:
click.echo(json.dumps(data))
else:
for item in data:
click.echo("{name:<20} with packages: {pkgs}".format(
name=click.style(item['name'], fg="cyan"),
pkgs=", ".join(item['packages'])
))

View File

@ -0,0 +1,155 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from datetime import datetime
import click
from platformio import app
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory
@click.group(short_help="Platforms and Packages Manager")
def cli():
pass
@cli.command("install", short_help="Install new platforms")
@click.argument("platforms", nargs=-1, required=True)
@click.option("--with-package", multiple=True, metavar="<package>")
@click.option("--without-package", multiple=True, metavar="<package>")
@click.option("--skip-default-package", is_flag=True)
def platforms_install(platforms, with_package, without_package,
skip_default_package):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.install(with_package, without_package, skip_default_package):
click.secho("The platform '%s' has been successfully installed!" %
platform, fg="green")
@cli.command("list", short_help="List installed platforms")
@click.option("--json-output", is_flag=True)
def platforms_list(json_output):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
data = []
for platform in installed_platforms:
p = PlatformFactory.newPlatform(platform)
data.append({
"name": platform,
"packages": p.get_installed_packages()
})
if json_output:
click.echo(json.dumps(data))
else:
for item in data:
click.echo("{name:<20} with packages: {pkgs}".format(
name=click.style(item['name'], fg="cyan"),
pkgs=", ".join(item['packages'])
))
@cli.command("search", short_help="Search for development platforms")
@click.argument("query", required=False)
@click.option("--json-output", is_flag=True)
def platforms_search(query, json_output):
data = []
platforms = PlatformFactory.get_platforms().keys()
platforms.sort()
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
type_ = p.get_type()
description = p.get_description()
if query == "all":
query = ""
search_data = "%s %s %s" % (type_, description, p.get_packages())
if query and query.lower() not in search_data.lower():
continue
data.append({
"type": type_,
"description": description,
"packages": p.get_packages()
})
if json_output:
click.echo(json.dumps(data))
else:
terminal_width, _ = click.get_terminal_size()
for item in data:
click.secho(item['type'], fg="cyan", nl=False)
click.echo(" (available packages: %s)" % ", ".join(
item.get("packages").keys()))
click.echo("-" * terminal_width)
click.echo(item['description'])
click.echo()
@cli.command("show", short_help="Show details about installed platform")
@click.argument("platform")
@click.pass_context
def platforms_show(ctx, platform):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if platform not in installed_platforms:
if (not app.get_setting("enable_prompts") or
click.confirm("The platform '%s' has not been installed yet. "
"Would you like to install it now?" % platform)):
ctx.invoke(platforms_install, platforms=[platform])
else:
raise PlatformNotInstalledYet(platform)
p = PlatformFactory.newPlatform(platform)
click.echo("{name:<20} - {description} [ {url} ]".format(
name=click.style(p.get_type(), fg="cyan"),
description=p.get_description(), url=p.get_vendor_url()))
installed_packages = PackageManager.get_installed()
for name in p.get_installed_packages():
data = installed_packages[name]
pkgalias = p.get_pkg_alias(name)
click.echo("----------")
click.echo("Package: %s" % click.style(name, fg="yellow"))
if pkgalias:
click.echo("Alias: %s" % pkgalias)
click.echo("Version: %d" % int(data['version']))
click.echo("Installed: %s" % datetime.fromtimestamp(
data['time']).strftime("%Y-%m-%d %H:%M:%S"))
@cli.command("uninstall", short_help="Uninstall platforms")
@click.argument("platforms", nargs=-1, required=True)
def platforms_uninstall(platforms):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.uninstall():
click.secho("The platform '%s' has been successfully "
"uninstalled!" % platform, fg="green")
@cli.command("update", short_help="Update installed Platforms and Packages")
def platforms_update():
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
installed_platforms.sort()
for platform in installed_platforms:
click.echo("\nPlatform %s" % click.style(platform, fg="cyan"))
click.echo("--------")
p = PlatformFactory.newPlatform(platform)
p.update()

View File

@ -2,6 +2,7 @@
# See LICENSE for details. # See LICENSE for details.
from datetime import datetime from datetime import datetime
from os import chdir, getcwd
from os.path import getmtime, isdir, join from os.path import getmtime, isdir, join
from shutil import rmtree from shutil import rmtree
from time import time from time import time
@ -9,7 +10,10 @@ from time import time
import click import click
from platformio import app, exception, telemetry, util from platformio import app, exception, telemetry, util
from platformio.commands.install import cli as cmd_install from platformio.commands.lib import lib_install as cmd_lib_install
from platformio.commands.platforms import \
platforms_install as cmd_platforms_install
from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
@ -17,55 +21,66 @@ from platformio.platforms.base import PlatformFactory
@click.option("--environment", "-e", multiple=True, metavar="<environment>") @click.option("--environment", "-e", multiple=True, metavar="<environment>")
@click.option("--target", "-t", multiple=True, metavar="<target>") @click.option("--target", "-t", multiple=True, metavar="<target>")
@click.option("--upload-port", metavar="<upload port>") @click.option("--upload-port", metavar="<upload port>")
@click.option("--project-dir", default=getcwd,
type=click.Path(exists=True, file_okay=False, dir_okay=True,
writable=True, resolve_path=True))
@click.pass_context @click.pass_context
def cli(ctx, environment, target, upload_port): def cli(ctx, environment, target, upload_port, project_dir):
initial_cwd = getcwd()
chdir(project_dir)
try:
config = util.get_project_config()
config = util.get_project_config() if not config.sections():
raise exception.ProjectEnvsNotAvailable()
if not config.sections(): unknown = set(environment) - set([s[4:] for s in config.sections()])
raise exception.ProjectEnvsNotAvailable() if unknown:
raise exception.UnknownEnvNames(", ".join(unknown))
unknown = set(environment) - set([s[4:] for s in config.sections()]) # remove ".pioenvs" if project config is modified
if unknown: _pioenvs_dir = util.get_pioenvs_dir()
raise exception.UnknownEnvNames(", ".join(unknown)) if (isdir(_pioenvs_dir) and
getmtime(join(util.get_project_dir(), "platformio.ini")) >
getmtime(_pioenvs_dir)):
rmtree(_pioenvs_dir)
# remove ".pioenvs" if project config is modified results = []
_pioenvs_dir = util.get_pioenvs_dir() for section in config.sections():
if (isdir(_pioenvs_dir) and if results and results[-1] is not None:
getmtime(join(util.get_project_dir(), "platformio.ini")) > click.echo()
getmtime(_pioenvs_dir)):
rmtree(_pioenvs_dir)
found_error = False results.append(_process_conf_section(
_first_done = False ctx, config, section, environment, target, upload_port))
for section in config.sections():
# skip main configuration section
if section == "platformio":
continue
elif section[:4] != "env:":
raise exception.InvalidEnvName(section)
envname = section[4:] if not all([r for r in results if r is not None]):
if environment and envname not in environment: raise exception.ReturnErrorCode()
# echo("Skipped %s environment" % style(envname, fg="yellow")) finally:
continue chdir(initial_cwd)
options = {}
for k, v in config.items(section):
options[k] = v
if _first_done:
click.echo()
if not process_environment(ctx, envname, options, target, upload_port):
found_error = True
_first_done = True
if found_error:
raise exception.ReturnErrorCode()
def process_environment(ctx, name, options, targets, upload_port): def _process_conf_section(ctx, config, section, # pylint: disable=R0913
environment, target, upload_port):
# skip main configuration section
if section == "platformio":
return None
if section[:4] != "env:":
raise exception.InvalidEnvName(section)
envname = section[4:]
if environment and envname not in environment:
# echo("Skipped %s environment" % style(envname, fg="yellow"))
return None
options = {}
for k, v in config.items(section):
options[k] = v
return _process_environment(ctx, envname, options, target, upload_port)
def _process_environment(ctx, name, options, targets, upload_port):
terminal_width, _ = click.get_terminal_size() terminal_width, _ = click.get_terminal_size()
start_time = time() start_time = time()
@ -114,13 +129,39 @@ def _run_environment(ctx, name, options, targets, upload_port):
telemetry.on_run_environment(options, envtargets) telemetry.on_run_environment(options, envtargets)
# install platform and libs dependencies
_autoinstall_env_platform(ctx, platform)
if "install_libs" in options:
_autoinstall_env_libs(ctx, options['install_libs'])
p = PlatformFactory.newPlatform(platform)
return p.run(variables, envtargets)
def _autoinstall_env_platform(ctx, platform):
installed_platforms = PlatformFactory.get_platforms( installed_platforms = PlatformFactory.get_platforms(
installed=True).keys() installed=True).keys()
if (platform not in installed_platforms and ( if (platform not in installed_platforms and (
not app.get_setting("enable_prompts") or not app.get_setting("enable_prompts") or
click.confirm("The platform '%s' has not been installed yet. " click.confirm("The platform '%s' has not been installed yet. "
"Would you like to install it now?" % platform))): "Would you like to install it now?" % platform))):
ctx.invoke(cmd_install, platforms=[platform]) ctx.invoke(cmd_platforms_install, platforms=[platform])
p = PlatformFactory.newPlatform(platform)
return p.run(variables, envtargets) def _autoinstall_env_libs(ctx, libids_list):
require_libs = [int(l.strip()) for l in libids_list.split(",")]
installed_libs = [
l['id'] for l in LibraryManager().get_installed().values()
]
not_intalled_libs = set(require_libs) - set(installed_libs)
if not require_libs or not not_intalled_libs:
return
if (not app.get_setting("enable_prompts") or
click.confirm(
"The libraries with IDs '%s' have not been installed yet. "
"Would you like to install them now?" %
", ".join([str(i) for i in not_intalled_libs])
)):
ctx.invoke(cmd_lib_install, libid=not_intalled_libs)

View File

@ -1,46 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
import click
from platformio.platforms.base import PlatformFactory
@click.command("search", short_help="Search for development platforms")
@click.argument("query", required=False)
@click.option("--json-output", is_flag=True)
def cli(query, json_output):
data = []
platforms = PlatformFactory.get_platforms().keys()
platforms.sort()
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
type_ = p.get_type()
description = p.get_description()
if query == "all":
query = ""
search_data = "%s %s %s" % (type_, description, p.get_packages())
if query and query.lower() not in search_data.lower():
continue
data.append({
"type": type_,
"description": description,
"packages": p.get_packages()
})
if json_output:
click.echo(json.dumps(data))
else:
for item in data:
click.secho(item['type'], fg="cyan", nl=False)
click.echo(" (available packages: %s)" % ", ".join(
item.get("packages").keys()))
click.secho("-" * len(item['type']), fg="cyan")
click.echo(item['description'])
click.echo()

View File

@ -25,7 +25,7 @@ def serialports_list(json_output):
for item in get_serialports(): for item in get_serialports():
click.secho(item['port'], fg="cyan") click.secho(item['port'], fg="cyan")
click.echo("----------") click.echo("-" * len(item['port']))
click.echo("Hardware ID: %s" % item['hwid']) click.echo("Hardware ID: %s" % item['hwid'])
click.echo("Description: %s" % item['description']) click.echo("Description: %s" % item['description'])
click.echo("") click.echo("")

View File

@ -16,6 +16,7 @@ def cli():
def settings_get(name): def settings_get(name):
list_tpl = "{name:<40} {value:<35} {description}" list_tpl = "{name:<40} {value:<35} {description}"
terminal_width, _ = click.get_terminal_size()
click.echo(list_tpl.format( click.echo(list_tpl.format(
name=click.style("Name", fg="cyan"), name=click.style("Name", fg="cyan"),
@ -23,7 +24,7 @@ def settings_get(name):
click.style(" [Default]", fg="yellow")), click.style(" [Default]", fg="yellow")),
description="Description" description="Description"
)) ))
click.echo("-" * 90) click.echo("-" * terminal_width)
for _name, _data in sorted(app.DEFAULT_SETTINGS.items()): for _name, _data in sorted(app.DEFAULT_SETTINGS.items()):
if name and name != _name: if name and name != _name:

View File

@ -1,46 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from datetime import datetime
import click
from platformio import app
from platformio.commands.install import cli as cmd_install
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms.base import PlatformFactory
@click.command("show", short_help="Show details about installed platform")
@click.argument("platform")
@click.pass_context
def cli(ctx, platform):
installed_platforms = PlatformFactory.get_platforms(
installed=True).keys()
if platform not in installed_platforms:
if (not app.get_setting("enable_prompts") or
click.confirm("The platform '%s' has not been installed yet. "
"Would you like to install it now?" % platform)):
ctx.invoke(cmd_install, platforms=[platform])
else:
raise PlatformNotInstalledYet(platform)
p = PlatformFactory.newPlatform(platform)
click.echo("{name:<20} - {description} [ {url} ]".format(
name=click.style(p.get_type(), fg="cyan"),
description=p.get_description(), url=p.get_vendor_url()))
installed_packages = PackageManager.get_installed()
for name in p.get_installed_packages():
data = installed_packages[name]
pkgalias = p.get_pkg_alias(name)
click.echo("----------")
click.echo("Package: %s" % click.style(name, fg="yellow"))
if pkgalias:
click.echo("Alias: %s" % pkgalias)
click.echo("Version: %d" % int(data['version']))
click.echo("Installed: %s" % datetime.fromtimestamp(
data['time']).strftime("%Y-%m-%d %H:%M:%S"))

View File

@ -1,17 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import click
from platformio.platforms.base import PlatformFactory
@click.command("uninstall", short_help="Uninstall platforms")
@click.argument("platforms", nargs=-1)
def cli(platforms):
for platform in platforms:
p = PlatformFactory.newPlatform(platform)
if p.uninstall():
click.secho("The platform '%s' has been successfully "
"uninstalled!" % platform, fg="green")

View File

@ -3,18 +3,14 @@
import click import click
from platformio.platforms.base import PlatformFactory from platformio.commands.lib import lib_update as cmd_lib_update
from platformio.commands.platforms import \
platforms_update as cmd_platforms_update
@click.command("update", short_help="Update installed platforms") @click.command("update",
def cli(): short_help="Update installed Platforms, Packages and Libraries")
@click.pass_context
installed_platforms = PlatformFactory.get_platforms( def cli(ctx):
installed=True).keys() ctx.invoke(cmd_platforms_update)
installed_platforms.sort() ctx.invoke(cmd_lib_update)
for platform in installed_platforms:
click.echo("\nPlatform %s" % click.style(platform, fg="cyan"))
click.echo("--------")
p = PlatformFactory.newPlatform(platform)
p.update()

View File

@ -4,9 +4,8 @@
import click import click
import requests import requests
from platformio import __version__ from platformio import __version__, util
from platformio.exception import GetLatestVersionError from platformio.exception import GetLatestVersionError
from platformio.util import exec_command
@click.command("upgrade", @click.command("upgrade",
@ -22,9 +21,9 @@ def cli():
click.secho("Please wait while upgrading PlatformIO ...", click.secho("Please wait while upgrading PlatformIO ...",
fg="yellow") fg="yellow")
pip_result = exec_command(["pip", "install", "--upgrade", pip_result = util.exec_command(["pip", "install", "--upgrade",
"platformio"]) "platformio"])
pio_result = exec_command(["platformio", "--version"]) pio_result = util.exec_command(["platformio", "--version"])
if last in pio_result['out'].strip(): if last in pio_result['out'].strip():
click.secho("PlatformIO has been successfully upgraded to %s" % click.secho("PlatformIO has been successfully upgraded to %s" %
@ -37,7 +36,9 @@ def cli():
def get_latest_version(): def get_latest_version():
try: try:
pkgdata = requests.get( pkgdata = requests.get(
"https://pypi.python.org/pypi/platformio/json").json() "https://pypi.python.org/pypi/platformio/json",
headers=util.get_request_defheaders()
).json()
return pkgdata['info']['version'] return pkgdata['info']['version']
except: except:
raise GetLatestVersionError() raise GetLatestVersionError()

View File

@ -9,9 +9,9 @@ from time import mktime
from click import progressbar from click import progressbar
from requests import get from requests import get
from platformio import util
from platformio.exception import (FDSHASumMismatch, FDSizeMismatch, from platformio.exception import (FDSHASumMismatch, FDSizeMismatch,
FDUnrecognizedStatusCode) FDUnrecognizedStatusCode)
from platformio.util import change_filemtime, exec_command
class FileDownloader(object): class FileDownloader(object):
@ -27,7 +27,8 @@ class FileDownloader(object):
self.set_destination(join(dest_dir, self._fname)) self.set_destination(join(dest_dir, self._fname))
self._progressbar = None self._progressbar = None
self._request = get(url, stream=True) self._request = get(url, stream=True,
headers=util.get_request_defheaders())
if self._request.status_code != 200: if self._request.status_code != 200:
raise FDUnrecognizedStatusCode(self._request.status_code, url) raise FDUnrecognizedStatusCode(self._request.status_code, url)
@ -66,11 +67,12 @@ class FileDownloader(object):
dlsha1 = None dlsha1 = None
try: try:
result = exec_command(["sha1sum", self._destination]) result = util.exec_command(["sha1sum", self._destination])
dlsha1 = result['out'] dlsha1 = result['out']
except OSError: except OSError:
try: try:
result = exec_command(["shasum", "-a", "1", self._destination]) result = util.exec_command(
["shasum", "-a", "1", self._destination])
dlsha1 = result['out'] dlsha1 = result['out']
except OSError: except OSError:
pass pass
@ -83,7 +85,7 @@ class FileDownloader(object):
def _preserve_filemtime(self, lmdate): def _preserve_filemtime(self, lmdate):
timedata = parsedate_tz(lmdate) timedata = parsedate_tz(lmdate)
lmtime = mktime(timedata[:9]) lmtime = mktime(timedata[:9])
change_filemtime(self._destination, lmtime) util.change_filemtime(self._destination, lmtime)
def __del__(self): def __del__(self):
self._request.close() self._request.close()

View File

@ -96,12 +96,6 @@ class UnsupportedArchiveType(PlatformioException):
MESSAGE = "Can not unpack file '%s'" MESSAGE = "Can not unpack file '%s'"
class ProjectInitialized(PlatformioException):
MESSAGE = ("Project is already initialized. "
"Process it with `platformio run` command")
class ProjectEnvsNotAvailable(PlatformioException): class ProjectEnvsNotAvailable(PlatformioException):
MESSAGE = "Please setup environments in `platformio.ini` file." MESSAGE = "Please setup environments in `platformio.ini` file."
@ -171,6 +165,15 @@ class UpgraderFailed(PlatformioException):
MESSAGE = "An error occurred while upgrading PlatformIO" MESSAGE = "An error occurred while upgrading PlatformIO"
class CIBuildEnvsEmpty(PlatformioException):
MESSAGE = (
"Can't find PlatformIO build environments.\nPlease specify `--board` "
"or path to `platformio.ini` with predefined environments using "
"`--project-conf` option"
)
class SConsNotInstalled(PlatformioException): class SConsNotInstalled(PlatformioException):
MESSAGE = ( MESSAGE = (

View File

@ -0,0 +1,2 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.

View File

@ -0,0 +1,84 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from glob import glob
from os import listdir, walk
from os.path import basename, isdir, join
import bottle
from platformio import util
class ProjectGenerator(object):
def __init__(self, project_dir, ide):
self.project_dir = project_dir
self.ide = ide
self._tplvars = {}
self._gather_tplvars()
@staticmethod
def get_supported_ides():
tpls_dir = join(util.get_source_dir(), "ide", "tpls")
return [d for d in listdir(tpls_dir)
if isdir(join(tpls_dir, d))]
@staticmethod
def get_project_env():
data = {}
config = util.get_project_config()
for section in config.sections():
if not section.startswith("env:"):
continue
data['env_name'] = section[4:]
for k, v in config.items(section):
data[k] = v
return data
def get_project_name(self):
return basename(self.project_dir)
@staticmethod
def get_includes():
return []
@staticmethod
def get_srcfiles():
result = []
for root, _, files in walk(util.get_projectsrc_dir()):
for f in files:
result.append(join(root, f))
return result
@staticmethod
def get_defines():
return []
def get_tpls(self):
tpls_dir = join(util.get_source_dir(), "ide", "tpls", self.ide)
return glob(join(tpls_dir, ".*.tpl")) + glob(join(tpls_dir, "*.tpl"))
def generate(self):
for tpl_path in self.get_tpls():
file_name = basename(tpl_path)[:-4]
with open(join(self.project_dir, file_name), "w") as f:
f.write(self._render_tpl(tpl_path).encode("utf8"))
def _render_tpl(self, tpl_path):
content = ""
with open(tpl_path) as f:
content = f.read()
return bottle.template(content, **self._tplvars)
def _gather_tplvars(self):
self._tplvars.update(self.get_project_env())
self._tplvars.update({
"project_name": self.get_project_name(),
"includes": self.get_includes(),
"srcfiles": self.get_srcfiles(),
"defines": self.get_defines(),
"project_dir": self.project_dir
})

View File

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.910961921">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.910961921" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="{{project_name}}" buildProperties="" description="" id="0.910961921" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.910961921." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.952979152" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.952979152.52310970" name=""/>
<builder cleanBuildTarget="--force run --target clean" command="platformio" id="org.eclipse.cdt.build.core.settings.default.builder.1519453406" incrementalBuildTarget="--force run" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1409095472" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.1624502120" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.239157887" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
% for include in includes:
<listOptionValue builtIn="false" value="{{include}}"/>
% end
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.922107295" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
% for define in defines:
<listOptionValue builtIn="false" value="{{define}}"/>
% end
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.149990277" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.54121539" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.1096940598" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
% for include in includes:
<listOptionValue builtIn="false" value="{{include}}"/>
% end
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1198905600" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
% for define in defines:
<listOptionValue builtIn="false" value="{{define}}"/>
% end
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.762536863" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1310559623" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.41298875" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
% for include in includes:
<listOptionValue builtIn="false" value="{{include}}"/>
% end
</option>
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.884639970" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
% for define in defines:
<listOptionValue builtIn="false" value="{{define}}"/>
% end
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.549319812" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="{{project_name}}.null.189551033" name="{{project_name}}"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="0.910961921">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/{{env_name}}"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>{{project_name}}</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,24 @@
win32 {
HOMEDIR += $$(USERPROFILE)
}
else {
HOMEDIR += $$(PWD)
}
% for include in includes:
INCLUDEPATH += "{{include}}"
% end
win32:INCLUDEPATH ~= s,/,\\,g
% for define in defines:
DEFINES += "{{define}}"
% end
OTHER_FILES += \
platformio.ini
SOURCES += \
% for file in srcfiles:
{{file}}
% end

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.2.2, 2015-05-07T12:57:08. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
<value type="QByteArray">{00248b6a-4380-4f03-8dea-a03053177907}</value>
</data>
<data>
<variable>ProjectExplorer.Project.ActiveTarget</variable>
<value type="int">0</value>
</data>
<data>
<variable>ProjectExplorer.Project.EditorSettings</variable>
<valuemap type="QVariantMap">
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
<value type="QString" key="language">Cpp</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
</valuemap>
</valuemap>
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
<value type="QString" key="language">QmlJS</value>
<valuemap type="QVariantMap" key="value">
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
</valuemap>
</valuemap>
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
<value type="int" key="EditorConfiguration.IndentSize">4</value>
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
<value type="int" key="EditorConfiguration.TabSize">8</value>
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.PluginSettings</variable>
<valuemap type="QVariantMap"/>
</data>
<data>
<variable>ProjectExplorer.Project.Target.0</variable>
<valuemap type="QVariantMap">
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">{{project_name}}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">{{project_name}}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.53.win32_mingw482_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">1</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">{{project_dir}}</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--force run</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">platformio</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--force run -t clean</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">platformio</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">{{project_dir}}</value>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--force run</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">platformio</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
</valuemap>
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Arguments">--force run -t clean</value>
<value type="QString" key="ProjectExplorer.ProcessStep.Command">platformio</value>
<value type="QString" key="ProjectExplorer.ProcessStep.WorkingDirectory">%{buildDir}</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Process Step</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.ProcessStep</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
<value type="bool" key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">2</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
</valuemap>
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
<value type="int">0</value>
<value type="int">1</value>
<value type="int">2</value>
<value type="int">3</value>
<value type="int">4</value>
<value type="int">5</value>
<value type="int">6</value>
<value type="int">7</value>
<value type="int">8</value>
<value type="int">9</value>
<value type="int">10</value>
<value type="int">11</value>
<value type="int">12</value>
<value type="int">13</value>
<value type="int">14</value>
</valuelist>
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">platformio</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:{{project_dir}}/platformio.pro</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments"></value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">platformio.pro</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
<value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
<value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>
</data>
<data>
<variable>ProjectExplorer.Project.TargetCount</variable>
<value type="int">1</value>
</data>
<data>
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
<value type="int">16</value>
</data>
<data>
<variable>Version</variable>
<value type="int">16</value>
</data>
</qtcreator>

View File

@ -0,0 +1,45 @@
{
"build_systems":
[
{
"cmd":
[
"platformio",
"run"
],
"name": "PlatformIO",
"variants":
[
{
"cmd":
[
"platformio",
"--force",
"run",
"--target",
"clean"
],
"name": "Clean"
},
{
"cmd":
[
"platformio",
"--force",
"run",
"--target",
"upload"
],
"name": "Upload"
}
],
"working_dir": "${project_path:${folder}}"
}
],
"folders":
[
{
"path": "."
}
]
}

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\src">
<UniqueIdentifier>{cad450ef-1a84-42d4-a5b5-a1736b8833d3}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<None Include="platformio.ini" />
<None Include="src\blink.pde">
<Filter>Source Files\src</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0FA9C3A8-452B-41EF-A418-9102B170F49F}</ProjectGuid>
<Keyword>MakeFileProj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Makefile</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<NMakeBuildCommandLine>platformio --force run</NMakeBuildCommandLine>
<NMakeCleanCommandLine>platformio --force run --target clean</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>{{";".join(defines)}}</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>{{";".join(includes)}}</NMakeIncludeSearchPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<NMakeBuildCommandLine>platformio run</NMakeBuildCommandLine>
<NMakeCleanCommandLine>platformio run -t clean</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>{";".join(defines)}}</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>{{";".join(includes)}}</NMakeIncludeSearchPath>
</PropertyGroup>
<ItemDefinitionGroup>
</ItemDefinitionGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<None Include="platformio.ini" />
% for file in srcfiles:
<None Include="{{file}}" />
% end
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -8,19 +8,18 @@ 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 import telemetry, util
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
from platformio.util import get_api_result
class LibraryManager(object): class LibraryManager(object):
CONFIG_NAME = ".library.json" CONFIG_NAME = ".library.json"
def __init__(self, lib_dir): def __init__(self, lib_dir=None):
self.lib_dir = lib_dir self.lib_dir = lib_dir or util.get_lib_dir()
@staticmethod @staticmethod
def download(url, dest_dir): def download(url, dest_dir):
@ -49,7 +48,7 @@ class LibraryManager(object):
lib_ids = [str(item['id']) for item in self.get_installed().values()] lib_ids = [str(item['id']) for item in self.get_installed().values()]
if not lib_ids: if not lib_ids:
return None return None
return get_api_result("/lib/version/" + str(",".join(lib_ids))) return util.get_api_result("/lib/version/" + str(",".join(lib_ids)))
def get_outdated(self): def get_outdated(self):
outdated = [] outdated = []
@ -75,8 +74,10 @@ class LibraryManager(object):
if self.is_installed(id_): if self.is_installed(id_):
raise LibAlreadyInstalledError() raise LibAlreadyInstalledError()
dlinfo = get_api_result("/lib/download/" + str(id_), dlinfo = util.get_api_result(
dict(version=version) if version else None) "/lib/download/" + str(id_),
dict(version=version) if version else None
)
dlpath = None dlpath = None
tmplib_dir = join(self.lib_dir, str(id_)) tmplib_dir = join(self.lib_dir, str(id_))
try: try:

View File

@ -11,16 +11,19 @@ from time import time
import click import click
from platformio import __version__, app, exception, telemetry from platformio import __version__, app, exception, telemetry
from platformio.commands.install import cli as cmd_install
from platformio.commands.lib import lib_update as cmd_libraries_update from platformio.commands.lib import lib_update as cmd_libraries_update
from platformio.commands.update import cli as cli_update from platformio.commands.platforms import \
platforms_install as cmd_platforms_install
from platformio.commands.platforms import \
platforms_update as cmd_platforms_update
from platformio.commands.upgrade import get_latest_version from platformio.commands.upgrade import get_latest_version
from platformio.libmanager import LibraryManager from platformio.libmanager import LibraryManager
from platformio.platforms.base import PlatformFactory from platformio.platforms.base import PlatformFactory
from platformio.util import get_home_dir, get_lib_dir from platformio.util import get_home_dir
def on_platformio_start(ctx): def on_platformio_start(ctx, force):
app.set_session_var("force_option", force)
telemetry.on_command(ctx) telemetry.on_command(ctx)
after_upgrade(ctx) after_upgrade(ctx)
@ -89,7 +92,7 @@ class Upgrader(object):
remove(join(get_home_dir(), fname)) remove(join(get_home_dir(), fname))
if prev_platforms: if prev_platforms:
ctx.invoke(cmd_install, platforms=prev_platforms) ctx.invoke(cmd_platforms_install, platforms=prev_platforms)
return True return True
@ -97,8 +100,7 @@ class Upgrader(object):
installed_platforms = PlatformFactory.get_platforms( installed_platforms = PlatformFactory.get_platforms(
installed=True).keys() installed=True).keys()
if installed_platforms: if installed_platforms:
ctx.invoke(cmd_install, platforms=installed_platforms) ctx.invoke(cmd_platforms_install, platforms=installed_platforms)
ctx.invoke(cli_update)
return True return True
@ -107,8 +109,12 @@ def after_upgrade(ctx):
if last_version == __version__: if last_version == __version__:
return return
terminal_width, _ = click.get_terminal_size()
# promotion # promotion
click.echo("\nIf you like %s, please:" % ( click.echo("")
click.echo("*" * terminal_width)
click.echo("If you like %s, please:" % (
click.style("PlatformIO", fg="cyan") click.style("PlatformIO", fg="cyan")
)) ))
click.echo( click.echo(
@ -121,7 +127,13 @@ def after_upgrade(ctx):
click.style("give", fg="cyan"), click.style("give", fg="cyan"),
click.style("https://github.com/platformio/platformio", fg="cyan") click.style("https://github.com/platformio/platformio", fg="cyan")
)) ))
click.secho("Thanks a lot!\n", fg="green") click.echo("- %s for the new features/issues on Bountysource > %s" % (
click.style("vote", fg="cyan"),
click.style("https://www.bountysource.com/teams/platformio/issues",
fg="cyan")
))
click.echo("*" * terminal_width)
click.echo("")
if last_version == "0.0.0": if last_version == "0.0.0":
app.set_state_item("last_version", __version__) app.set_state_item("last_version", __version__)
@ -133,6 +145,8 @@ def after_upgrade(ctx):
u = Upgrader(last_version, __version__) u = Upgrader(last_version, __version__)
if u.run(ctx): if u.run(ctx):
app.set_state_item("last_version", __version__) app.set_state_item("last_version", __version__)
ctx.invoke(cmd_platforms_update)
click.secho("PlatformIO has been successfully upgraded to %s!\n" % click.secho("PlatformIO has been successfully upgraded to %s!\n" %
__version__, fg="green") __version__, fg="green")
@ -158,13 +172,19 @@ def check_platformio_upgrade():
Upgrader.version_to_int(__version__)): Upgrader.version_to_int(__version__)):
return return
terminal_width, _ = click.get_terminal_size()
click.echo("")
click.echo("*" * terminal_width)
click.secho("There is a new version %s of PlatformIO available.\n" click.secho("There is a new version %s of PlatformIO available.\n"
"Please upgrade it via " % latest_version, "Please upgrade it via " % latest_version,
fg="yellow", nl=False) fg="yellow", nl=False)
click.secho("platformio upgrade", fg="cyan", nl=False) click.secho("platformio upgrade", fg="cyan", nl=False)
click.secho(" command.\nChanges: ", fg="yellow", nl=False) click.secho(" command.\nChanges: ", fg="yellow", nl=False)
click.secho("http://docs.platformio.org/en/latest/history.html\n", click.secho("http://docs.platformio.org/en/latest/history.html",
fg="cyan") fg="cyan")
click.echo("*" * terminal_width)
click.echo("")
def check_internal_updates(ctx, what): def check_internal_updates(ctx, what):
@ -183,28 +203,35 @@ def check_internal_updates(ctx, what):
if p.is_outdated(): if p.is_outdated():
outdated_items.append(platform) outdated_items.append(platform)
elif what == "libraries": elif what == "libraries":
lm = LibraryManager(get_lib_dir()) lm = LibraryManager()
outdated_items = lm.get_outdated() outdated_items = lm.get_outdated()
if not outdated_items: if not outdated_items:
return return
terminal_width, _ = click.get_terminal_size()
click.echo("")
click.echo("*" * terminal_width)
click.secho("There are the new updates for %s (%s)" % click.secho("There are the new updates for %s (%s)" %
(what, ", ".join(outdated_items)), fg="yellow") (what, ", ".join(outdated_items)), fg="yellow")
if not app.get_setting("auto_update_" + what): if not app.get_setting("auto_update_" + what):
click.secho("Please update them via ", fg="yellow", nl=False) click.secho("Please update them via ", fg="yellow", nl=False)
click.secho("`platformio %supdate`" % click.secho("`platformio %s update`" %
("lib " if what == "libraries" else ""), ("lib" if what == "libraries" else "platforms"),
fg="cyan", nl=False) fg="cyan", nl=False)
click.secho(" command.\n", fg="yellow") click.secho(" command.", fg="yellow")
else: else:
click.secho("Please wait while updating %s ..." % what, fg="yellow") click.secho("Please wait while updating %s ..." % what, fg="yellow")
if what == "platforms": if what == "platforms":
ctx.invoke(cli_update) ctx.invoke(cmd_platforms_update)
elif what == "libraries": elif what == "libraries":
ctx.invoke(cmd_libraries_update) ctx.invoke(cmd_libraries_update)
click.echo() click.echo()
telemetry.on_event(category="Auto", action="Update", telemetry.on_event(category="Auto", action="Update",
label=what.title()) label=what.title())
click.echo("*" * terminal_width)
click.echo("")

View File

@ -8,28 +8,24 @@ from time import time
import click import click
from platformio import exception, telemetry from platformio import exception, telemetry, util
from platformio.app import get_state_item, set_state_item from platformio.app import get_state_item, set_state_item
from platformio.downloader import FileDownloader from platformio.downloader import FileDownloader
from platformio.unpacker import FileUnpacker from platformio.unpacker import FileUnpacker
from platformio.util import get_api_result, get_home_dir, get_systype
class PackageManager(object): class PackageManager(object):
def __init__(self): def __init__(self):
self._package_dir = join(get_home_dir(), "packages") self._package_dir = join(util.get_home_dir(), "packages")
if not isdir(self._package_dir): if not isdir(self._package_dir):
makedirs(self._package_dir) makedirs(self._package_dir)
assert isdir(self._package_dir) assert isdir(self._package_dir)
@classmethod @classmethod
@util.memoized
def get_manifest(cls): def get_manifest(cls):
try: return util.get_api_result("/packages/manifest")
return cls._cached_manifest
except AttributeError:
cls._cached_manifest = get_api_result("/packages/manifest")
return cls._cached_manifest
@staticmethod @staticmethod
def download(url, dest_dir, sha1=None): def download(url, dest_dir, sha1=None):
@ -63,7 +59,7 @@ class PackageManager(object):
raise exception.UnknownPackage(name) raise exception.UnknownPackage(name)
# check system platform # check system platform
systype = get_systype() systype = util.get_systype()
builds = ([b for b in manifest[name] if b['system'] == "all" or systype builds = ([b for b in manifest[name] if b['system'] == "all" or systype
in b['system']]) in b['system']])
if not builds: if not builds:

View File

@ -119,7 +119,7 @@ class PlatformFactory(object):
@staticmethod @staticmethod
def get_clsname(type_): def get_clsname(type_):
return "%sPlatform" % type_.title() return "%s%sPlatform" % (type_.upper()[0], type_.lower()[1:])
@staticmethod @staticmethod
def load_module(type_, path): def load_module(type_, path):
@ -132,14 +132,16 @@ class PlatformFactory(object):
return module return module
@classmethod @classmethod
def get_platforms(cls, installed=False): @util.memoized
def _lookup_platforms(cls):
platforms = {} platforms = {}
for d in (util.get_home_dir(), util.get_source_dir()): for d in (util.get_home_dir(), util.get_source_dir()):
pdir = join(d, "platforms") pdir = join(d, "platforms")
if not isdir(pdir): if not isdir(pdir):
continue continue
for p in listdir(pdir): for p in listdir(pdir):
if p in ("__init__.py", "base.py") or not p.endswith(".py"): if (p in ("__init__.py", "base.py") or not
p.endswith(".py")):
continue continue
type_ = p[:-3] type_ = p[:-3]
path = join(pdir, p) path = join(pdir, p)
@ -152,6 +154,11 @@ class PlatformFactory(object):
platforms[type_] = path platforms[type_] = path
except exception.UnknownPlatform: except exception.UnknownPlatform:
pass pass
return platforms
@classmethod
def get_platforms(cls, installed=False):
platforms = cls._lookup_platforms()
if not installed: if not installed:
return platforms return platforms

View File

@ -12,8 +12,7 @@ from time import time
import click import click
import requests import requests
from platformio import __version__, app from platformio import __version__, app, util
from platformio.util import exec_command, get_systype
class TelemetryBase(object): class TelemetryBase(object):
@ -77,7 +76,7 @@ class MeasurementProtocol(TelemetryBase):
dpdata.append("Click/%s" % click.__version__) dpdata.append("Click/%s" % click.__version__)
# dpdata.append("Requests/%s" % requests.__version__) # dpdata.append("Requests/%s" % requests.__version__)
try: try:
result = exec_command(["scons", "--version"]) result = util.exec_command(["scons", "--version"])
match = re.search(r"engine: v([\d\.]+)", result['out']) match = re.search(r"engine: v([\d\.]+)", result['out'])
if match: if match:
dpdata.append("SCons/%s" % match.group(1)) dpdata.append("SCons/%s" % match.group(1))
@ -86,7 +85,7 @@ class MeasurementProtocol(TelemetryBase):
self['an'] = " ".join(dpdata) self['an'] = " ".join(dpdata)
def _prefill_custom_data(self): def _prefill_custom_data(self):
self['cd1'] = get_systype() self['cd1'] = util.get_systype()
self['cd2'] = "Python/%s %s" % (platform.python_version(), self['cd2'] = "Python/%s %s" % (platform.python_version(),
platform.platform()) platform.platform())
self['cd4'] = 1 if app.get_setting("enable_prompts") else 0 self['cd4'] = 1 if app.get_setting("enable_prompts") else 0
@ -96,7 +95,7 @@ class MeasurementProtocol(TelemetryBase):
if not args: if not args:
return return
if args[0] in ("lib", "serialports", "settings"): if args[0] in ("lib", "platforms", "serialports", "settings"):
cmd_path = args[:2] cmd_path = args[:2]
else: else:
cmd_path = args[:1] cmd_path = args[:1]
@ -155,6 +154,7 @@ class MPDataPusher(threading.Thread):
r = self.http_session().post( r = self.http_session().post(
"https://ssl.google-analytics.com/collect", "https://ssl.google-analytics.com/collect",
data=data, data=data,
headers=util.get_request_defheaders(),
timeout=3 timeout=3
) )
r.raise_for_status() r.raise_for_status()

View File

@ -1,6 +1,8 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
import collections
import functools
import json import json
import os import os
import re import re
@ -53,6 +55,39 @@ class AsyncPipe(Thread):
self.join() self.join()
class memoized(object):
'''
Decorator. Caches a function's return value each time it is called.
If called later with the same arguments, the cached value is returned
(not reevaluated).
https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
'''
def __init__(self, func):
self.func = func
self.cache = {}
def __call__(self, *args):
if not isinstance(args, collections.Hashable):
# uncacheable. a list, for instance.
# better to not cache than blow up.
return self.func(*args)
if args in self.cache:
return self.cache[args]
else:
value = self.func(*args)
self.cache[args] = value
return value
def __repr__(self):
'''Return the function's docstring.'''
return self.func.__doc__
def __get__(self, obj, objtype):
'''Support instance methods.'''
return functools.partial(self.__call__, obj)
def get_systype(): def get_systype():
data = uname() data = uname()
return ("%s_%s" % (data[0], data[4])).lower() return ("%s_%s" % (data[0], data[4])).lower()
@ -207,19 +242,22 @@ def get_logicaldisks():
return disks return disks
def get_request_defheaders():
return {"User-Agent": "PlatformIO/%s %s" % (
__version__, requests.utils.default_user_agent())}
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" % (
__version__, requests.utils.default_user_agent())}
if data: if data:
r = requests.post(__apiurl__ + path, params=params, data=data, r = requests.post(__apiurl__ + path, params=params, data=data,
headers=headers) headers=get_request_defheaders())
else: else:
r = requests.get(__apiurl__ + path, params=params, headers=headers) r = requests.get(__apiurl__ + path, params=params,
headers=get_request_defheaders())
result = r.json() result = r.json()
r.raise_for_status() r.raise_for_status()
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
@ -239,22 +277,24 @@ def get_api_result(path, params=None, data=None):
return result return result
def get_boards(type_=None): @memoized
def _lookup_boards():
boards = {} boards = {}
try: bdirs = [join(get_source_dir(), "boards")]
boards = get_boards._cache # pylint: disable=W0212 if isdir(join(get_home_dir(), "boards")):
except AttributeError: bdirs.append(join(get_home_dir(), "boards"))
bdirs = [join(get_source_dir(), "boards")]
if isdir(join(get_home_dir(), "boards")):
bdirs.append(join(get_home_dir(), "boards"))
for bdir in bdirs: for bdir in bdirs:
for json_file in os.listdir(bdir): for json_file in os.listdir(bdir):
if not json_file.endswith(".json"): if not json_file.endswith(".json"):
continue continue
with open(join(bdir, json_file)) as f: with open(join(bdir, json_file)) as f:
boards.update(json.load(f)) boards.update(json.load(f))
get_boards._cache = boards # pylint: disable=W0212 return boards
def get_boards(type_=None):
boards = _lookup_boards()
if type_ is None: if type_ is None:
return boards return boards
@ -264,33 +304,34 @@ def get_boards(type_=None):
return boards[type_] return boards[type_]
def get_frameworks(type_=None): @memoized
def _lookup_frameworks():
frameworks = {} frameworks = {}
frameworks_path = join(
get_source_dir(), "builder", "scripts", "frameworks")
try: frameworks_list = [f[:-3] for f in os.listdir(frameworks_path)
frameworks = get_frameworks._cache # pylint: disable=W0212 if not f.startswith("__") and f.endswith(".py")]
except AttributeError: for _type in frameworks_list:
frameworks_path = join( script_path = join(frameworks_path, "%s.py" % _type)
get_source_dir(), "builder", "scripts", "frameworks") with open(script_path) as f:
fcontent = f.read()
assert '"""' in fcontent
_doc_start = fcontent.index('"""') + 3
fdoc = fcontent[
_doc_start:fcontent.index('"""', _doc_start)].strip()
doclines = [l.strip() for l in fdoc.splitlines() if l.strip()]
frameworks[_type] = {
"name": doclines[0],
"description": " ".join(doclines[1:-1]),
"url": doclines[-1],
"script": script_path
}
return frameworks
frameworks_list = [f[:-3] for f in os.listdir(frameworks_path)
if not f.startswith("__") and f.endswith(".py")] def get_frameworks(type_=None):
for _type in frameworks_list: frameworks = _lookup_frameworks()
script_path = join(frameworks_path, "%s.py" % _type)
with open(script_path) as f:
fcontent = f.read()
assert '"""' in fcontent
_doc_start = fcontent.index('"""') + 3
fdoc = fcontent[
_doc_start:fcontent.index('"""', _doc_start)].strip()
doclines = [l.strip() for l in fdoc.splitlines() if l.strip()]
frameworks[_type] = {
"name": doclines[0],
"description": " ".join(doclines[1:-1]),
"url": doclines[-1],
"script": script_path
}
get_frameworks._cache = frameworks # pylint: disable=W0212
if type_ is None: if type_ is None:
return frameworks return frameworks

View File

@ -1,4 +1,5 @@
click==4.0 click==4.0
bottle=0.12.8
colorama==0.3.3 colorama==0.3.3
pyserial==2.7 pyserial==2.7
requests==2.7.0 requests==2.7.0

View File

@ -18,13 +18,21 @@ setup(
url=__url__, url=__url__,
license=__license__, license=__license__,
install_requires=[ install_requires=[
"bottle",
"click>=3.0", "click>=3.0",
"pyserial", "pyserial",
"requests>=2.4.0", "requests>=2.4.0",
# "SCons" # "SCons"
] + (["colorama"] if system() == "Windows" else []), ] + (["colorama"] if system() == "Windows" else []),
packages=find_packages(), packages=find_packages(),
package_data={"platformio": ["projectconftpl.ini", "boards/*.json"]}, package_data={
"platformio": [
"projectconftpl.ini",
"boards/*.json",
"ide/tpls/*/.*.tpl",
"ide/tpls/*/*.tpl"
]
},
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [
"platformio = platformio.__main__:main" "platformio = platformio.__main__:main"

View File

@ -5,13 +5,15 @@ import json
from os.path import isfile, join from os.path import isfile, join
from platformio import util from platformio import util
from platformio.commands.boards import cli as boards_cli from platformio.commands.boards import cli as cmd_boards
from platformio.commands.install import cli as install_cli from platformio.commands.platforms import \
from platformio.commands.search import cli as search_cli platforms_install as cmd_platforms_install
from platformio.commands.platforms import \
platforms_search as cmd_platforms_search
def test_board_json_output(platformio_setup, clirunner, validate_cliresult): def test_board_json_output(platformio_setup, clirunner, validate_cliresult):
result = clirunner.invoke(boards_cli, ["cortex", "--json-output"]) result = clirunner.invoke(cmd_boards, ["cortex", "--json-output"])
validate_cliresult(result) validate_cliresult(result)
boards = json.loads(result.output) boards = json.loads(result.output)
assert isinstance(boards, dict) assert isinstance(boards, dict)
@ -19,7 +21,7 @@ def test_board_json_output(platformio_setup, clirunner, validate_cliresult):
def test_board_raw_output(platformio_setup, clirunner, validate_cliresult): def test_board_raw_output(platformio_setup, clirunner, validate_cliresult):
result = clirunner.invoke(boards_cli, ["energia"]) result = clirunner.invoke(cmd_boards, ["energia"])
validate_cliresult(result) validate_cliresult(result)
assert "titiva" in result.output assert "titiva" in result.output
@ -29,7 +31,7 @@ def test_board_options(platformio_setup, clirunner, validate_cliresult):
["build", "platform", "upload", "name"]) ["build", "platform", "upload", "name"])
# fetch available platforms # fetch available platforms
result = clirunner.invoke(search_cli, ["--json-output"]) result = clirunner.invoke(cmd_platforms_search, ["--json-output"])
validate_cliresult(result) validate_cliresult(result)
search_result = json.loads(result.output) search_result = json.loads(result.output)
assert isinstance(search_result, list) assert isinstance(search_result, list)
@ -43,7 +45,7 @@ def test_board_options(platformio_setup, clirunner, validate_cliresult):
def test_board_ldscripts(platformio_setup, clirunner, validate_cliresult): def test_board_ldscripts(platformio_setup, clirunner, validate_cliresult):
result = clirunner.invoke( result = clirunner.invoke(
install_cli, [ cmd_platforms_install, [
"ststm32", "ststm32",
"--skip-default-package", "--skip-default-package",
"--with-package=ldscripts" "--with-package=ldscripts"

View File

@ -46,9 +46,9 @@ def test_init_special_board(platformio_setup, clirunner, validate_cliresult):
("targets", "upload") ("targets", "upload")
] ]
assert config.has_section("env:autogen_uno") assert config.has_section("env:uno")
assert len(set(expected_result).symmetric_difference( assert len(set(expected_result).symmetric_difference(
set(config.items("env:autogen_uno")))) == 0 set(config.items("env:uno")))) == 0
def test_init_disable_auto_uploading(platformio_setup, clirunner, def test_init_disable_auto_uploading(platformio_setup, clirunner,
@ -64,11 +64,13 @@ def test_init_disable_auto_uploading(platformio_setup, clirunner,
("framework", "arduino"), ("framework", "arduino"),
("board", "uno") ("board", "uno")
] ]
assert config.has_section("env:autogen_uno") assert config.has_section("env:uno")
assert len(set(expected_result).symmetric_difference( assert len(set(expected_result).symmetric_difference(
set(config.items("env:autogen_uno")))) == 0 set(config.items("env:uno")))) == 0
def test_init_incorrect_board(clirunner): def test_init_incorrect_board(clirunner):
result = clirunner.invoke(cli, ["-b", "missed_board"]) result = clirunner.invoke(cli, ["-b", "missed_board"])
assert isinstance(result.exception, exception.UnknownBoard) assert result.exit_code == 2
assert 'Error: Invalid value for "--board" / "-b"' in result.output
assert isinstance(result.exception, SystemExit)

View File

@ -1,22 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from platformio.commands.list import cli
def test_list_json_output(clirunner, validate_cliresult):
result = clirunner.invoke(cli, ["--json-output"])
validate_cliresult(result)
list_result = json.loads(result.output)
assert isinstance(list_result, list)
assert len(list_result)
platforms = [item['name'] for item in list_result]
assert "titiva" in platforms
def test_list_raw_output(clirunner, validate_cliresult):
result = clirunner.invoke(cli)
validate_cliresult(result)
assert "teensy" in result.output

View File

@ -0,0 +1,42 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from platformio.commands.platforms import \
platforms_list as cmd_platforms_list
from platformio.commands.platforms import \
platforms_search as cmd_platforms_search
def test_list_json_output(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_platforms_list, ["--json-output"])
validate_cliresult(result)
list_result = json.loads(result.output)
assert isinstance(list_result, list)
assert len(list_result)
platforms = [item['name'] for item in list_result]
assert "titiva" in platforms
def test_list_raw_output(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_platforms_list)
validate_cliresult(result)
assert "teensy" in result.output
def test_search_json_output(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_platforms_search,
["arduino", "--json-output"])
validate_cliresult(result)
search_result = json.loads(result.output)
assert isinstance(search_result, list)
assert len(search_result)
platforms = [item['type'] for item in search_result]
assert "atmelsam" in platforms
def test_search_raw_output(clirunner, validate_cliresult):
result = clirunner.invoke(cmd_platforms_search, ["arduino"])
validate_cliresult(result)
assert "teensy" in result.output

View File

@ -1,22 +0,0 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from platformio.commands.search import cli
def test_search_json_output(clirunner, validate_cliresult):
result = clirunner.invoke(cli, ["arduino", "--json-output"])
validate_cliresult(result)
search_result = json.loads(result.output)
assert isinstance(search_result, list)
assert len(search_result)
platforms = [item['type'] for item in search_result]
assert "atmelsam" in platforms
def test_search_raw_output(clirunner, validate_cliresult):
result = clirunner.invoke(cli, ["arduino"])
validate_cliresult(result)
assert "teensy" in result.output