diff --git a/HISTORY.rst b/HISTORY.rst index 65235d65..f6be44fa 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,6 +1,15 @@ Release History =============== +2.1.1 (2015-06-09) +------------------ + +* Automatically detect upload port using VID:PID board settings + (`issue #231 `_) +* Improved detection of build changes +* Avoided ``LibInstallDependencyError`` when more then 1 library is found + (`issue #229 `_) + 2.1.0 (2015-06-03) ------------------ diff --git a/README.rst b/README.rst index b3129c0b..aff892be 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,8 @@ PlatformIO .. image:: https://badges.gitter.im/Join%20Chat.svg :alt: Join the chat at https://gitter.im/platformio/platformio :target: https://gitter.im/platformio/platformio +.. image:: https://www.openhub.net/p/platformio/widgets/project_thin_badge.gif + :target: https://www.openhub.net/p/platformio `Website + Library Search `_ | `Documentation `_ | diff --git a/platformio/__init__.py b/platformio/__init__.py index f28df34d..d0de4173 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (2, 1, 0) +VERSION = (2, 1, 1) __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 4b07953e..a9f06099 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -11,7 +11,7 @@ except ImportError: break from platformio import util -from os.path import join +from os.path import isfile, join from time import time from SCons.Script import (DefaultEnvironment, Exit, SConscript, @@ -63,6 +63,7 @@ DefaultEnvironment( PIOHOME_DIR=util.get_home_dir(), PROJECT_DIR=util.get_project_dir(), + PROJECTLIB_DIR=util.get_projectlib_dir(), PROJECTSRC_DIR=util.get_projectsrc_dir(), PIOENVS_DIR=util.get_pioenvs_dir(), @@ -71,7 +72,7 @@ DefaultEnvironment( BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"), LIBSOURCE_DIRS=[ - join("$PROJECT_DIR", "lib"), + "$PROJECTLIB_DIR", util.get_lib_dir(), join("$PLATFORMFW_DIR", "libraries") ] @@ -97,9 +98,11 @@ if "BOARD" in env: UPLOAD_SPEED="${BOARD_OPTIONS['upload'].get('speed', None)}") if "ldscript" in env.get("BOARD_OPTIONS", {}).get("build", {}): env.Replace( - LDSCRIPT_PATH=join( - "$PIOHOME_DIR", "packages", "ldscripts", - "${BOARD_OPTIONS['build']['ldscript']}" + LDSCRIPT_PATH=( + env['BOARD_OPTIONS']['build']['ldscript'] + if isfile(env['BOARD_OPTIONS']['build']['ldscript']) + else join("$PIOHOME_DIR", "packages", "ldscripts", + "${BOARD_OPTIONS['build']['ldscript']}") ) ) diff --git a/platformio/builder/tools/pioupload.py b/platformio/builder/tools/pioupload.py index 4dd2f3d1..1cc75a53 100644 --- a/platformio/builder/tools/pioupload.py +++ b/platformio/builder/tools/pioupload.py @@ -69,18 +69,25 @@ def AutodetectUploadPort(env): if (not item['name'] or not any([l in item['name'].lower() for l in msdlabels])): continue - print "Auto-detected UPLOAD_PORT/DISK: %s" % item['disk'] env.Replace(UPLOAD_PORT=item['disk']) break else: + board_build_opts = env.get("BOARD_OPTIONS", {}).get("build", {}) + board_hwid = ("%s:%s" % ( + board_build_opts.get("vid"), + board_build_opts.get("pid") + )).replace("0x", "") + for item in get_serialports(): if "VID:PID" not in item['hwid']: continue - print "Auto-detected UPLOAD_PORT: %s" % item['port'] env.Replace(UPLOAD_PORT=item['port']) - break + if board_hwid in item['hwid']: + break - if "UPLOAD_PORT" not in env: + if "UPLOAD_PORT" in env: + print "Auto-detected UPLOAD_PORT/DISK: %s" % env['UPLOAD_PORT'] + else: Exit("Error: Please specify `upload_port` for environment or use " "global `--upload-port` option.\n" "For the some development platforms it can be USB flash drive\n") diff --git a/platformio/commands/lib.py b/platformio/commands/lib.py index 7bf31383..b2fed51b 100644 --- a/platformio/commands/lib.py +++ b/platformio/commands/lib.py @@ -142,8 +142,23 @@ def lib_install_dependency(ctx, data): query.append('+"%s"' % data[key]) result = get_api_result("/lib/search", dict(query=" ".join(query))) - assert result['total'] == 1 - ctx.invoke(lib_install, libid=[result['items'][0]['id']]) + assert result['total'] > 0 + + if result['total'] == 1 or not app.get_setting("enable_prompts"): + ctx.invoke(lib_install, libid=[result['items'][0]['id']]) + else: + click.secho( + "Conflict: More then one dependent libraries have been found " + "by request %s:" % json.dumps(data), fg="red") + + echo_liblist_header() + for item in result['items']: + echo_liblist_item(item) + + deplib_id = click.prompt( + "Please choose one dependent library ID", + type=click.Choice([str(i['id']) for i in result['items']])) + ctx.invoke(lib_install, libid=[int(deplib_id)]) @cli.command("uninstall", short_help="Uninstall libraries") diff --git a/platformio/commands/run.py b/platformio/commands/run.py index 5b27d1c6..7f79c506 100644 --- a/platformio/commands/run.py +++ b/platformio/commands/run.py @@ -2,8 +2,9 @@ # See LICENSE for details. from datetime import datetime -from os import getcwd -from os.path import getmtime, isdir, join +from hashlib import sha1 +from os import getcwd, makedirs, walk +from os.path import getmtime, isdir, isfile, join from shutil import rmtree from time import time @@ -38,12 +39,8 @@ def cli(ctx, environment, target, upload_port, # pylint: disable=R0913,R0914 if unknown: raise exception.UnknownEnvNames(", ".join(unknown)) - # remove ".pioenvs" if project config is modified - _pioenvs_dir = util.get_pioenvs_dir() - if (isdir(_pioenvs_dir) and - getmtime(join(util.get_project_dir(), "platformio.ini")) > - getmtime(_pioenvs_dir)): - rmtree(_pioenvs_dir) + # clean obsolete .pioenvs dir + _clean_pioenvs_dir() results = [] for section in config.sections(): @@ -176,3 +173,41 @@ def _autoinstall_libs(ctx, libids_list): ", ".join([str(i) for i in not_intalled_libs]) )): ctx.invoke(cmd_lib_install, libid=not_intalled_libs) + + +def _clean_pioenvs_dir(): + pioenvs_dir = util.get_pioenvs_dir() + structhash_file = join(pioenvs_dir, "structure.hash") + proj_hash = calculate_project_hash() + + # if project's config is modified + if (isdir(pioenvs_dir) and + getmtime(join(util.get_project_dir(), "platformio.ini")) > + getmtime(pioenvs_dir)): + rmtree(pioenvs_dir) + + # check project structure + if isdir(pioenvs_dir) and isfile(structhash_file): + with open(structhash_file) as f: + if f.read() == proj_hash: + return + rmtree(pioenvs_dir) + + if not isdir(pioenvs_dir): + makedirs(pioenvs_dir) + + with open(structhash_file, "w") as f: + f.write(proj_hash) + + +def calculate_project_hash(): + structure = [] + for d in (util.get_projectsrc_dir(), util.get_projectlib_dir()): + if not isdir(d): + continue + for root, _, files in walk(d): + for f in files: + path = join(root, f) + if not any([s in path for s in (".git", ".svn")]): + structure.append(path) + return sha1(",".join(sorted(structure))).hexdigest() if structure else "" diff --git a/platformio/telemetry.py b/platformio/telemetry.py index 0dd676e1..6c666943 100644 --- a/platformio/telemetry.py +++ b/platformio/telemetry.py @@ -12,7 +12,7 @@ from time import time import click import requests -from platformio import __version__, app, util +from platformio import __version__, app, exception, util class TelemetryBase(object): @@ -219,9 +219,11 @@ def on_event(category, action, label=None, value=None, screen_name=None): def on_exception(e): + if isinstance(e, exception.AbortedByUser): + return mp = MeasurementProtocol() mp['exd'] = "%s: %s" % (type(e).__name__, e) - mp['exf'] = 1 + mp['exf'] = int(not isinstance(e, exception.PlatformioException)) mp.send("exception") diff --git a/platformio/util.py b/platformio/util.py index 4afa52cf..adc1e696 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -167,6 +167,10 @@ def get_projectsrc_dir(): ) +def get_projectlib_dir(): + return join(get_project_dir(), "lib") + + def get_pioenvs_dir(): return _get_projconf_option_dir( "envs_dir", @@ -263,9 +267,7 @@ def get_logicaldisks(): def get_request_defheaders(): return {"User-Agent": "PlatformIO/%s CI/%d %s" % ( - __version__, - 1 if is_ci() else 0, - requests.utils.default_user_agent() + __version__, int(is_ci()), requests.utils.default_user_agent() )} diff --git a/tests/test_examples.py b/tests/test_examples.py index ab02d640..2e98739d 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -38,6 +38,8 @@ def test_run(platformio_setup, pioproject_dir): # check .elf file pioenvs_dir = join(pioproject_dir, ".pioenvs") for item in listdir(pioenvs_dir): + if not isdir(item): + continue assert isfile(join(pioenvs_dir, item, "firmware.elf")) # check .hex or .bin files firmwares = []