diff --git a/HISTORY.rst b/HISTORY.rst index ce866c17..1e018976 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -4,6 +4,7 @@ Release History 0.9.0 (?) --------- +* Refactored *Package Manager* * Download Manager: fixed SHA1 verification within *Cygwin Environment* (`issue #26 `_) diff --git a/platformio/__init__.py b/platformio/__init__.py index d5216660..b778f896 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -16,4 +16,3 @@ __license__ = "MIT License" __copyright__ = "Copyright (C) 2014 Ivan Kravets" __apiurl__ = "http://api.platformio.ikravets.com" -__pkgmanifesturl__ = "http://dl.platformio.ikravets.com/packages/manifest.json" diff --git a/platformio/builder/main.py b/platformio/builder/main.py index 07fd7725..5fcfbed3 100644 --- a/platformio/builder/main.py +++ b/platformio/builder/main.py @@ -11,10 +11,10 @@ except ImportError: break from platformio.util import get_home_dir -from os.path import isdir, join +from os.path import join -from SCons.Script import (DefaultEnvironment, Exit, SConscript, - SConscriptChdir, Variables) +from SCons.Script import (DefaultEnvironment, SConscript, SConscriptChdir, + Variables) from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir, get_source_dir) @@ -24,8 +24,16 @@ from platformio.util import (get_lib_dir, get_pioenvs_dir, get_project_dir, # allow common variables from INI file commonvars = Variables(None) commonvars.AddVariables( + ("BUILD_SCRIPT",), ("PIOENV",), ("PLATFORM",), + + # package aliases + ("PIOPACKAGE_TOOLCHAIN",), + ("PIOPACKAGE_UPLOADER",), + ("PIOPACKAGE_FRAMEWORK",), + + # options ("FRAMEWORK",), ("BUILD_FLAGS",), ("SRCBUILD_FLAGS",), @@ -46,14 +54,13 @@ DefaultEnvironment( toolpath=[join("$PIOBUILDER_DIR", "tools")], variables=commonvars, - PIOBUILDER_DIR=join(get_source_dir(), "builder"), + PIOHOME_DIR=get_home_dir(), PROJECT_DIR=get_project_dir(), PIOENVS_DIR=get_pioenvs_dir(), - PLATFORMIOHOME_DIR=get_home_dir(), - PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "$PLATFORM"), - PLATFORMFW_DIR=join("$PLATFORM_DIR", "frameworks", "$FRAMEWORK"), - PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"), + PIOBUILDER_DIR=join(get_source_dir(), "builder"), + PIOPACKAGES_DIR=join("$PIOHOME_DIR", "packages"), + PLATFORMFW_DIR=join("$PIOPACKAGES_DIR", "$PIOPACKAGE_FRAMEWORK"), BUILD_DIR=join("$PIOENVS_DIR", "$PIOENV"), LIBSOURCE_DIRS=[ @@ -64,14 +71,10 @@ DefaultEnvironment( ) env = DefaultEnvironment() - -if not isdir(env['PLATFORMIOHOME_DIR']): - Exit("You haven't installed any platforms yet. Please use " - "`platformio install` command") -elif not isdir(env.subst("$PLATFORM_DIR")): - Exit("An '%s' platform hasn't been installed yet. Please use " - "`platformio install %s` command" % (env['PLATFORM'], - env['PLATFORM'])) +env.PrependENVPath( + "PATH", + env.subst(join("$PIOPACKAGES_DIR", "$PIOPACKAGE_TOOLCHAIN", "bin")) +) SConscriptChdir(0) -SConscript(env.subst(join("$PIOBUILDER_DIR", "scripts", "${PLATFORM}.py"))) +SConscript(env.subst("$BUILD_SCRIPT")) diff --git a/platformio/builder/scripts/atmelavr.py b/platformio/builder/scripts/atmelavr.py index e3806c23..cfdd2de9 100644 --- a/platformio/builder/scripts/atmelavr.py +++ b/platformio/builder/scripts/atmelavr.py @@ -53,13 +53,13 @@ env.Replace( "-mmcu=$BOARD_MCU" ], - UPLOADER=join("$PLATFORMTOOLS_DIR", "avrdude", "avrdude"), + UPLOADER=join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude"), UPLOADERFLAGS=[ "-V", # do not verify "-q", # suppress progress output "-D", # disable auto erase for flash memory "-p", "$BOARD_MCU", - "-C", join("$PLATFORMTOOLS_DIR", "avrdude", "avrdude.conf"), + "-C", join("$PIOPACKAGES_DIR", "tool-avrdude", "avrdude.conf"), "-c", "$UPLOAD_PROTOCOL", "-b", "$UPLOAD_SPEED", "-P", "$UPLOAD_PORT" diff --git a/platformio/builder/scripts/timsp430.py b/platformio/builder/scripts/timsp430.py index cd81bce7..98ac204f 100644 --- a/platformio/builder/scripts/timsp430.py +++ b/platformio/builder/scripts/timsp430.py @@ -51,7 +51,7 @@ env.Replace( "-Wl,-gc-sections,-u,main" ], - UPLOADER=join("$PLATFORMTOOLS_DIR", "mspdebug", "mspdebug"), + UPLOADER=join("$PIOPACKAGES_DIR", "tool-mspdebug", "mspdebug"), UPLOADERFLAGS=[ "$UPLOAD_PROTOCOL" if system() != "Windows" else "tilib", "--force-reset" diff --git a/platformio/builder/scripts/titiva.py b/platformio/builder/scripts/titiva.py index 8dacd75f..046d11b0 100644 --- a/platformio/builder/scripts/titiva.py +++ b/platformio/builder/scripts/titiva.py @@ -71,7 +71,7 @@ env.Replace( "-fsingle-precision-constant" ], - UPLOADER=join("$PLATFORMTOOLS_DIR", "lm4flash", "lm4flash"), + UPLOADER=join("$PIOPACKAGES_DIR", "tool-lm4flash", "lm4flash"), UPLOADCMD="$UPLOADER $SOURCES" ) diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py index 19302a1a..565603ae 100644 --- a/platformio/builder/tools/platformio.py +++ b/platformio/builder/tools/platformio.py @@ -14,11 +14,6 @@ def ProcessGeneral(env): if "BUILD_FLAGS" in env: env.MergeFlags(env['BUILD_FLAGS']) - env.PrependENVPath( - "PATH", - join(env.subst("$PLATFORMTOOLS_DIR"), "toolchain", "bin") - ) - if "FRAMEWORK" in env: if env['FRAMEWORK'] in ("arduino", "energia"): env.ConvertInotoCpp() diff --git a/platformio/commands/lib.py b/platformio/commands/lib.py index 0d6d4f1f..60402ca9 100644 --- a/platformio/commands/lib.py +++ b/platformio/commands/lib.py @@ -8,7 +8,6 @@ from platformio.exception import (LibAlreadyInstalledError, from platformio.libmanager import LibraryManager from platformio.util import get_api_result, get_lib_dir - LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} " "\"{authornames}\": {description}") diff --git a/platformio/commands/list.py b/platformio/commands/list.py index 990429bf..7650164f 100644 --- a/platformio/commands/list.py +++ b/platformio/commands/list.py @@ -3,14 +3,19 @@ from click import command, echo, style -from platformio.pkgmanager import PackageManager +from platformio.platforms.base import PlatformFactory @command("list", short_help="List installed platforms") def cli(): - for name, pkgs in PackageManager.get_installed().items(): + installed_platforms = PlatformFactory.get_platforms( + installed=True).keys() + sorted(installed_platforms) + + for platform in installed_platforms: + p = PlatformFactory().newPlatform(platform) echo("{name:<20} with packages: {pkgs}".format( - name=style(name, fg="cyan"), - pkgs=", ".join(pkgs.keys()) + name=style(p.get_name(), fg="cyan"), + pkgs=", ".join(p.get_installed_packages()) )) diff --git a/platformio/commands/search.py b/platformio/commands/search.py index 2457b05e..e798e587 100644 --- a/platformio/commands/search.py +++ b/platformio/commands/search.py @@ -4,19 +4,21 @@ from click import argument, command, echo, style from platformio.platforms.base import PlatformFactory -from platformio.util import get_platforms @command("search", short_help="Search for development platforms") @argument("query") def cli(query): - for platform in get_platforms(): + for platform in PlatformFactory.get_platforms().keys(): p = PlatformFactory().newPlatform(platform) name = p.get_name() shinfo = p.get_short_info() + if query == "all": + query = "" + search_data = "%s %s" % (name, shinfo) - if query != "all" and query.lower() not in search_data.lower(): + if query and query.lower() not in search_data.lower(): continue echo("{name:<20} - {info}".format(name=style(name, fg="cyan"), diff --git a/platformio/commands/show.py b/platformio/commands/show.py index 38cb4212..5d2a9d83 100644 --- a/platformio/commands/show.py +++ b/platformio/commands/show.py @@ -1,7 +1,7 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os.path import join +from datetime import datetime from click import argument, command, echo, style @@ -13,20 +13,25 @@ from platformio.platforms.base import PlatformFactory @command("show", short_help="Show details about installed platforms") @argument("platform") def cli(platform): - p = PlatformFactory().newPlatform(platform) - if platform not in PackageManager.get_installed(): + + installed_platforms = PlatformFactory.get_platforms( + installed=True).keys() + + if platform not in installed_platforms: raise PlatformNotInstalledYet(platform) - # print info about platform + p = PlatformFactory().newPlatform(platform) echo("{name:<20} - {info}".format(name=style(p.get_name(), fg="cyan"), info=p.get_short_info())) - pm = PackageManager(platform) - for name, data in pm.get_installed(platform).items(): + installed_packages = PackageManager.get_installed() + for name in p.get_installed_packages(): + data = installed_packages[name] pkgalias = p.get_pkg_alias(name) echo("----------") echo("Package: %s" % style(name, fg="yellow")) if pkgalias: echo("Alias: %s" % pkgalias) - echo("Location: %s" % join(pm.get_platform_dir(), data['path'])) echo("Version: %d" % int(data['version'])) + echo("Installed: %s" % datetime.fromtimestamp( + data['time']).strftime("%Y-%m-%d %H:%M:%S")) diff --git a/platformio/commands/uninstall.py b/platformio/commands/uninstall.py index 72765911..7d25eabb 100644 --- a/platformio/commands/uninstall.py +++ b/platformio/commands/uninstall.py @@ -3,8 +3,6 @@ from click import argument, command, secho -from platformio.exception import PlatformNotInstalledYet -from platformio.pkgmanager import PackageManager from platformio.platforms.base import PlatformFactory @@ -13,10 +11,6 @@ from platformio.platforms.base import PlatformFactory def cli(platforms): for platform in platforms: - - if platform not in PackageManager.get_installed(): - raise PlatformNotInstalledYet(platform) - p = PlatformFactory().newPlatform(platform) if p.uninstall(): secho("The platform '%s' has been successfully " diff --git a/platformio/commands/update.py b/platformio/commands/update.py index 8fad8523..8ccedb2f 100644 --- a/platformio/commands/update.py +++ b/platformio/commands/update.py @@ -3,14 +3,17 @@ from click import command, echo, style -from platformio.pkgmanager import PackageManager from platformio.platforms.base import PlatformFactory @command("update", short_help="Update installed platforms") def cli(): - for platform in PackageManager.get_installed().keys(): + installed_platforms = PlatformFactory.get_platforms( + installed=True).keys() + sorted(installed_platforms) + + for platform in installed_platforms: echo("\nPlatform %s" % style(platform, fg="cyan")) echo("--------") p = PlatformFactory().newPlatform(platform) diff --git a/platformio/exception.py b/platformio/exception.py index e0b508e5..48c12d94 100644 --- a/platformio/exception.py +++ b/platformio/exception.py @@ -124,3 +124,8 @@ class LibNotInstalledError(PlatformioException): class LibInstallDependencyError(PlatformioException): MESSAGE = "Error has been occurred for library dependency '%s'" + + +class BuildScriptNotFound(PlatformioException): + + MESSAGE = "Invalid path '%s' to build script" diff --git a/platformio/pkgmanager.py b/platformio/pkgmanager.py index 2bdffff0..4dedaed9 100644 --- a/platformio/pkgmanager.py +++ b/platformio/pkgmanager.py @@ -1,39 +1,36 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -import json from os import makedirs, remove -from os.path import isdir, isfile, join +from os.path import isdir, join from shutil import rmtree +from time import time from click import echo, secho, style -from requests import get -from requests.utils import default_user_agent -from platformio import __pkgmanifesturl__, __version__ from platformio.downloader import FileDownloader from platformio.exception import (InvalidPackageVersion, NonSystemPackage, UnknownPackage) from platformio.unpacker import FileUnpacker -from platformio.util import get_home_dir, get_systype +from platformio.util import AppState, get_api_result, get_home_dir, get_systype class PackageManager(object): DBFILE_PATH = join(get_home_dir(), "installed.json") - def __init__(self, platform_name): - self._platform_name = platform_name + def __init__(self): + self._package_dir = join(get_home_dir(), "packages") + if not isdir(self._package_dir): + makedirs(self._package_dir) + assert isdir(self._package_dir) @staticmethod def get_manifest(): try: return PackageManager._cached_manifest except AttributeError: - headers = {"User-Agent": "PlatformIO/%s %s" % ( - __version__, default_user_agent())} - PackageManager._cached_manifest = get(__pkgmanifesturl__, - headers=headers).json() + PackageManager._cached_manifest = get_api_result("/packages") return PackageManager._cached_manifest @staticmethod @@ -49,20 +46,19 @@ class PackageManager(object): return fu.start() @staticmethod - def get_installed(platform=None): - data = {} - if isfile(PackageManager.DBFILE_PATH): - with open(PackageManager.DBFILE_PATH) as fp: - data = json.load(fp) - return data.get(platform, None) if platform else data + def get_installed(): + pkgs = {} + with AppState() as state: + pkgs = state.get("installed_packages", {}) + return pkgs - def get_platform_dir(self): - return join(get_home_dir(), self._platform_name) + @staticmethod + def update_appstate_instpkgs(data): + with AppState() as state: + state['installed_packages'] = data def is_installed(self, name): - installed = self.get_installed() - return (self._platform_name in installed and name in - installed[self._platform_name]) + return name in self.get_installed() def get_info(self, name, version=None): manifest = self.get_manifest() @@ -84,35 +80,40 @@ class PackageManager(object): else: return sorted(builds, key=lambda s: s['version'])[-1] - def install(self, name, path): + def install(self, name): echo("Installing %s package:" % style(name, fg="cyan")) if self.is_installed(name): secho("Already installed", fg="yellow") - return + return False info = self.get_info(name) - pkg_dir = join(self.get_platform_dir(), path) + pkg_dir = join(self._package_dir, name) if not isdir(pkg_dir): makedirs(pkg_dir) dlpath = self.download(info['url'], pkg_dir, info['sha1']) if self.unpack(dlpath, pkg_dir): - self._register(name, info['version'], path) + self._register(name, info['version']) # remove archive remove(dlpath) - def uninstall(self, name, path): + def uninstall(self, name): echo("Uninstalling %s package: \t" % style(name, fg="cyan"), nl=False) - rmtree(join(self.get_platform_dir(), path)) + + if not self.is_installed(name): + secho("Not installed", fg="yellow") + return False + + rmtree(join(self._package_dir, name)) self._unregister(name) echo("[%s]" % style("OK", fg="green")) def update(self, name): echo("Updating %s package:" % style(name, fg="yellow")) - installed = self.get_installed(self._platform_name) + installed = self.get_installed() current_version = installed[name]['version'] latest_version = self.get_info(name)['version'] @@ -125,36 +126,18 @@ class PackageManager(object): else: echo("[%s]" % (style("Out-of-date", fg="red"))) - self.uninstall(name, installed[name]['path']) - self.install(name, installed[name]['path']) + self.uninstall(name) + self.install(name) - def register_platform(self, name): + def _register(self, name, version): data = self.get_installed() - if name not in data: - data[name] = {} - self._update_db(data) - return data - - def unregister_platform(self, name): - data = self.get_installed() - del data[name] - self._update_db(data) - - def _register(self, name, version, path): - data = self.get_installed() - if self._platform_name not in data: - data = self.register_platform(self._platform_name) - data[self._platform_name][name] = { + data[name] = { "version": version, - "path": path + "time": time() } - self._update_db(data) + self.update_appstate_instpkgs(data) def _unregister(self, name): data = self.get_installed() - del data[self._platform_name][name] - self._update_db(data) - - def _update_db(self, data): - with open(self.DBFILE_PATH, "w") as fp: - json.dump(data, fp) + del data[name] + self.update_appstate_instpkgs(data) diff --git a/platformio/platforms/atmelavr.py b/platformio/platforms/atmelavr.py index 4ba6e117..c0a9edc4 100644 --- a/platformio/platforms/atmelavr.py +++ b/platformio/platforms/atmelavr.py @@ -1,8 +1,6 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os.path import join - from platformio.platforms.base import BasePlatform @@ -15,19 +13,17 @@ class AtmelavrPlatform(BasePlatform): PACKAGES = { "toolchain-atmelavr": { - "path": join("tools", "toolchain"), "alias": "toolchain", "default": True }, "tool-avrdude": { - "path": join("tools", "avrdude"), "alias": "uploader", "default": True }, "framework-arduinoavr": { - "path": join("frameworks", "arduino"), + "alias": "framework", "default": True } } diff --git a/platformio/platforms/base.py b/platformio/platforms/base.py index cbca3fea..e95cc24d 100644 --- a/platformio/platforms/base.py +++ b/platformio/platforms/base.py @@ -1,23 +1,44 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os.path import join -from shutil import rmtree +from imp import load_source +from os import listdir +from os.path import isfile, join -from platformio.exception import UnknownPackage, UnknownPlatform +from platformio.exception import (BuildScriptNotFound, PlatformNotInstalledYet, + UnknownPackage, UnknownPlatform) from platformio.pkgmanager import PackageManager -from platformio.util import exec_command, get_platforms, get_source_dir +from platformio.util import AppState, exec_command, get_source_dir class PlatformFactory(object): + @staticmethod + def get_platforms(installed=False): + platforms = {} + for p in listdir(join(get_source_dir(), "platforms")): + if p in ("__init__.py", "base.py") or not p.endswith(".py"): + continue + platforms[p[:-3]] = join(get_source_dir(), "platforms", p) + + if not installed: + return platforms + + installed_platforms = {} + with AppState() as state: + for name in state.get("installed_platforms", []): + if name in platforms: + installed_platforms[name] = platforms[name] + return installed_platforms + @staticmethod def newPlatform(name): + platforms = PlatformFactory.get_platforms() clsname = "%sPlatform" % name.title() try: - assert name in get_platforms() - mod = __import__("platformio.platforms." + name.lower(), - None, None, [clsname]) + assert name in platforms + mod = load_source( + "platformio.platforms.%s" % name, platforms[name]) except (AssertionError, ImportError): raise UnknownPlatform(name) @@ -33,6 +54,13 @@ class BasePlatform(object): def get_name(self): raise NotImplementedError() + def get_build_script(self): + builtin = join(get_source_dir(), "builder", "scripts", "%s.py" % + self.get_name()) + if isfile(builtin): + return builtin + raise NotImplementedError() + def get_short_info(self): if self.__doc__: doclines = [l.strip() for l in self.__doc__.splitlines()] @@ -40,6 +68,9 @@ class BasePlatform(object): else: raise NotImplementedError() + def get_packages(self): + return self.PACKAGES + def get_pkg_alias(self, pkgname): return self.PACKAGES[pkgname].get("alias", None) @@ -47,62 +78,113 @@ class BasePlatform(object): names = [] for alias in aliases: name = alias - # lookup by packages alias - if name not in self.PACKAGES: - for _name, _opts in self.PACKAGES.items(): - if _opts.get("alias", None) == alias: - name = _name - break + # lookup by package aliases + for _name, _opts in self.get_packages().items(): + if _opts.get("alias", None) == alias: + name = _name + break names.append(name) return names + def get_installed_packages(self): + pm = PackageManager() + return [n for n in self.get_packages().keys() if pm.is_installed(n)] + def install(self, with_packages, without_packages, skip_default_packages): with_packages = set(self.pkg_aliases_to_names(with_packages)) without_packages = set(self.pkg_aliases_to_names(without_packages)) upkgs = with_packages | without_packages - ppkgs = set(self.PACKAGES.keys()) + ppkgs = set(self.get_packages().keys()) if not upkgs.issubset(ppkgs): raise UnknownPackage(", ".join(upkgs - ppkgs)) requirements = [] - for name, opts in self.PACKAGES.items(): + for name, opts in self.get_packages().items(): if name in without_packages: continue elif (name in with_packages or (not skip_default_packages and opts['default'])): - requirements.append((name, opts['path'])) + requirements.append(name) + + pm = PackageManager() + for name in requirements: + pm.install(name) + + # register installed platform + with AppState() as state: + data = state.get("installed_platforms", []) + if self.get_name() not in data: + data.append(self.get_name()) + state['installed_platforms'] = data - pm = PackageManager(self.get_name()) - for (package, path) in requirements: - pm.install(package, path) return len(requirements) def uninstall(self): platform = self.get_name() - pm = PackageManager(platform) + installed_platforms = PlatformFactory.get_platforms( + installed=True).keys() - for package, data in pm.get_installed(platform).items(): - pm.uninstall(package, data['path']) + if platform not in installed_platforms: + raise PlatformNotInstalledYet(platform) + + deppkgs = set() + for item in installed_platforms: + if item == platform: + continue + p = PlatformFactory().newPlatform(item) + deppkgs = deppkgs.union(set(p.get_packages().keys())) + + pm = PackageManager() + for name in self.get_packages().keys(): + if not pm.is_installed(name): + continue + pm.uninstall(name) + + # unregister installed platform + with AppState() as state: + installed_platforms.remove(platform) + state['installed_platforms'] = installed_platforms - pm.unregister_platform(platform) - rmtree(pm.get_platform_dir()) return True def update(self): - platform = self.get_name() - pm = PackageManager(platform) - for package in pm.get_installed(platform).keys(): - pm.update(package) + pm = PackageManager() + for name in self.get_installed_packages(): + pm.update(name) def run(self, variables, targets): assert isinstance(variables, list) assert isinstance(targets, list) + installed_platforms = PlatformFactory.get_platforms( + installed=True).keys() + installed_packages = PackageManager.get_installed() + + if self.get_name() not in installed_platforms: + raise PlatformNotInstalledYet(self.get_name()) + if "clean" in targets: targets.remove("clean") targets.append("-c") + if not any([v.startswith("BUILD_SCRIPT=") for v in variables]): + variables.append("BUILD_SCRIPT=%s" % self.get_build_script()) + + for v in variables: + if not v.startswith("BUILD_SCRIPT="): + continue + _, path = v.split("=", 2) + if not isfile(path): + raise BuildScriptNotFound(path) + + # append aliases of installed packages + for name, options in self.get_packages().items(): + if name not in installed_packages: + continue + variables.append( + "PIOPACKAGE_%s=%s" % (options['alias'].upper(), name)) + result = exec_command([ "scons", "-Q", diff --git a/platformio/platforms/timsp430.py b/platformio/platforms/timsp430.py index 7058af16..7cd799c3 100644 --- a/platformio/platforms/timsp430.py +++ b/platformio/platforms/timsp430.py @@ -1,8 +1,6 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os.path import join - from platformio.platforms.base import BasePlatform @@ -15,19 +13,17 @@ class Timsp430Platform(BasePlatform): PACKAGES = { "toolchain-timsp430": { - "path": join("tools", "toolchain"), "alias": "toolchain", "default": True }, "tool-mspdebug": { - "path": join("tools", "mspdebug"), "alias": "uploader", "default": True }, "framework-energiamsp430": { - "path": join("frameworks", "energia"), + "alias": "framework", "default": True } } diff --git a/platformio/platforms/titiva.py b/platformio/platforms/titiva.py index ed89cb44..d2253114 100644 --- a/platformio/platforms/titiva.py +++ b/platformio/platforms/titiva.py @@ -1,8 +1,6 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. -from os.path import join - from platformio.platforms.base import BasePlatform @@ -15,19 +13,17 @@ class TitivaPlatform(BasePlatform): PACKAGES = { "toolchain-gccarmnoneeabi": { - "path": join("tools", "toolchain"), "alias": "toolchain", "default": True }, "tool-lm4flash": { - "path": join("tools", "lm4flash"), "alias": "uploader", "default": True }, "framework-energiativa": { - "path": join("frameworks", "energia"), + "alias": "framework", "default": True } } diff --git a/platformio/util.py b/platformio/util.py index dfa314b7..aedb86d1 100644 --- a/platformio/util.py +++ b/platformio/util.py @@ -1,16 +1,15 @@ # Copyright (C) Ivan Kravets # See LICENSE for details. +import json from os import name as os_name -from os import getcwd, getenv, listdir, utime -from os.path import dirname, expanduser, isfile, join, realpath +from os import getcwd, getenv, makedirs, utime +from os.path import dirname, expanduser, isdir, isfile, join, realpath from platform import system, uname 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 +import requests from serial import Serial from platformio import __apiurl__, __version__ @@ -23,6 +22,28 @@ except ImportError: from ConfigParser import ConfigParser +class AppState(object): + + def __init__(self, path=None): + self.path = path + if not self.path: + self.path = join(get_home_dir(), "appstate.json") + self._state = {} + + def __enter__(self): + try: + if isfile(self.path): + with open(self.path, "r") as fp: + self._state = json.load(fp) + except ValueError: + self._state = {} + return self._state + + def __exit__(self, type_, value, traceback): + with open(self.path, "w") as fp: + json.dump(self._state, fp) + + def get_systype(): if system() == "Windows": return "windows" @@ -31,14 +52,24 @@ def get_systype(): def get_home_dir(): + home_dir = None + try: config = get_project_config() if (config.has_section("platformio") and config.has_option("platformio", "home_dir")): - return config.get("platformio", "home_dir") + home_dir = config.get("platformio", "home_dir") except NotPlatformProject: pass - return expanduser("~/.platformio") + + if not home_dir: + home_dir = expanduser("~/.platformio") + + if not isdir(home_dir): + makedirs(home_dir) + + assert isdir(home_dir) + return home_dir def get_lib_dir(): @@ -77,15 +108,6 @@ def get_project_config(): return cp -def get_platforms(): - platforms = [] - for p in listdir(join(get_source_dir(), "platforms")): - if p in ("__init__.py", "base.py") or not p.endswith(".py"): - continue - platforms.append(p[:-3]) - return platforms - - def change_filemtime(path, time): utime(path, (time, time)) @@ -123,20 +145,20 @@ def get_api_result(path, params=None, data=None): r = None try: headers = {"User-Agent": "PlatformIO/%s %s" % ( - __version__, default_user_agent())} + __version__, requests.utils.default_user_agent())} if data: - r = post(__apiurl__ + path, params=params, data=data, - headers=headers) + r = requests.post(__apiurl__ + path, params=params, data=data, + headers=headers) else: - r = get(__apiurl__ + path, params=params, headers=headers) + r = requests.get(__apiurl__ + path, params=params, headers=headers) result = r.json() r.raise_for_status() - except HTTPError as e: + except requests.exceptions.HTTPError as e: if result and "errors" in result: raise APIRequestError(result['errors'][0]['title']) else: raise APIRequestError(e) - except ConnectionError: + except requests.exceptions.ConnectionError: raise APIRequestError( "Could not connect to PlatformIO Registry Service") except ValueError: