diff --git a/HISTORY.rst b/HISTORY.rst index 997e6059..49771c84 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -13,9 +13,11 @@ PlatformIO 2.0 * PlatformIO `command completion in Terminal `_ for ``bash`` and ``zsh`` * Added support for ubIQio Ardhat board (`pull #302 `_) +* Install SCons automatically and avoid ``error: option --single-version-externally-managed not recognized`` + (`issue #279 `_) * Use Teensy CLI Loader for upload of .hex files on Mac OS X (`issue #306 `_) -* Fixed missing of `framework-mbed `_ +* Fixed missing `framework-mbed `_ package for `teensy `_ platform (`issue #305 `_) diff --git a/platformio/__init__.py b/platformio/__init__.py index 33ac68f2..fffd186e 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -VERSION = (2, 3, "4.dev2") +VERSION = (2, 3, "4.dev3") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/platforms/base.py b/platformio/platforms/base.py index ddc21a5b..21866942 100644 --- a/platformio/platforms/base.py +++ b/platformio/platforms/base.py @@ -3,8 +3,6 @@ import os import re -import sys -from glob import glob from imp import load_source from os.path import isdir, isfile, join @@ -374,7 +372,7 @@ class BasePlatform(object): self._found_error = False try: # test that SCons is installed correctly - assert self.test_scons() + assert util.test_scons() result = util.exec_command( [ @@ -397,39 +395,6 @@ class BasePlatform(object): return result - @staticmethod - def test_scons(): - try: - r = util.exec_command(["scons", "--version"]) - if "ImportError: No module named SCons.Script" in r['err']: - _PYTHONPATH = [] - for p in sys.path: - if not p.endswith("-packages"): - continue - for item in glob(join(p, "scons*")): - if isdir(join(item, "SCons")) and item not in sys.path: - _PYTHONPATH.append(item) - sys.path.insert(0, item) - if _PYTHONPATH: - _PYTHONPATH = str(os.pathsep).join(_PYTHONPATH) - if os.getenv("PYTHONPATH"): - os.environ['PYTHONPATH'] += os.pathsep + _PYTHONPATH - else: - os.environ['PYTHONPATH'] = _PYTHONPATH - r = util.exec_command(["scons", "--version"]) - assert r['returncode'] == 0 - return True - except (OSError, AssertionError): - for p in sys.path: - try: - r = util.exec_command([join(p, "scons"), "--version"]) - assert r['returncode'] == 0 - os.environ['PATH'] += os.pathsep + p - return True - except (OSError, AssertionError): - pass - return False - def on_run_out(self, line): self._echo_line(line, level=3) diff --git a/platformio/util.py b/platformio/util.py index fa71848b..e9f5efe6 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -7,13 +7,13 @@ import json import os import re import subprocess +import sys +from glob import glob from os.path import (abspath, basename, dirname, expanduser, isdir, isfile, join, realpath) from platform import system, uname from threading import Thread -import requests - from platformio import __apiurl__, __version__, exception try: @@ -277,12 +277,14 @@ def get_logicaldisks(): def get_request_defheaders(): + import requests return {"User-Agent": "PlatformIO/%s CI/%d %s" % ( __version__, int(is_ci()), requests.utils.default_user_agent() )} def get_api_result(path, params=None, data=None): + import requests result = None r = None @@ -312,6 +314,53 @@ def get_api_result(path, params=None, data=None): return result +def test_scons(): + try: + r = exec_command(["scons", "--version"]) + if "ImportError: No module named SCons.Script" in r['err']: + _PYTHONPATH = [] + for p in sys.path: + if not p.endswith("-packages"): + continue + for item in glob(join(p, "scons*")): + if isdir(join(item, "SCons")) and item not in sys.path: + _PYTHONPATH.append(item) + sys.path.insert(0, item) + if _PYTHONPATH: + _PYTHONPATH = str(os.pathsep).join(_PYTHONPATH) + if os.getenv("PYTHONPATH"): + os.environ['PYTHONPATH'] += os.pathsep + _PYTHONPATH + else: + os.environ['PYTHONPATH'] = _PYTHONPATH + r = exec_command(["scons", "--version"]) + assert r['returncode'] == 0 + return True + except (OSError, AssertionError): + for p in sys.path: + try: + r = exec_command([join(p, "scons"), "--version"]) + assert r['returncode'] == 0 + os.environ['PATH'] += os.pathsep + p + return True + except (OSError, AssertionError): + pass + return False + + +def install_scons(): + r = exec_command(["pip", "install", "-U", "scons"]) + if r['returncode'] != 0: + r = exec_command(["pip", "install", "--egg", "scons"]) + return r['returncode'] == 0 + + +def scons_in_pip(): + r = exec_command(["pip", "list"]) + if r['returncode'] != 0: + return False + return "scons (" in r['out'].lower() + + @memoized def _lookup_boards(): boards = {} diff --git a/setup.py b/setup.py index 668ada4a..35d674df 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,21 @@ from platform import system from setuptools import find_packages, setup from platformio import (__author__, __description__, __email__, __license__, - __title__, __url__, __version__) + __title__, __url__, __version__, util) + +install_requires = [ + "bottle", + "click>=3.2", + "lockfile>=0.9.1", + "pyserial<3", + "requests>=2.4.0" +] + +if system() == "Windows": + install_requires.append("colorama") + +if (not util.test_scons() and not util.install_scons()) or util.scons_in_pip(): + install_requires.append("scons") setup( name=__title__, @@ -17,14 +31,7 @@ setup( author_email=__email__, url=__url__, license=__license__, - install_requires=[ - "bottle", - "click>=3.2", - "lockfile>=0.9.1", - "pyserial", - "requests>=2.4.0", - "SCons" - ] + (["colorama"] if system() == "Windows" else []), + install_requires=install_requires, packages=find_packages(), package_data={ "platformio": [