diff --git a/HISTORY.rst b/HISTORY.rst index a5e000bb45..423b0c19ab 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,13 @@ Release History =============== +0.7.0 (2014-09-24) +------------------ + +* Implemented new ``[platformio]`` section for Configuration File with ``home_dir`` + option (`issue #14 `_) +* Implemented *Library Manager* (`issue #6 `_) + 0.6.0 (2014-08-09) ------------------ diff --git a/README.rst b/README.rst index c89e7c8941..808382fa96 100644 --- a/README.rst +++ b/README.rst @@ -17,8 +17,8 @@ PlatformIO :target: https://pypi.python.org/pypi/platformio/ :alt: License -`Documentation `_ / -`PDF `_ | +`Website `_ | +`Documentation `_ | `Project Examples `_ | `Bugs/Questions `_ | `Blog `_ | @@ -26,6 +26,7 @@ PlatformIO **PlatformIO** is a cross-platform code builder and library manager. +* `Website + Library Search `_ * `Quickstart `_ * `Installation `_ * `Project Configuration File `_ diff --git a/docs/index.rst b/docs/index.rst index d082ae73ac..d76fb76d61 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,6 +1,7 @@ PlatformIO: A cross-platform code builder and library manager ============================================================= +`Website + Library Search `_ | `Project Examples `_ | `Source Code `_ | `Bugs/Questions `_ | @@ -42,6 +43,7 @@ Contents installation projectconf platforms/index + librarymanager/index userguide/index ide history diff --git a/docs/installation.rst b/docs/installation.rst index c4b4d0d319..d0f875bb31 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -27,13 +27,7 @@ Then run the following (which may require administrator access): .. code-block:: bash - $ python get-platformio.py - -An alternative short version for *Mac/Linux* users: - -.. code-block:: bash - - $ curl -L http://bit.ly/1lpanta | python + $ [sudo] python get-platformio.py On *Windows OS* it may look like: @@ -43,9 +37,11 @@ On *Windows OS* it may look like: C:\Python27\python.exe get-platformio.py .. warning:: - If you have an error ``pkg_resources.DistributionNotFound`` try to - uninstall *PlatformIO* ``$ pip uninstall platformio``, then install it via - ``$ easy_install platformio``. + **Mac OS Users**: If you have an error ``pkg_resources.DistributionNotFound`` please + upgrade *SetupTools* package: ``$ [sudo] pip uninstall setuptools`` + and ``$ [sudo] pip install setuptools``. + Then re-install *PlatformIO*: ``$ [sudo] pip uninstall platformio`` + and ``$ [sudo] pip install platformio``. Full Guide diff --git a/docs/librarymanager/config.rst b/docs/librarymanager/config.rst new file mode 100644 index 0000000000..bfc6692d20 --- /dev/null +++ b/docs/librarymanager/config.rst @@ -0,0 +1,247 @@ +.. _library_config: + +library.json +============ + +*PlatformIO*-suitable library should be defined by a manifest file +``library.json`` in a `JSON-style `_. +A data in ``library.json`` should be represented via +`associative array `_ +(name/value pairs). An order doesn't matter. + +The allowable fields (names from pairs) are described below. The fields +(:ref:`libjson_name`, :ref:`libjson_description` and :ref:`libjson_keywords`) +will be displayed in the search results at the :ref:`cmd_lib_search` (*CLI*) +and at the *WebSite*. Also, they can be used for searching for libraries. + +.. contents:: + +.. _libjson_name: + +``name`` +-------- + +**Required** | Type: ``String`` | Max. Length: 50 + +A name of the library. + +* Must be unique. +* Should be slug style for simplicity, consistency and compatibility. + Example: *Arduino-SPI* +* Title Case, Aa-z, can contain digits and dashes (but not start/end + with them). +* Consecutive dashes are not allowed. + + +.. _libjson_description: + +``description`` +--------------- + +**Required** | Type: ``String`` | Max. Length: 255 + +The field helps users to identify and search for your library with a brief +description. Describe the hardware devices (sensors, boards and etc.) which +are suitable with it. + + +.. _libjson_keywords: + +``keywords`` +------------ + +**Required** | Type: ``String`` | Max. Length: 255 + +Used for search by keyword. Helps to make your library easier to discover +without people needing to know its name. + +The keyword should be lowercased, can contain a-z, digits and dash (but not +start/end with them). A list from the keywords can be specified with +separator ``,`` + + +.. _libjson_version: + +``version`` +----------- + +*Required* if :ref:`libjson_repository` field is not defined | Type: ``String`` +| Max. Length: 20 + +A version of the current library source code. + +* Can contain a-z, digits, dots or dash. +* `Semantic Versioning `_ is recommended. +* A `CVS `_ + revision from the latest commit. Example: ``13`` (*SVN*) or first 10 + chars of *SHA* digest ``e4564b7da4`` (*Git*). + +.. note:: + You can omit :ref:`libjson_version` field and define + :ref:`libjson_repository` field. In this case + *PlatformIO-API Crawler* will use the *CVS*-revision from the latest commit. + + +.. _libjson_author: + +``author`` +---------- + +*Required* if :ref:`libjson_repository` field is not defined | Type: ``Object`` + +An author contact information + +* ``name`` Full name (**Required**) +* ``email`` +* ``url`` An author's contact page + +Example: + +.. code-block:: javascript + + "author": + { + "name": "John Smith", + "email": "me@john-smith.com", + "url": "http://www.john-smith/contact" + } + +.. note:: + You can omit :ref:`libjson_author` field and define + :ref:`libjson_repository` field. Only *GitHub-based* repository is + supported now. In this case + *PlatformIO-API Crawler* will use information from + `GitHub API Users `_. + + +.. _libjson_repository: + +``repository`` +-------------- + +*Required* if :ref:`libjson_downloadurl` field is not defined | Type: ``Object`` + +The repository in which the source code can be found. + +Example: + +.. code-block:: javascript + + "repository": + { + "name": "git", + "url": "https://github.com/foo/bar.git" + } + + +.. _libjson_downloadurl: + +``downloadUrl`` +--------------- + +*Required* if :ref:`libjson_repository` field is not defined | Type: ``String`` + +It is the *HTTP URL* to the archived source code of library. It should end +with the type of archive (``.zip`` or ``.tar.gz``). + + +.. _libjson_include: + +``include`` +----------- + +*Optional* | Type: ``String`` or ``Array`` | +`Glob Pattern `_ + +If :ref:`libjson_include` field is a type of ``String``, then +*PlatformIO-API Crawler* will recognize it like a "relative path inside +repository/archive to library source code". See example below where the only +source code from the relative directory ``LibrarySourceCodeHere`` will be +included. + +.. code-block:: javascript + + "include": "some/child/dir/LibrarySourceCodeHere" + +If :ref:`libjson_include` field is a type of ``Array``, then +*PlatformIO-API Crawler* firstly will apply :ref:`libjson_exclude` filter and +then include only directories/files which match with :ref:`libjson_include` +patterns. + +Example: + +.. code-block:: javascript + + "include": + [ + "dir/*.[ch]pp", + "dir/examples/*", + "*/*/*.h" + ] + +Pattern Meaning + +.. list-table:: + :header-rows: 1 + + * - Pattern + - Meaning + * - ``*`` + - matches everything + * - ``?`` + - matches any single character + * - ``[seq]`` + - matches any character in seq + * - ``[!seq]`` + - matches any character not in seq + + +.. _libjson_exclude: + +``exclude`` +----------- + +*Optional* | Type: ``String`` or ``Array`` | +`Glob Pattern `_ + +Exclude the directories and files which match with :ref:`libjson_exclude` +patterns. + + +.. _libjson_dependencies: + +``dependencies`` +---------------- + +*Optional* | Type: ``Array`` + +A list of dependent libraries. They will be installed automatically with +:ref:`cmd_lib_install` command. + +Example: + +.. code-block:: javascript + + "dependencies": + [ + "Library-Foo", + "Library-Bar" + ] + + +.. _libjson_examples: + +``examples`` +---------------- + +*Optional* | Type: ``String`` or ``Array`` | +`Glob Pattern `_ + +A list of example patterns. This field is predefined with default value: + +.. code-block:: javascript + + "examples": [ + "[Ee]xamples/*/*.ini", + "[Ee]xamples/*/*.pde" + ] diff --git a/docs/librarymanager/creating.rst b/docs/librarymanager/creating.rst new file mode 100644 index 0000000000..18af7c2c92 --- /dev/null +++ b/docs/librarymanager/creating.rst @@ -0,0 +1,130 @@ +.. _library_creating: +.. |PIOAPICR| replace:: *PlatformIO-API Crawler* + +Creating Library +================ + +*PlatformIO* :ref:`librarymanager` doesn't have any requirements to a library +source code structure. The only one requirement is library's manifest file - +:ref:`library_config`. It can be located inside your library or in the another +location where |PIOAPICR| will have *HTTP* access. + +.. contents:: + +Source Code Location +-------------------- + +There are a several ways how to share your library with the whole world +(see `examples `_). + +You can hold a lot of libraries (split into separated folders) inside one of +the repository/archive. In this case please use :ref:`libjson_include` +field to specify the relative path to your library's source code. + + +At GitHub +^^^^^^^^^ + +**Recommended** + +If a library source code is located at `GitHub `_, then +you **need to specify** only these fields in the :ref:`library_config`: + +* :ref:`libjson_name` +* :ref:`libjson_keywords` +* :ref:`libjson_description` +* :ref:`libjson_repository` + +|PIOAPICR| will populate the rest fields, like :ref:`libjson_version` or +:ref:`libjson_author` with an actual information from *GitHub*. + +Example: + +.. code-block:: javascript + + { + "name": "Arduino-IRremote", + "keywords": "infrared, ir, remote", + "description": "Send and receive infrared signals with multiple protocols", + "repository": + { + "type": "git", + "url": "https://github.com/shirriff/Arduino-IRremote.git" + } + } + +Under CVS (SVN/GIT) +^^^^^^^^^^^^^^^^^^^ + +|PIOAPICR| can operate with a library source code that is under *CVS* control. +The list of **required** fields in the :ref:`library_config` will look like: + +* :ref:`libjson_name` +* :ref:`libjson_keywords` +* :ref:`libjson_description` +* :ref:`libjson_author` +* :ref:`libjson_repository` + +Example: + +.. code-block:: javascript + + { + "name": "Arduino-XBee", + "keywords": "xbee, protocol, radio", + "description": "Arduino library for communicating with XBees in API mode", + "author": + { + "name": "Andrew Rapp", + "email": "andrew.rapp@gmail.com", + "url": "https://code.google.com/u/andrew.rapp@gmail.com/" + }, + "repository": + { + "type": "git", + "url": "https://code.google.com/p/xbee-arduino/" + } + } + +Self-hosted +^^^^^^^^^^^ + +You can manually archive (*Zip, Tar.Gz*) your library source code and host it +in the *Internet*. Then you should specify the additional fields, +like :ref:`libjson_version` and :ref:`libjson_downloadurl`. The final list +of **required** fields in the :ref:`library_config` will look like: + +* :ref:`libjson_name` +* :ref:`libjson_keywords` +* :ref:`libjson_description` +* :ref:`libjson_author` +* :ref:`libjson_version` +* :ref:`libjson_downloadurl` + +.. code-block:: javascript + + { + "name": "Arduino-OneWire", + "keywords": "onewire, 1-wire, bus, sensor, temperature, ibutton", + "description": "Control devices (from Dallas Semiconductor) that use the One Wire protocol (DS18S20, DS18B20, DS2408 and etc)", + "author": + { + "name": "Paul Stoffregen", + "url": "http://www.pjrc.com/teensy/td_libs_OneWire.html" + }, + "version": "2.2", + "downloadUrl": "http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip", + "include": "OneWire" + } + + +Register +-------- + +The registration requirements: + +* A library must adhere to the :ref:`library_config` specification. +* There must be public *HTTP* access to the library :ref:`library_config` file. + +Now, you can :ref:`register ` your library and allow others +to :ref:`install ` it. diff --git a/docs/librarymanager/index.rst b/docs/librarymanager/index.rst new file mode 100644 index 0000000000..3840872c87 --- /dev/null +++ b/docs/librarymanager/index.rst @@ -0,0 +1,24 @@ +.. _librarymanager: + +Library Manager +=============== + +.. + + *"The missing library manager for embedded platforms"* [#]_ + +*PlatformIO Library Manager* allows you to organize external embedded libraries. +You can search for new libraries via :ref:`Command Line ` +or `WebSite `_ interfaces. + +You don't need to bother for finding the latest version of library. Due to +:ref:`cmd_lib_update` command you will have up-to-date external libraries. + +.. toctree:: + :maxdepth: 2 + + creating + config + +.. [#] Inspired by `npm `_ and `bower + `_ package managers for web. diff --git a/docs/platforms/atmelavr.rst b/docs/platforms/atmelavr.rst index a5f979d258..ca10dc56f0 100644 --- a/docs/platforms/atmelavr.rst +++ b/docs/platforms/atmelavr.rst @@ -299,8 +299,8 @@ More detailed information you can find here `Microduino boards `_. -Miscellaneous -~~~~~~~~~~~~~ +Raspduino +~~~~~~~~~ .. list-table:: :header-rows: 1 @@ -318,3 +318,6 @@ Miscellaneous - 16 MHz ``16000000L`` - 32 Kb - 2 Kb + +More detailed information you can find in +`Wiki `_. diff --git a/docs/projectconf.rst b/docs/projectconf.rst index 3a1ab0bbc0..d63996e85d 100644 --- a/docs/projectconf.rst +++ b/docs/projectconf.rst @@ -14,6 +14,32 @@ The sections and their allowable values are described below. .. contents:: +[platformio] +------------ + +A ``platformio`` section is used for overriding default configuration options + +Options +~~~~~~~ + +``home_dir`` +^^^^^^^^^^^^ + +A ``$PIO_HOME_DIR`` is used to store platform tool chains, frameworks, +external libraries, service data and etc. + +A default value is user's home directory: *Unix* - ``~/.platformio``, +Windows - ``%HOMEPATH%\.platformio``. + + +``lib_dir`` +^^^^^^^^^^^^ + +This directory is used to store external libraries downloaded by +:ref:`librarymanager`. + +A default value is ``$PIO_HOME_DIR/lib``. + [env:NAME] ---------- @@ -220,14 +246,51 @@ Examples framework = arduino board = uno - upload_port = /dev/ ttyUSB0 - # upload_port = COM3 # for Windows OS + upload_port = /dev/ttyUSB0 + # for Windows OS + # upload_port = COM3 + + # enable auto-uploading + targets = upload + + +2. :ref:`platform_atmelavr`: Microduino Core (ATmega168P, 3.3V) board with + auto pre-configured ``board_*`` and ``upload_*`` options (use only + ``board`` option) and Arduino Wiring-based Framework + +.. code-block:: ini + + [env:atmelavr_microduino_core_board] + platform = atmelavr + framework = arduino + board = 168pa8m + + upload_port = /dev/ttyUSB0 + # for Windows OS + # upload_port = COM3 + + # enable auto-uploading + targets = upload + + +3. :ref:`platform_atmelavr`: Raspduino board with + auto pre-configured ``board_*`` and ``upload_*`` options (use only + ``board`` option) and Arduino Wiring-based Framework + +.. code-block:: ini + + [env:atmelavr_raspduino_board] + platform = atmelavr + framework = arduino + board = raspduino + + upload_port = /dev/ttyS0 # enable auto-uploading targets = upload -2. :ref:`platform_atmelavr`: Embedded board that is based on ATmega168 MCU with +4. :ref:`platform_atmelavr`: Embedded board that is based on ATmega168 MCU with "arduino" bootloader .. code-block:: ini @@ -238,7 +301,8 @@ Examples board_f_cpu = 16000000L upload_port = /dev/ttyUSB0 - # upload_port = COM3 # for Windows OS + # for Windows OS + # upload_port = COM3 upload_protocol = arduino upload_speed = 19200 @@ -246,7 +310,7 @@ Examples targets = upload -3. :ref:`platform_timsp430`: TI MSP430G2553 LaunchPad with auto pre-configured +5. :ref:`platform_timsp430`: TI MSP430G2553 LaunchPad with auto pre-configured ``board_*`` and ``upload_*`` options (use only ``board`` option) and Energia Wiring-based Framework @@ -258,7 +322,7 @@ Examples board = lpmsp430g2553 -4. :ref:`platform_timsp430`: Embedded board that is based on MSP430G2553 MCU +6. :ref:`platform_timsp430`: Embedded board that is based on MSP430G2553 MCU .. code-block:: ini diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 9c947c9989..6ad1551c78 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -36,6 +36,17 @@ Initialize new PlatformIO based project and setup environments in `platformio.ini` file. Then process project with `platformio run` command. + +Setup environments in ``platformio.ini``. For more examples go to +:ref:`projectconf` + +.. code-block:: ini + + # Simple and base environment + [env:mybaseenv] + platform = %INSTALLED_PLATFORM_NAME_HERE% + + Process the project's environments .. code-block:: bash @@ -49,4 +60,8 @@ Process the project's environments $ platformio run --target clean -For more detailed information please go to :ref:`userguide` sections. +Further examples can be found in the ``examples/`` directory in the source +distribution or `on the web `_. + +Also, for more detailed information as for commands please go to +:ref:`userguide` sections. diff --git a/docs/userguide/cmd_serialports.rst b/docs/userguide/cmd_serialports.rst index 04b1950bbe..83e476d85e 100644 --- a/docs/userguide/cmd_serialports.rst +++ b/docs/userguide/cmd_serialports.rst @@ -171,7 +171,7 @@ Diagnostics: suppress non-error messages, default ``Off`` Examples ~~~~~~~~ -1. Show available option for command +1. Show available options for *monitor* .. code-block:: bash diff --git a/docs/userguide/index.rst b/docs/userguide/index.rst index 5779209aad..3cadb2f55e 100644 --- a/docs/userguide/index.rst +++ b/docs/userguide/index.rst @@ -16,6 +16,7 @@ To print all available commands and options use: cmd_init cmd_install + platformio lib cmd_list cmd_run cmd_search diff --git a/docs/userguide/lib/cmd_install.rst b/docs/userguide/lib/cmd_install.rst new file mode 100644 index 0000000000..81483ff5ae --- /dev/null +++ b/docs/userguide/lib/cmd_install.rst @@ -0,0 +1,68 @@ +.. _cmd_lib_install: + +platformio lib install +====================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib install [OPTIONS] [NAMES] + + +Description +----------- + +Install new library + +Options +------- + +.. option:: + -v, --version + +Install specified version of library + + +Examples +-------- + +1. Install the latest version of library + +.. code-block:: bash + + $ platformio lib install Arduino-IRremote + Installing Arduino-IRremote library: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The library 'Arduino-IRremote' has been successfully installed! + + +2. Install specified version of library + +.. code-block:: bash + + $ platformio lib install Arduino-XBee --version=0.5 + Installing Arduino-XBee library: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The library 'Arduino-XBee' has been successfully installed! + + +3. Install library with dependencies + +.. code-block:: bash + + $ platformio lib install Adafruit-Arduino-ST7735 + Installing Adafruit-Arduino-ST7735 library: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The library 'Adafruit-Arduino-ST7735' has been successfully installed! + Installing dependencies: + Installing Adafruit-Arduino-GFX library: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The library 'Adafruit-Arduino-GFX' has been successfully installed! diff --git a/docs/userguide/lib/cmd_list.rst b/docs/userguide/lib/cmd_list.rst new file mode 100644 index 0000000000..757bc7de26 --- /dev/null +++ b/docs/userguide/lib/cmd_list.rst @@ -0,0 +1,31 @@ +.. _cmd_lib_list: + +platformio lib list +=================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib list + + +Description +----------- + +List installed libraries + + +Examples +-------- + +.. code-block:: bash + + $ platformio lib list + Arduino-IRremote Send and receive infrared signals with multiple protocols + ... + Arduino-Webduino An extensible web server library (for use with the Arduino Ethernet Shield) + Arduino-XBee Arduino library for communicating with XBees in API mode diff --git a/docs/userguide/lib/cmd_register.rst b/docs/userguide/lib/cmd_register.rst new file mode 100644 index 0000000000..fddb147812 --- /dev/null +++ b/docs/userguide/lib/cmd_register.rst @@ -0,0 +1,26 @@ +.. _cmd_lib_register: + +platformio lib register +======================= + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib regiter [HTTP_URL_TO_LIBRARY.JSON] + + +Description +----------- + +Register new library and allow others to install it. + +Examples +-------- + +.. code-block:: bash + + $ platformio lib register http://my.example.com/library.json diff --git a/docs/userguide/lib/cmd_search.rst b/docs/userguide/lib/cmd_search.rst new file mode 100644 index 0000000000..14d92f5d73 --- /dev/null +++ b/docs/userguide/lib/cmd_search.rst @@ -0,0 +1,136 @@ +.. _cmd_lib_search: + +platformio lib search +===================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib search [OPTIONS] [QUERY] + + +Description +----------- + +Search for library over ``name``, ``description`` and ``keywords`` fields from +the :ref:`library_config` file in the boolean mode. + +The boolean search capability supports the following operators: + +.. list-table:: + :header-rows: 1 + + * - Operator + - Description + * - ``+`` + - A leading or trailing plus sign indicates that this word must be present + in library fields (see above) that is returned. + * - ``-`` + - A leading or trailing minus sign indicates that this word must not be + present in any of the libraries that are returned. + * - ``(no operator)`` + - By default (when neither ``+`` nor ``-`` is specified), the + word is optional, but the libraries that contain it are rated higher. + * - ``> <`` + - These two operators are used to change a word's contribution to the + relevance value that is assigned to a library. The ``>`` operator + increases the contribution and the ``<`` operator decreases it. + * - ``( )`` + - Parentheses group words into subexpressions. Parenthesized groups can + be nested. + * - ``~`` + - A leading tilde acts as a negation operator, causing the word's + contribution to the library's relevance to be negative. This is useful for + marking "noise" words. A library containing such a word is rated lower than + others, but is not excluded altogether, as it would be with the ``-`` operator. + * - ``*`` + - The asterisk serves as the truncation (or wildcard) operator. Unlike the + other operators, it is appended to the word to be affected. Words match if + they begin with the word preceding the ``*`` operator. + * - ``"`` + - A phrase that is enclosed within double quote (``"``) characters matches + only libraries that contain the phrase literally, as it was typed. + +For more detail information please go to +`MySQL Boolean Full-Text Searches `_. + +Options +------- + +.. option:: + -a, --author + +Filter libraries by specified author + +.. option:: + -k, --keyword + +Filter libraries by specified keyword + +Examples +-------- + +1. Search for "1-Wire" library + +.. code-block:: bash + + $ platformio lib search 1-wire + Found N libraries: + Arduino-OneWire Control devices (from Dallas Semiconductor) that use the One Wire protocol + ... + +2. Search for Arduino-based "I2C" libraries. The ``+`` sign is here like ``AND`` + operator. + +.. code-block:: bash + + $ platformio lib search "+i2c +arduino" + Found N libraries: + i2cdevlib-Arduino-i2cdev The I2C Device Library (i2cdevlib) is a collection of uniform and well-documented classes to provide simple and intuitive interfaces to I2C devices. + i2cdevlib-Arduino-AK8975 AK8975 is 3-axis electronic compass IC with high sensitive Hall sensor technology + ... + +3. Search for libraries by "web" and "http" keywords. The ``""`` here is for + "empty" query argument. + +.. code-block:: bash + + $ platformio lib search "" --keyword web --keyword http + Found N libraries: + Arduino-Webduino An extensible web server library (for use with the Arduino Ethernet Shield) + Arduino-aJson An Arduino library to enable JSON processing with Arduino + ... + +4. Search for libraries from "Adafruit Industries" author. + +.. code-block:: bash + + $ platformio lib search "" --author "Adafruit Industries" + Found N libraries: + Adafruit-Arduino-ST7735 A library for the Adafruit 1.8" SPI display + Adafruit-Arduino-GFX A core graphics library for all our displays, providing a common set of graphics primitives (points, lines, circles, etc.) + ... + +5. Search for libraries that are compatible with Dallas temperature sensors + like DS18B20, DS18S20 and etc. + +.. code-block:: bash + + $ platformio lib search "DS*" + Found N libraries: + Arduino-OneWire Control devices (from Dallas Semiconductor) that use the One Wire protocol + ... + +6. Search for Arduino-based *X10* or *XBee* libraries. The search query that is + described below can be interpreted like ``arduino x10 OR arduino xbee``. + +.. code-block:: bash + + $ platformio lib search "+arduino +(x10 xbee)" + Found 2 libraries: + Arduino-X10 Sending X10 signals over AC power lines + Arduino-XBee Arduino library for communicating with XBees in API mode diff --git a/docs/userguide/lib/cmd_show.rst b/docs/userguide/lib/cmd_show.rst new file mode 100644 index 0000000000..b7cca0449a --- /dev/null +++ b/docs/userguide/lib/cmd_show.rst @@ -0,0 +1,34 @@ +.. _cmd_lib_show: + +platformio lib show +=================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib show NAME + + +Description +----------- + +Show details about the installed library + + +Examples +-------- + +.. code-block:: bash + + $ platformio lib show Arduino-XBee + Arduino-XBee + ------------ + Author: Andrew Rapp + Keywords: xbee, protocol, radio + Version: 0.5 + + Arduino library for communicating with XBees in API mode diff --git a/docs/userguide/lib/cmd_uninstall.rst b/docs/userguide/lib/cmd_uninstall.rst new file mode 100644 index 0000000000..66a26b75f1 --- /dev/null +++ b/docs/userguide/lib/cmd_uninstall.rst @@ -0,0 +1,31 @@ +.. _cmd_lib_uninstall: + +platformio lib uninstall +======================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib uninstall NAME + + +Description +----------- + +Uninstall specified library + + +Examples +-------- + +.. code-block:: bash + + $ platformio lib install Arduino-IRremote + Installing Arduino-IRremote library: + Downloading [####################################] 100% + Unpacking [####################################] 100% + The library 'Arduino-IRremote' has been successfully installed! diff --git a/docs/userguide/lib/cmd_update.rst b/docs/userguide/lib/cmd_update.rst new file mode 100644 index 0000000000..68d6b361d8 --- /dev/null +++ b/docs/userguide/lib/cmd_update.rst @@ -0,0 +1,33 @@ +.. _cmd_lib_update: + +platformio lib update +===================== + +.. contents:: + +Usage +----- + +.. code-block:: bash + + platformio lib update + + +Description +----------- + +Check or update installed libraries + + +Examples +-------- + +.. code-block:: bash + + $ platformio lib update + Updating Arduino-IRremote library: + Versions: Current=24ba950f5c, Latest=24ba950f5c [Up-to-date] + Updating Arduino-Webduino library: + Versions: Current=3631af8e02, Latest=3631af8e02 [Up-to-date] + Updating Arduino-XBee library: + Versions: Current=0.5, Latest=0.5 [Up-to-date] diff --git a/docs/userguide/lib/index.rst b/docs/userguide/lib/index.rst new file mode 100644 index 0000000000..6d2c5fead2 --- /dev/null +++ b/docs/userguide/lib/index.rst @@ -0,0 +1,23 @@ +.. _userguide_lib: + +Library Manager +=============== + +To print all available commands and options use: + +.. code-block:: bash + + $ platformio lib --help + $ platformio lib COMMAND --help + + +.. toctree:: + :maxdepth: 2 + + cmd_install + cmd_list + cmd_register + cmd_search + cmd_show + cmd_uninstall + cmd_update diff --git a/platformio/__init__.py b/platformio/__init__.py index b2f1c430ec..dcc97ca2c5 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,17 +1,18 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (0, 6, 0) +VERSION = (0, 7, 0) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" __description__ = ("A cross-platform code builder and library manager") -__url__ = "https://github.com/ivankravets/platformio" +__url__ = "http://platformio.ikravets.com" __author__ = "Ivan Kravets" __email__ = "me@ikravets.com" -__license__ = "MIT Licence" +__license__ = "MIT License" __copyright__ = "Copyright (C) 2014 Ivan Kravets" -__pkgmanifesturl__ = "http://platformio.ikravets.com/packages/manifest.json" +__apiurl__ = "http://api.platformio.ikravets.com" +__pkgmanifesturl__ = "http://dl.platformio.ikravets.com/packages/manifest.json" diff --git a/platformio/__main__.py b/platformio/__main__.py index 3fa96c6f5c..ab1cceb3fa 100644 --- a/platformio/__main__.py +++ b/platformio/__main__.py @@ -15,7 +15,7 @@ from platformio.util import get_home_dir, get_source_dir -class PlatformioCLI(MultiCommand): +class PlatformioCLI(MultiCommand): # pylint: disable=R0904 def list_commands(self, ctx): cmds = [] diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 97c0be782b..07fd7725b6 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -16,7 +16,8 @@ from SCons.Script import (DefaultEnvironment, Exit, SConscript, SConscriptChdir, Variables) -from platformio.util import get_pioenvs_dir, get_project_dir, get_source_dir +from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir, + get_source_dir) # AllowSubstExceptions() @@ -57,6 +58,7 @@ BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"), LIBSOURCE_DIRS=[ join("$PROJECT_DIR", "lib"), + get_lib_dir(), join("$PLATFORMFW_DIR", "libraries"), ] ) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index 103ca4b559..5285309fec 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -165,8 +165,9 @@ def delete_tmpcpp(files): remove(f) tmpcpp = [] - - for item in env.Glob(join("$PROJECT_DIR", "src", "*.ino")): + items = (env.Glob(join("$PROJECT_DIR", "src", "*.ino")) + + env.Glob(join("$PROJECT_DIR", "src", "*.pde"))) + for item in items: cppfile = item.get_path()[:-3] + "cpp" if isfile(cppfile): continue diff --git a/platformio/commands/lib.py b/platformio/commands/lib.py new file mode 100644 index 0000000000..9de31be267 --- /dev/null +++ b/platformio/commands/lib.py @@ -0,0 +1,173 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +import click + +from platformio.exception import LibAlreadyInstalledError +from platformio.libmanager import LibraryManager +from platformio.util import get_api_result, get_lib_dir + + +@click.group(short_help="Library Manager") +def cli(): + pass + + +@cli.command("search", short_help="Search for library") +@click.option("-a", "--author", multiple=True) +@click.option("-k", "--keyword", multiple=True) +@click.argument("query") +def lib_search(query, author, keyword): + for key, values in dict(author=author, keyword=keyword).iteritems(): + for value in values: + query += ' %s:"%s"' % (key, value) + + result = get_api_result("/lib/search", dict(query=query)) + click.secho("Found %d libraries:" % result['total'], + fg="green" if result['total'] else "yellow") + + while True: + for item in result['items']: + click.echo("{name:<30} {description}".format( + name=click.style(item['name'], fg="cyan"), + description=item['description'] + )) + + if int(result['page'])*int(result['perpage']) >= int(result['total']): + break + + if click.confirm("Show next libraries?"): + result = get_api_result( + "/lib/search", + dict(query=query, page=str(int(result['page']) + 1)) + ) + else: + break + + +@cli.command("install", short_help="Install library") +@click.argument("names", nargs=-1) +@click.option("-v", "--version") +def lib_install_cli(names, version): + lib_install(names, version) + + +def lib_install(names, version=None): + lm = LibraryManager(get_lib_dir()) + for name in names: + click.echo("Installing %s library:" % click.style(name, fg="cyan")) + try: + if lm.install(name, version): + click.secho( + "The library '%s' has been successfully installed!" % + name, fg="green") + info = lm.get_info(name) + if "dependencies" in info: + click.secho("Installing dependencies:", fg="yellow") + lib_install(info['dependencies']) + + except LibAlreadyInstalledError: + click.secho("Already installed", fg="yellow") + + +@cli.command("uninstall", short_help="Uninstall libraries") +@click.argument("names", nargs=-1) +def lib_uninstall_cli(names): + lib_uninstall(names) + + +def lib_uninstall_dependency(dependency): + lm = LibraryManager(get_lib_dir()) + + for name in lm.get_installed(): + info = lm.get_info(name) + if dependency in info.get("dependencies", []): + return + + lib_uninstall([dependency]) + + +def lib_uninstall(names): + lm = LibraryManager(get_lib_dir()) + for name in names: + info = lm.get_info(name) + if lm.uninstall(name): + # find dependencies + if "dependencies" in info: + for d in info['dependencies']: + lib_uninstall_dependency(d) + + click.secho("The library '%s' has been successfully " + "uninstalled!" % name, fg="green") + + +@cli.command("list", short_help="List installed libraries") +def lib_list(): + lm = LibraryManager(get_lib_dir()) + for name in lm.get_installed(): + info = lm.get_info(name) + click.echo("{name:<30} {description}".format( + name=click.style(info['name'], fg="cyan"), + description=info['description'] + )) + + +@cli.command("show", short_help="Show details about installed libraries") +@click.argument("name") +def lib_show(name): + lm = LibraryManager(get_lib_dir()) + info = lm.get_info(name) + click.secho(info['name'], fg="cyan") + click.echo("-" * len(info['name'])) + + if "author" in info: + _data = [] + for k in ("name", "email"): + if k in info['author'] and info['author'][k] is not None: + _value = info['author'][k] + if k == "email": + _value = "<%s>" % _value + _data.append(_value) + click.echo("Author: %s" % " ".join(_data)) + + click.echo("Keywords: %s" % info['keywords']) + click.echo("Version: %s" % info['version']) + click.echo() + click.echo(info['description']) + click.echo() + + +@cli.command("update", short_help="Update installed libraries") +def lib_update(): + lm = LibraryManager(get_lib_dir()) + lib_names = lm.get_installed() + versions = get_api_result("/lib/version/" + ",".join(lib_names)) + + for name in lib_names: + info = lm.get_info(name) + + click.echo("Updating %s library:" % click.style(name, fg="yellow")) + + current_version = info['version'] + latest_version = versions[name] + + click.echo("Versions: Current=%s, Latest=%s \t " % ( + current_version, latest_version), nl=False) + + if current_version == latest_version: + click.echo("[%s]" % (click.style("Up-to-date", fg="green"))) + continue + else: + click.echo("[%s]" % (click.style("Out-of-date", fg="red"))) + + lib_uninstall([name]) + lib_install([name]) + + +@cli.command("register", short_help="Register new library") +@click.argument("config_url") +def lib_register(config_url): + result = get_api_result("/lib/register", data=dict(config_url=config_url)) + if "message" in result and result['message']: + click.secho(result['message'], fg="green" if "successed" in result and + result['successed'] else "red") diff --git a/platformio/commands/show.py b/platformio/commands/show.py index 616a7a519e..38cb4212fb 100644 --- a/platformio/commands/show.py +++ b/platformio/commands/show.py @@ -10,7 +10,7 @@ from platformio.platforms.base import PlatformFactory -@command("show", short_help="Show details about an installed platforms") +@command("show", short_help="Show details about installed platforms") @argument("platform") def cli(platform): p = PlatformFactory().newPlatform(platform) diff --git a/platformio/exception.py b/platformio/exception.py index 046ad0846e..920ee521e3 100644 --- a/platformio/exception.py +++ b/platformio/exception.py @@ -105,3 +105,17 @@ class GetSerialPortsError(PlatformioException): class GetLatestVersionError(PlatformioException): MESSAGE = "Can't retrieve latest PlatformIO version" + + +class APIRequestError(PlatformioException): + + MESSAGE = "[API] %s" + + +class LibAlreadyInstalledError(PlatformioException): + pass + + +class LibNotInstalledError(PlatformioException): + + MESSAGE = "Library '%s' has not been installed yet" diff --git a/platformio/libmanager.py b/platformio/libmanager.py new file mode 100644 index 0000000000..2fb4a18587 --- /dev/null +++ b/platformio/libmanager.py @@ -0,0 +1,75 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +import json +from os import listdir, makedirs, remove +from os.path import isdir, isfile, join +from shutil import rmtree +from tempfile import gettempdir + +from platformio.downloader import FileDownloader +from platformio.exception import LibAlreadyInstalledError, LibNotInstalledError +from platformio.unpacker import FileUnpacker +from platformio.util import get_api_result + + +class LibraryManager(object): + + CONFIG_NAME = "library.json" + + def __init__(self, lib_dir): + self.lib_dir = lib_dir + + @staticmethod + def download(url, dest_dir): + fd = FileDownloader(url, dest_dir) + fd.start() + return fd.get_filepath() + + @staticmethod + def unpack(pkgpath, dest_dir): + fu = FileUnpacker(pkgpath, dest_dir) + return fu.start() + + def get_installed(self): + items = [] + for item in listdir(self.lib_dir): + conf_path = join(self.lib_dir, item, self.CONFIG_NAME) + if isfile(conf_path): + items.append(item) + return items + + def get_info(self, name): + conf_path = join(self.lib_dir, name, self.CONFIG_NAME) + if not isfile(conf_path): + raise LibNotInstalledError(name) + with open(conf_path, "r") as f: + return json.load(f) + + def is_installed(self, name): + return isfile(join(self.lib_dir, name, self.CONFIG_NAME)) + + def install(self, name, version=None): + if self.is_installed(name): + raise LibAlreadyInstalledError() + + _lib_dir = join(self.lib_dir, name) + if not isdir(_lib_dir): + makedirs(_lib_dir) + + dlinfo = get_api_result("/lib/download/" + name, dict(version=version) + if version else None) + try: + dlpath = self.download(dlinfo['url'], gettempdir()) + self.unpack(dlpath, _lib_dir) + finally: + remove(dlpath) + + return self.is_installed(name) + + def uninstall(self, name): + if self.is_installed(name): + rmtree(join(self.lib_dir, name)) + return True + else: + raise LibNotInstalledError(name) diff --git a/platformio/util.py b/platformio/util.py index 8fb6363ba9..c29347d95a 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -8,9 +8,14 @@ from subprocess import PIPE, Popen from time import sleep +from requests import get, post +from requests.exceptions import ConnectionError, HTTPError +from requests.utils import default_user_agent from serial import Serial -from platformio.exception import GetSerialPortsError, NotPlatformProject +from platformio import __apiurl__, __version__ +from platformio.exception import (APIRequestError, GetSerialPortsError, + NotPlatformProject) try: from configparser import ConfigParser @@ -26,9 +31,27 @@ def get_systype(): def get_home_dir(): + try: + config = get_project_config() + if (config.has_section("platformio") and + config.has_option("platformio", "home_dir")): + return config.get("platformio", "home_dir") + except NotPlatformProject: + pass return expanduser("~/.platformio") +def get_lib_dir(): + try: + config = get_project_config() + if (config.has_section("platformio") and + config.has_option("platformio", "lib_dir")): + return config.get("platformio", "lib_dir") + except NotPlatformProject: + pass + return join(get_home_dir(), "lib") + + def get_source_dir(): return dirname(realpath(__file__)) @@ -89,3 +112,31 @@ def get_serialports(): else: raise GetSerialPortsError(os_name) return[{"port": p, "description": d, "hwid": h} for p, d, h in comports()] + + +def get_api_result(path, params=None, data=None): + result = None + r = None + try: + headers = {"User-Agent": "PlatformIO/%s %s" % ( + __version__, default_user_agent())} + if data: + r = post(__apiurl__ + path, params=params, data=data, + headers=headers) + else: + r = get(__apiurl__ + path, params=params, headers=headers) + result = r.json() + r.raise_for_status() + except HTTPError as e: + if result and "errors" in result: + raise APIRequestError(result['errors'][0]['title']) + else: + raise APIRequestError(e) + except ConnectionError: + raise APIRequestError("Could not connect to PlatformIO API Service") + except ValueError: + raise APIRequestError("Invalid response: %s" % r.text) + finally: + if r: + r.close() + return result diff --git a/requirements.txt b/requirements.txt index ffd41083bd..984e12bdab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -click==2.5 +click==3.3 colorama==0.3.1 pyserial==2.7 -requests==2.3.0 +requests==2.4.1 scons==2.3.0