diff --git a/HISTORY.rst b/HISTORY.rst index 2fbabd97..8d0e1d88 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,10 +1,35 @@ Release History =============== +2.0.1 (2015-??-??) +------------------ + +* Handle new environment variables + `PLATFORMIO_BUILD_FLAGS `_ + and `PLATFORMIO_LDF_CYCLIC `_ +* Pass to API requests information about Continuous Integration system. This + information will be used by PlatformIO-API. +* Use ``include`` directories from toolchain when initialising project for IDE + (`issue #210 `_) +* Added support for new WildFire boards from + `Wicked Device `_ to + `atmelavr `__ + platform +* Updated `Arduino Framework `__ to + 1.6.4 version (`issue #212 `_) +* Handle Atmel AVR Symbols when initialising project for IDE + (`issue #216 `_) +* Fixed bug with converting ``*.ino`` to ``*.cpp`` +* Fixed failing with ``platformio init --ide eclipse`` without boards + (`issue #217 `_) + 2.0.0 (2015-05-22) ------------------ -* PlatformIO as :ref:`ci` (CI) tool for embedded projects +*Made in* `Paradise `_ + +* PlatformIO as `Continuous Integration `_ + (CI) tool for embedded projects (`issue #108 `_) * Initialise PlatformIO project for the specified IDE (`issue #151 `_) @@ -80,7 +105,7 @@ Release History `teensy `__ platform * Added support for new Arduino based boards by *SparkFun, BQ, LightUp, - LowPowerLab, Quirkbot, RedBearLab, TinyCircuits, WickedDevice* to + LowPowerLab, Quirkbot, RedBearLab, TinyCircuits* to `atmelavr `__ platform * Upgraded `Arduino Framework `__ to diff --git a/docs/ci/travis.rst b/docs/ci/travis.rst index 4c5e9e34..8eeff63d 100644 --- a/docs/ci/travis.rst +++ b/docs/ci/travis.rst @@ -44,6 +44,8 @@ Please put ``.travis.yml`` to the root directory of the GitHub repository. - platformio ci --board=TYPE_1 --board=TYPE_2 --board=TYPE_N +Then see step 1, 2, and step 4 here: http://docs.travis-ci.com/user/getting-started/ + For more details as for PlatformIO build process please look into :ref:`cmd_ci` command. @@ -60,13 +62,22 @@ Examples - "2.7" env: - - PLATFORMIO_CI_SRC=examples/Bluetooth/PS3SPP/PS3SPP.ino - - PLATFORMIO_CI_SRC=examples/pl2303/pl2303_gps/pl2303_gps.ino + - PLATFORMIO_CI_SRC=examples/acm/acm_terminal + - PLATFORMIO_CI_SRC=examples/Bluetooth/WiiIRCamera PLATFORMIO_BUILD_FLAGS="-DWIICAMERA" + - PLATFORMIO_CI_SRC=examples/ftdi/USBFTDILoopback + - PLATFORMIO_CI_SRC=examples/Xbox/XBOXUSB + # - ... install: - python -c "$(curl -fsSL https://raw.githubusercontent.com/platformio/platformio/master/scripts/get-platformio.py)" - - wget https://github.com/xxxajk/spi4teensy3/archive/master.zip -O /tmp/spi4teensy3.zip - - unzip /tmp/spi4teensy3.zip -d /tmp + + # Libraries from PlatformIO Library Registry + # http://platformio.org/#!/lib/show/416/TinyGPS + # http://platformio.org/#!/lib/show/417/SPI4Teensy3 + - platformio lib install 416 417 script: - - platformio ci --lib="." --lib="/tmp/spi4teensy3-master" --board=uno --board=teensy31 --board=due + - platformio ci --board=uno --board=teensy31 --board=due --lib="." + +* Configuration file: https://github.com/felis/USB_Host_Shield_2.0/blob/master/.travis.yml +* Build History: https://travis-ci.org/felis/USB_Host_Shield_2.0 diff --git a/docs/envvars.rst b/docs/envvars.rst index 765ec0a3..25414e27 100644 --- a/docs/envvars.rst +++ b/docs/envvars.rst @@ -36,44 +36,53 @@ In other words, ``CI=true`` automatically setup PLATFORMIO_HOME_DIR ~~~~~~~~~~~~~~~~~~~ -Allows to override :ref:`projectconf` option -:ref:`projectconf_pio_home_dir`. +Allows to override :ref:`projectconf` option :ref:`projectconf_pio_home_dir`. .. _envvar_PLATFORMIO_LIB_DIR: PLATFORMIO_LIB_DIR ~~~~~~~~~~~~~~~~~~ -Allows to override :ref:`projectconf` option -:ref:`projectconf_pio_lib_dir`. +Allows to override :ref:`projectconf` option :ref:`projectconf_pio_lib_dir`. .. _envvar_PLATFORMIO_SRC_DIR: PLATFORMIO_SRC_DIR ~~~~~~~~~~~~~~~~~~ -Allows to override :ref:`projectconf` option -:ref:`projectconf_pio_src_dir`. +Allows to override :ref:`projectconf` option :ref:`projectconf_pio_src_dir`. .. _envvar_PLATFORMIO_ENVS_DIR: PLATFORMIO_ENVS_DIR ~~~~~~~~~~~~~~~~~~~ -Allows to override :ref:`projectconf` option -:ref:`projectconf_pio_envs_dir`. +Allows to override :ref:`projectconf` option :ref:`projectconf_pio_envs_dir`. Builder ------- +.. _envvar_PLATFORMIO_BUILD_FLAGS: + +PLATFORMIO_BUILD_FLAGS +~~~~~~~~~~~~~~~~~~~~~~ + +Allows to set :ref:`projectconf` option :ref:`projectconf_build_flags`. + .. _envvar_PLATFORMIO_SRCBUILD_FLAGS: PLATFORMIO_SRCBUILD_FLAGS ~~~~~~~~~~~~~~~~~~~~~~~~~ -Allows to override :ref:`projectconf` option -:ref:`projectconf_srcbuild_flags`. +Allows to set :ref:`projectconf` option :ref:`projectconf_srcbuild_flags`. + +.. _envvar_PLATFORMIO_LDF_CYCLIC: + +PLATFORMIO_LDF_CYCLIC +~~~~~~~~~~~~~~~~~~~~~ + +Allows to set :ref:`projectconf` option :ref:`projectconf_ldf_cyclic`. Settings -------- diff --git a/docs/frameworks/arduino.rst b/docs/frameworks/arduino.rst index 5804f7f7..b0b06738 100644 --- a/docs/frameworks/arduino.rst +++ b/docs/frameworks/arduino.rst @@ -923,8 +923,8 @@ TinyCircuits - 32 Kb - 2 Kb -WickedDevice -~~~~~~~~~~~~ +Wicked Device +~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 @@ -937,14 +937,14 @@ WickedDevice - RAM * - ``wildfirev2`` - - `WickedDevice WildFire v2 [stk500] `_ + - `Wicked Device WildFire V2 `_ - ATMEGA1284P - 16 MHz - 128 Kb - 16 Kb * - ``wildfirev3`` - - `WickedDevice WildFire v3 [optiboot] `_ + - `Wicked Device WildFire V3 `_ - ATMEGA1284P - 16 MHz - 128 Kb diff --git a/docs/ide/eclipse.rst b/docs/ide/eclipse.rst index 2549c24d..ee89db47 100644 --- a/docs/ide/eclipse.rst +++ b/docs/ide/eclipse.rst @@ -29,12 +29,13 @@ Integration Project Generator ^^^^^^^^^^^^^^^^^ -Since PlatformIO 2.0 you can generate Eclipse compatible project using -:option:`platformio init --ide` command: +SSince PlatformIO 2.0 you can generate Eclipse compatible project using +:option:`platformio init --ide` command. Please choose board type using +:ref:`cmd_boards` command and run: .. code-block:: shell - platformio init --ide eclipse + platformio init --ide eclipse --board %TYPE% Then import this project via ``File > Import... > General > Existing Projects into Workspace > Next`` and specify root directory where is located diff --git a/docs/ide/qtcreator.rst b/docs/ide/qtcreator.rst index 31bc7cde..d5d97994 100644 --- a/docs/ide/qtcreator.rst +++ b/docs/ide/qtcreator.rst @@ -21,12 +21,13 @@ Integration Project Generator ^^^^^^^^^^^^^^^^^ -Since PlatformIO 2.0 you can generate Eclipse compatible project using -:option:`platformio init --ide` command: +Since PlatformIO 2.0 you can generate Qt Creator compatible project using +:option:`platformio init --ide` command. Please choose board type using +:ref:`cmd_boards` command and run: .. code-block:: shell - platformio init --ide qtcreator + platformio init --ide qtcreator --board %TYPE% Then import this project via ``File > New File or Project > Import Project`` and specify root directory where is located :ref:`projectconf`. diff --git a/docs/ide/sublimetext.rst b/docs/ide/sublimetext.rst index af39f328..9e6ab34e 100644 --- a/docs/ide/sublimetext.rst +++ b/docs/ide/sublimetext.rst @@ -21,12 +21,13 @@ Integration Project Generator ^^^^^^^^^^^^^^^^^ -Since PlatformIO 2.0 you can generate Eclipse compatible project using -:option:`platformio init --ide` command: +Since PlatformIO 2.0 you can generate Sublime Text compatible project using +:option:`platformio init --ide` command. Please choose board type using +:ref:`cmd_boards` command and run: .. code-block:: shell - platformio init --ide sublimetext + platformio init --ide sublimetext --board %TYPE% Then import this project via ``Project > Open Project...`` and specify root directory where is located :ref:`projectconf`. @@ -44,17 +45,17 @@ described below: .. code-block:: bash { - "cmd": ["platformio", "run"], + "cmd": ["platformio", "--force", "run"], "working_dir": "${project_path:${folder}}", "variants": [ { "name": "Clean", - "cmd": ["platformio", "run", "-t", "clean"] + "cmd": ["platformio", "--force", "run", "--target", "clean"] }, { "name": "Upload", - "cmd": ["platformio", "run", "-t", "upload"] + "cmd": ["platformio", "--force", "run", "--target", "upload"] } ] } diff --git a/docs/ide/vim.rst b/docs/ide/vim.rst index ae1116f6..a9ccc115 100644 --- a/docs/ide/vim.rst +++ b/docs/ide/vim.rst @@ -30,10 +30,10 @@ Put to the project directory ``Makefile`` wrapper with contents: #PATH := /usr/local/bin:$(PATH) all: - platformio run -t upload + platformio --force run --target upload clean: - platformio run -t clean + platformio --force run --target clean Now, in VIM ``cd /path/to/this/project`` and press ``Ctrl+B`` or ``Cmd+B`` diff --git a/docs/ide/visualstudio.rst b/docs/ide/visualstudio.rst index f5275532..4afb100d 100644 --- a/docs/ide/visualstudio.rst +++ b/docs/ide/visualstudio.rst @@ -21,15 +21,16 @@ Integration Project Generator ^^^^^^^^^^^^^^^^^ -Since PlatformIO 2.0 you can generate Eclipse compatible project using -:option:`platformio init --ide` command: +Since PlatformIO 2.0 you can generate Visual Studio compatible project using +:option:`platformio init --ide` command. Please choose board type using +:ref:`cmd_boards` command and run: .. code-block:: shell - platformio init --ide visualstudio + platformio init --ide visualstudio --board %TYPE% -Then import this project via ``File > Import ...`` and specify root directory -where is located :ref:`projectconf`. +Then import this project via ``File->Open->Project/Solution`` and specify root +directory where is located :ref:`projectconf`. Manual Integration ^^^^^^^^^^^^^^^^^^ diff --git a/docs/librarymanager/index.rst b/docs/librarymanager/index.rst index 994437fd..7f00a0bd 100644 --- a/docs/librarymanager/index.rst +++ b/docs/librarymanager/index.rst @@ -8,8 +8,10 @@ Library Manager *"The missing library manager for development platforms"* [#]_ *PlatformIO Library Manager* allows you to organize external embedded libraries. -You can search for new libraries via :ref:`Command Line interface ` -or `Web 2.0 Library Search `_. +You can search for new libraries via + +* :ref:`Command Line interface ` +* `Web 2.0 Library Search `_ 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. diff --git a/docs/platforms/atmelavr.rst b/docs/platforms/atmelavr.rst index 5cc1c84e..048b7bef 100644 --- a/docs/platforms/atmelavr.rst +++ b/docs/platforms/atmelavr.rst @@ -816,8 +816,8 @@ TinyCircuits - 32 Kb - 2 Kb -WickedDevice -~~~~~~~~~~~~ +Wicked Device +~~~~~~~~~~~~~ .. list-table:: :header-rows: 1 @@ -830,14 +830,14 @@ WickedDevice - RAM * - ``wildfirev2`` - - `WickedDevice WildFire v2 [stk500] `_ + - `Wicked Device WildFire V2 `_ - ATMEGA1284P - 16 MHz - 128 Kb - 16 Kb * - ``wildfirev3`` - - `WickedDevice WildFire v3 [optiboot] `_ + - `Wicked Device WildFire V3 `_ - ATMEGA1284P - 16 MHz - 128 Kb diff --git a/docs/projectconf.rst b/docs/projectconf.rst index 698a8762..8aba9efe 100644 --- a/docs/projectconf.rst +++ b/docs/projectconf.rst @@ -270,6 +270,9 @@ processes: - Add the directory *dir* to the list of directories to be searched for header files. +This option can be set by global environment variable +:ref:`envvar_PLATFORMIO_BUILD_FLAGS`. + Example: .. code-block:: ini @@ -306,7 +309,7 @@ An option ``srcbuild_flags`` has the same behaviour like ``build_flags`` but will be applied only for the project source code from :ref:`projectconf_pio_src_dir` directory. -This option can be overridden by global environment variable +This option can be set by global environment variable :ref:`envvar_PLATFORMIO_SRCBUILD_FLAGS`. ``install_libs`` @@ -328,7 +331,7 @@ Example: ``use_libs`` ^^^^^^^^^^^^ -Specify libraries which should be used by ``Library Dependency Finder`` with +Specify libraries which should be used by ``Library Dependency Finder (LDF)`` with the highest priority. Example: @@ -341,7 +344,7 @@ Example: ``ignore_libs`` ^^^^^^^^^^^^^^^ -Specify libraries which should be ignored by ``Library Dependency Finder`` +Specify libraries which should be ignored by ``Library Dependency Finder (LDF)`` Example: @@ -350,6 +353,30 @@ Example: [env:ignore_some_libs] ignore_libs = SPI,EngduinoV3_ID123 +.. _projectconf_ldf_cyclic: + +``ldf_cyclic`` +^^^^^^^^^^^^^^ + +Control cyclic (recursive) behaviour for ``Library Dependency Finder (LDF)``. +By default, this option is turned OFF (``ldf_cyclic=False``) and means, that +``LDF`` will find only libraries which are included in source files from the +project :ref:`projectconf_pio_src_dir`. + +If you want to enable cyclic (recursive, nested) search, please set this option +to ``True``. Founded library will be treated like a new source files and +``LDF`` will search dependencies for it. + +This option can be set by global environment variable +:ref:`envvar_PLATFORMIO_LDF_CYCLIC`. + +Example: + +.. code-block:: ini + + [env:libs_with_enabled_ldf_cyclic] + ldf_cyclic = True + .. _projectconf_examples: diff --git a/platformio/__init__.py b/platformio/__init__.py index 0864a676..a38b7a47 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (2, 0, 0) +VERSION = (2, 0, 1) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/boards/misc.json b/platformio/boards/misc.json index b9f7dba6..fbcbf031 100644 --- a/platformio/boards/misc.json +++ b/platformio/boards/misc.json @@ -250,50 +250,6 @@ "vendor": "TinyCircuits" }, - "wildfirev3": { - "build": { - "core": "arduino", - "extra_flags": "-DARDUINO_ARCH_AVR", - "f_cpu": "16000000L", - "mcu": "atmega1284p", - "variant": "wildfirev3" - }, - "frameworks": ["arduino"], - "name": "WickedDevice WildFire v3 [optiboot]", - "platform": "atmelavr", - "upload": { - "maximum_ram_size": 16384, - "maximum_size": 130048, - "protocol": "arduino", - "require_upload_port" : true, - "speed": 115200 - }, - "url": "http://shop.wickeddevice.com/resources/wildfire/", - "vendor": "WickedDevice" - }, - - "wildfirev2": { - "build": { - "core": "arduino", - "extra_flags": "-DARDUINO_ARCH_AVR", - "f_cpu": "16000000L", - "mcu": "atmega1284p", - "variant": "wildfirev2" - }, - "frameworks": ["arduino"], - "name": "WickedDevice WildFire v2 [stk500]", - "platform": "atmelavr", - "upload": { - "maximum_ram_size": 16384, - "maximum_size": 122878, - "protocol": "wiring", - "require_upload_port" : true, - "speed": 38400 - }, - "url": "http://shop.wickeddevice.com/resources/wildfire/#arduinoidesetup", - "vendor": "WickedDevice" - }, - "blend": { "build": { "core": "arduino", @@ -521,5 +477,49 @@ }, "url": "http://quirkbot.com", "vendor": "Quirkbot" + }, + + "wildfirev2": { + "build": { + "core": "arduino", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_MEGA", + "f_cpu": "16000000L", + "mcu": "atmega1284p", + "variant": "wildfirev2" + }, + "frameworks": ["arduino"], + "name": "Wicked Device WildFire V2", + "platform": "atmelavr", + "upload": { + "maximum_ram_size": 16384, + "maximum_size": 122878, + "protocol": "wiring", + "require_upload_port" : true, + "speed": 38400 + }, + "url": "http://shop.wickeddevice.com/resources/wildfire/", + "vendor": "Wicked Device" + }, + + "wildfirev3": { + "build": { + "core": "arduino", + "extra_flags": "-DARDUINO_ARCH_AVR -DARDUINO_AVR_MEGA", + "f_cpu": "16000000L", + "mcu": "atmega1284p", + "variant": "wildfirev3" + }, + "frameworks": ["arduino"], + "name": "Wicked Device WildFire V3", + "platform": "atmelavr", + "upload": { + "maximum_ram_size": 16384, + "maximum_size": 130048, + "protocol": "arduino", + "require_upload_port" : true, + "speed": 115200 + }, + "url": "http://shop.wickeddevice.com/resources/wildfire/", + "vendor": "Wicked Device" } } diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 45ec63d6..4b07953e 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -38,6 +38,7 @@ commonvars.AddVariables( ("SRCBUILD_FLAGS",), ("IGNORE_LIBS",), ("USE_LIBS",), + ("LDF_CYCLIC",), # board options ("BOARD",), diff --git a/platformio/builder/scripts/ststm32.py b/platformio/builder/scripts/ststm32.py index 0855457d..c1622028 100644 --- a/platformio/builder/scripts/ststm32.py +++ b/platformio/builder/scripts/ststm32.py @@ -53,6 +53,8 @@ env.Append( "${BOARD_OPTIONS['build']['variant'].upper()}" ], + LIBS=["stdc++", "nosys"], + LINKFLAGS=[ "-nostartfiles", "-nostdlib" diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index 656473b7..7eae3b34 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -4,6 +4,7 @@ import atexit import json import re +from glob import glob from os import getenv, listdir, remove, sep, walk from os.path import basename, dirname, isdir, isfile, join, normpath @@ -47,10 +48,11 @@ def BuildFirmware(env): _LIBFLAGS=" -Wl,--end-group" ) - _srcbuild_flags = getenv("PLATFORMIO_SRCBUILD_FLAGS", - env.subst("$SRCBUILD_FLAGS")) - if _srcbuild_flags: - firmenv.MergeFlags(_srcbuild_flags) + # Handle SRCBUILD_FLAGS + if getenv("PLATFORMIO_SRCBUILD_FLAGS", None): + firmenv.MergeFlags(getenv("PLATFORMIO_SRCBUILD_FLAGS")) + if "SRCBUILD_FLAGS" in env: + firmenv.MergeFlags(env['SRCBUILD_FLAGS']) firmenv.Append( CPPDEFINES=["PLATFORMIO={0:02d}{1:02d}{2:02d}".format( @@ -62,18 +64,13 @@ def BuildFirmware(env): Exit() if "idedata" in COMMAND_LINE_TARGETS: - _data = {"defines": [], "includes": []} - for item in env.get("VARIANT_DIRS", []): - _data['includes'].append(env.subst(item[1])) - for item in env.get("CPPDEFINES", []): - _data['defines'].append(env.subst(item)) - print json.dumps(_data) + print json.dumps(env.DumpIDEData()) Exit() return firmenv.Program( join("$BUILD_DIR", "firmware"), [firmenv.GlobCXXFiles(vdir) for vdir in vdirs], - LIBS=list(env.get("LIBS", []) + deplibs)[::-1], + LIBS=env.get("LIBS", []) + deplibs, LIBPATH=env.get("LIBPATH", []) + ["$BUILD_DIR"], PROGSUFFIX=".elf" ) @@ -83,6 +80,9 @@ def ProcessFlags(env): if "extra_flags" in env.get("BOARD_OPTIONS", {}).get("build", {}): env.MergeFlags(env.subst("${BOARD_OPTIONS['build']['extra_flags']}")) + # Handle BUILD_FLAGS + if getenv("PLATFORMIO_BUILD_FLAGS", None): + env.MergeFlags(getenv("PLATFORMIO_BUILD_FLAGS")) if "BUILD_FLAGS" in env: env.MergeFlags(env['BUILD_FLAGS']) @@ -97,8 +97,8 @@ def ProcessFlags(env): def GlobCXXFiles(env, path): files = [] - for suff in ["*.c", "*.cpp", "*.S"]: - _list = env.Glob(join(path, suff)) + for suff in ["c", "cpp", "S", "spp", "SPP", "sx", "s", "asm", "ASM"]: + _list = env.Glob(join(path, "*.%s" % suff)) if _list: files += _list return files @@ -278,23 +278,24 @@ def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914 len(state['ordered']) + 1, finder.getLibName(), _lib_dir)) state['libs'].add(_lib_dir) - state = _process_src_dir(state, _lib_dir) + + if getenv("PLATFORMIO_LDF_CYCLIC", + env.subst("$LDF_CYCLIC")).lower() == "true": + state = _process_src_dir(state, _lib_dir) return state # end internal prototypes deplibs = _get_dep_libs(src_dir) - env.Prepend( - CPPPATH=[join("$BUILD_DIR", l) for (l, _) in deplibs] - ) - - # add automatically "utility" dir from the lib (Arduino issue) - env.Prepend( - CPPPATH=[ - join("$BUILD_DIR", l, "utility") for (l, ld) in deplibs - if isdir(join(ld, "utility")) - ] - ) + for l, ld in deplibs: + env.Append( + CPPPATH=[join("$BUILD_DIR", l)] + ) + # add automatically "utility" dir from the lib (Arduino issue) + if isdir(join(ld, "utility")): + env.Append( + CPPPATH=[join("$BUILD_DIR", l, "utility")] + ) libs = [] for (libname, inc_dir) in deplibs: @@ -309,8 +310,8 @@ class InoToCPPConverter(object): PROTOTYPE_RE = re.compile( r"""^( - (?:\s*[a-z_\d]+){1,2} # return type - \s+[a-z_\d]+\s* # name of prototype + (\s*[a-z_\d]+){1,2} # return type + (\s+[a-z_\d]+\s*) # name of prototype \([a-z_,\.\*\&\[\]\s\d]*\) # arguments )\s*\{ # must end with { """, @@ -319,7 +320,8 @@ class InoToCPPConverter(object): DETECTMAIN_RE = re.compile(r"void\s+(setup|loop)\s*\(", re.M | re.I) - STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|//[^\r\n]*$)", re.M | re.S) + STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|(^|\s+)//[^\r\n]*$)", + re.M | re.S) def __init__(self, nodes): self.nodes = nodes @@ -334,6 +336,15 @@ class InoToCPPConverter(object): else: return " " + def _parse_prototypes(self, contents): + prototypes = [] + reserved_keywords = set(["if", "else", "while"]) + for item in self.PROTOTYPE_RE.findall(contents): + if set([item[1].strip(), item[2].strip()]) & reserved_keywords: + continue + prototypes.append(item[0]) + return prototypes + def append_prototypes(self, fname, contents, prototypes): contents = self.STRIPCOMMENTS_RE.sub(self._replace_comments_callback, contents) @@ -358,7 +369,7 @@ class InoToCPPConverter(object): data = [] for node in self.nodes: ino_contents = node.get_text_contents() - prototypes += self.PROTOTYPE_RE.findall(ino_contents) + prototypes += self._parse_prototypes(ino_contents) item = (basename(node.get_path()), ino_contents) if self.is_main_node(ino_contents): @@ -404,6 +415,38 @@ def ConvertInoToCpp(env): atexit.register(delete_tmpcpp_file, tmpcpp_file) +def DumpIDEData(env): + data = { + "defines": [], + "includes": [] + } + + # includes from framework and libs + for item in env.get("VARIANT_DIRS", []): + data['includes'].append(env.subst(item[1])) + + # includes from toolchain + for item in glob(env.subst( + join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN", + "*", "include"))): + data['includes'].append(item) + + # global symbols + for item in env.get("CPPDEFINES", []): + data['defines'].append(env.subst(item)) + + # special symbol for Atmel AVR MCU + board = env.get("BOARD_OPTIONS", {}) + if board and board['platform'] == "atmelavr": + data['defines'].append( + "__AVR_%s__" % board['build']['mcu'].upper() + .replace("ATMEGA", "ATmega") + .replace("ATTINY", "ATtiny") + ) + + return data + + def exists(_): return True @@ -418,4 +461,5 @@ def generate(env): env.AddMethod(BuildLibrary) env.AddMethod(BuildDependentLibraries) env.AddMethod(ConvertInoToCpp) + env.AddMethod(DumpIDEData) return env diff --git a/platformio/commands/ci.py b/platformio/commands/ci.py index e4b48e07..cf4f5010 100644 --- a/platformio/commands/ci.py +++ b/platformio/commands/ci.py @@ -3,7 +3,7 @@ import stat from glob import glob -from os import chmod, environ, makedirs, remove +from os import chmod, getenv, makedirs, remove from os.path import abspath, basename, isdir, isfile, join from shutil import copyfile, copytree, rmtree from tempfile import mkdtemp @@ -59,7 +59,7 @@ def cli(ctx, src, lib, exclude, board, # pylint: disable=R0913 build_dir, keep_build_dir, project_conf, verbose): if not src: - src = environ.get("PLATFORMIO_CI_SRC", "").split(":") + src = getenv("PLATFORMIO_CI_SRC", "").split(":") if not src: raise click.BadParameter("Missing argument 'src'") diff --git a/platformio/commands/run.py b/platformio/commands/run.py index b61544ba..5b27d1c6 100644 --- a/platformio/commands/run.py +++ b/platformio/commands/run.py @@ -2,7 +2,7 @@ # See LICENSE for details. from datetime import datetime -from os import chdir, getcwd +from os import getcwd from os.path import getmtime, isdir, join from shutil import rmtree from time import time @@ -28,9 +28,7 @@ from platformio.platforms.base import PlatformFactory @click.pass_context def cli(ctx, environment, target, upload_port, # pylint: disable=R0913,R0914 project_dir, verbose): - initial_cwd = getcwd() - chdir(project_dir) - try: + with util.cd(project_dir): config = util.get_project_config() if not config.sections(): @@ -74,8 +72,6 @@ def cli(ctx, environment, target, upload_port, # pylint: disable=R0913,R0914 if not all(results): raise exception.ReturnErrorCode() - finally: - chdir(initial_cwd) class EnvironmentProcessor(object): diff --git a/platformio/downloader.py b/platformio/downloader.py index 7520446d..04227029 100644 --- a/platformio/downloader.py +++ b/platformio/downloader.py @@ -3,7 +3,6 @@ from email.utils import parsedate_tz from math import ceil -from os import environ from os.path import getsize, join from time import mktime @@ -50,7 +49,7 @@ class FileDownloader(object): f = open(self._destination, "wb") chunks = int(ceil(self.get_size() / float(self.CHUNK_SIZE))) - if environ.get("CI") == "true": + if util.is_ci(): click.echo("Downloading...") for _ in range(0, chunks): f.write(next(itercontent)) diff --git a/platformio/ide/projectgenerator.py b/platformio/ide/projectgenerator.py index fda18e9e..e98282cb 100644 --- a/platformio/ide/projectgenerator.py +++ b/platformio/ide/projectgenerator.py @@ -26,16 +26,16 @@ class ProjectGenerator(object): 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 + def get_project_env(self): + data = {"env_name": "PlatformIO"} + with util.cd(self.project_dir): + 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 @util.memoized @@ -44,7 +44,8 @@ class ProjectGenerator(object): if "env_name" not in envdata: return None result = util.exec_command( - ["platformio", "run", "-t", "idedata", "-e", envdata['env_name']] + ["platformio", "run", "-t", "idedata", "-e", envdata['env_name'], + "--project-dir", self.project_dir] ) if result['returncode'] != 0 or '{"includes":' not in result['out']: return None diff --git a/platformio/ide/tpls/qtcreator/platformio.pro.user.tpl b/platformio/ide/tpls/qtcreator/platformio.pro.user.tpl index 72ecb9ad..c6035cca 100644 --- a/platformio/ide/tpls/qtcreator/platformio.pro.user.tpl +++ b/platformio/ide/tpls/qtcreator/platformio.pro.user.tpl @@ -84,7 +84,7 @@ true - --force run -t clean + --force run --target clean platformio %{buildDir} Custom Process Step @@ -125,7 +125,7 @@ true - --force run -t clean + --force run --target clean platformio %{buildDir} Custom Process Step diff --git a/platformio/ide/tpls/sublimetext/platformio.sublime-project.tpl b/platformio/ide/tpls/sublimetext/platformio.sublime-project.tpl index 4c4855a2..bd785662 100644 --- a/platformio/ide/tpls/sublimetext/platformio.sublime-project.tpl +++ b/platformio/ide/tpls/sublimetext/platformio.sublime-project.tpl @@ -5,6 +5,7 @@ "cmd": [ "platformio", + "--force", "run" ], "name": "PlatformIO", diff --git a/platformio/ide/tpls/visualstudio/platformio.vcxproj.tpl b/platformio/ide/tpls/visualstudio/platformio.vcxproj.tpl index 1a069d7e..2b3aa1f9 100644 --- a/platformio/ide/tpls/visualstudio/platformio.vcxproj.tpl +++ b/platformio/ide/tpls/visualstudio/platformio.vcxproj.tpl @@ -43,7 +43,7 @@ platformio run - platformio run -t clean + platformio run --target clean {";".join(defines)}} {{";".join(includes)}} diff --git a/platformio/maintenance.py b/platformio/maintenance.py index 89d7fbd3..e225aa4f 100644 --- a/platformio/maintenance.py +++ b/platformio/maintenance.py @@ -3,6 +3,7 @@ import re import struct +import sys from os import remove from os.path import isdir, isfile, join from shutil import rmtree @@ -25,6 +26,13 @@ from platformio.util import get_home_dir def on_platformio_start(ctx, force): app.set_session_var("force_option", force) telemetry.on_command(ctx) + + # skip any check operations when upgrade process + args = [str(s).lower() for s in sys.argv[1:] + if not str(s).startswith("-")] + if len(args) > 1 and args[1] == "upgrade": + return + after_upgrade(ctx) try: diff --git a/platformio/telemetry.py b/platformio/telemetry.py index 3662b7f4..0dd676e1 100644 --- a/platformio/telemetry.py +++ b/platformio/telemetry.py @@ -4,9 +4,9 @@ import atexit import platform import re +import sys import threading import uuid -from sys import argv as sys_argv from time import time import click @@ -91,7 +91,8 @@ class MeasurementProtocol(TelemetryBase): self['cd4'] = 1 if app.get_setting("enable_prompts") else 0 def _prefill_screen_name(self): - args = [str(s).lower() for s in sys_argv[1:]] + args = [str(s).lower() for s in sys.argv[1:] + if not str(s).startswith("-")] if not args: return @@ -101,7 +102,7 @@ class MeasurementProtocol(TelemetryBase): cmd_path = args[:1] self['screen_name'] = " ".join([p.title() for p in cmd_path]) - self['cd3'] = " ".join(args) + self['cd3'] = " ".join([str(s).lower() for s in sys.argv[1:]]) def send(self, hittype): if not app.get_setting("enable_telemetry"): diff --git a/platformio/unpacker.py b/platformio/unpacker.py index 34cb3594..482aae96 100644 --- a/platformio/unpacker.py +++ b/platformio/unpacker.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os import chmod, environ +from os import chmod from os.path import join, splitext from tarfile import open as tarfile_open from time import mktime @@ -9,8 +9,8 @@ from zipfile import ZipFile import click +from platformio import util from platformio.exception import UnsupportedArchiveType -from platformio.util import change_filemtime class ArchiveBase(object): @@ -51,7 +51,7 @@ class ZIPArchive(ArchiveBase): @staticmethod def preserve_mtime(item, dest_dir): - change_filemtime( + util.change_filemtime( join(dest_dir, item.filename), mktime(list(item.date_time) + [0]*3) ) @@ -81,7 +81,7 @@ class FileUnpacker(object): raise UnsupportedArchiveType(archpath) def start(self): - if environ.get("CI") == "true": + if util.is_ci(): click.echo("Unpacking...") for item in self._unpacker.get_items(): self._unpacker.extract_item(item, self._dest_dir) diff --git a/platformio/util.py b/platformio/util.py index 6dbad199..b1e512bc 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -55,6 +55,18 @@ class AsyncPipe(Thread): self.join() +class cd(object): + def __init__(self, new_path): + self.new_path = new_path + self.prev_path = os.getcwd() + + def __enter__(self): + os.chdir(self.new_path) + + def __exit__(self, etype, value, traceback): + os.chdir(self.prev_path) + + class memoized(object): ''' Decorator. Caches a function's return value each time it is called. @@ -175,6 +187,10 @@ def change_filemtime(path, time): os.utime(path, (time, time)) +def is_ci(): + return os.getenv("CI", "").lower() == "true" + + def exec_command(*args, **kwargs): result = { "out": None, @@ -246,8 +262,11 @@ def get_logicaldisks(): def get_request_defheaders(): - return {"User-Agent": "PlatformIO/%s %s" % ( - __version__, requests.utils.default_user_agent())} + return {"User-Agent": "PlatformIO/%s CI/%d %s" % ( + __version__, + 1 if is_ci() else 0, + requests.utils.default_user_agent() + )} def get_api_result(path, params=None, data=None): diff --git a/tests/test_examples.py b/tests/test_examples.py index 9ababba2..ab02d640 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -30,8 +30,7 @@ def test_run(platformio_setup, pioproject_dir): rmtree(join(pioproject_dir, ".pioenvs")) result = exec_command( - ["platformio", "run"], - cwd=pioproject_dir + ["platformio", "--force", "run", "--project-dir", pioproject_dir] ) if result['returncode'] != 0: pytest.fail(result) diff --git a/tox.ini b/tox.ini index cafecaca..49706329 100644 --- a/tox.ini +++ b/tox.ini @@ -44,9 +44,8 @@ basepython = py26: python2.6 py27: python2.7 usedevelop = True +passenv = * deps = pytest -setenv = - PLATFORMIO_SETTING_ENABLE_PROMPTS = False commands = {envpython} --version pip install --egg http://sourceforge.net/projects/scons/files/latest/download