def __init__(self, from_version, to_version): self.from_version = semantic_version.Version.coerce( util.pepver_to_semver(from_version)) self.to_version = semantic_version.Version.coerce( util.pepver_to_semver(to_version)) self._upgraders = [(semantic_version.Version("3.5.0-a.2"), self._update_dev_platforms)]
def __init__(self, from_version, to_version): self.from_version = semantic_version.Version.coerce( util.pepver_to_semver(from_version)) self.to_version = semantic_version.Version.coerce( util.pepver_to_semver(to_version)) self._upgraders = [ (semantic_version.Version("3.0.0-a.1"), self._upgrade_to_3_0_0), (semantic_version.Version("3.0.0-b.11"), self._upgrade_to_3_0_0b11) ]
def __init__(self, from_version, to_version): self.from_version = semantic_version.Version.coerce( util.pepver_to_semver(from_version)) self.to_version = semantic_version.Version.coerce( util.pepver_to_semver(to_version)) self._upgraders = [ (semantic_version.Version("3.0.0-a1"), self._upgrade_to_3_0_0), (semantic_version.Version("3.0.0-b11"), self._upgrade_to_3_0_0) ]
def __init__(self, from_version, to_version): self.from_version = semantic_version.Version.coerce( util.pepver_to_semver(from_version)) self.to_version = semantic_version.Version.coerce( util.pepver_to_semver(to_version)) self._upgraders = [(semantic_version.Version("3.0.0-a.1"), self._upgrade_to_3_0_0), (semantic_version.Version("3.0.0-b.11"), self._upgrade_to_3_0_0b11), (semantic_version.Version("3.5.0-a.2"), self._update_dev_platforms)]
def check_platformio_upgrade(): last_check = app.get_state_item("last_check", {}) interval = int(app.get_setting("check_platformio_interval")) * 3600 * 24 if (time() - interval) < last_check.get("platformio_upgrade", 0): return last_check["platformio_upgrade"] = int(time()) app.set_state_item("last_check", last_check) util.internet_on(raise_exception=True) # Update PlatformIO's Core packages update_core_packages(silent=True) latest_version = get_latest_version() if semantic_version.Version.coerce(util.pepver_to_semver( latest_version)) <= semantic_version.Version.coerce( util.pepver_to_semver(__version__)): return terminal_width, _ = click.get_terminal_size() click.echo("") click.echo("*" * terminal_width) click.secho( "There is a new version %s of PlatformIO available.\n" "Please upgrade it via `" % latest_version, fg="yellow", nl=False, ) if getenv("PLATFORMIO_IDE"): click.secho("PlatformIO IDE Menu: Upgrade PlatformIO", fg="cyan", nl=False) click.secho("`.", fg="yellow") elif join("Cellar", "platformio") in fs.get_source_dir(): click.secho("brew update && brew upgrade", fg="cyan", nl=False) click.secho("` command.", fg="yellow") else: click.secho("platformio upgrade", fg="cyan", nl=False) click.secho("` or `", fg="yellow", nl=False) click.secho("pip install -U platformio", fg="cyan", nl=False) click.secho("` command.", fg="yellow") click.secho("Changes: ", fg="yellow", nl=False) click.secho("https://docs.platformio.org/en/latest/history.html", fg="cyan") click.echo("*" * terminal_width) click.echo("")
def check_platformio_upgrade(): last_check = app.get_state_item("last_check", {}) interval = int(app.get_setting("check_platformio_interval")) * 3600 * 24 if (time() - interval) < last_check.get("platformio_upgrade", 0): return last_check['platformio_upgrade'] = int(time()) app.set_state_item("last_check", last_check) util.internet_on(raise_exception=True) # Update PlatformIO's Core packages update_core_packages(silent=True) latest_version = get_latest_version() if semantic_version.Version.coerce(util.pepver_to_semver( latest_version)) <= semantic_version.Version.coerce( util.pepver_to_semver(__version__)): return terminal_width, _ = click.get_terminal_size() click.echo("") click.echo("*" * terminal_width) click.secho( "There is a new version %s of PlatformIO available.\n" "Please upgrade it via `" % latest_version, fg="yellow", nl=False) if getenv("PLATFORMIO_IDE"): click.secho( "PlatformIO IDE Menu: Upgrade PlatformIO", fg="cyan", nl=False) click.secho("`.", fg="yellow") elif join("Cellar", "platformio") in util.get_source_dir(): click.secho("brew update && brew upgrade", fg="cyan", nl=False) click.secho("` command.", fg="yellow") else: click.secho("platformio upgrade", fg="cyan", nl=False) click.secho("` or `", fg="yellow", nl=False) click.secho("pip install -U platformio", fg="cyan", nl=False) click.secho("` command.", fg="yellow") click.secho("Changes: ", fg="yellow", nl=False) click.secho( "https://docs.platformio.org/en/latest/history.html", fg="cyan") click.echo("*" * terminal_width) click.echo("")
class PkgRepoMixin(object): PIO_VERSION = semantic_version.Version(util.pepver_to_semver(__version__)) @staticmethod def is_system_compatible(valid_systems): if valid_systems in (None, "all", "*"): return True if not isinstance(valid_systems, list): valid_systems = list([valid_systems]) return util.get_systype() in valid_systems def max_satisfying_repo_version(self, versions, requirements=None): item = None reqspec = None if requirements: try: reqspec = self.parse_semver_spec(requirements, raise_exception=True) except ValueError: pass for v in versions: if not self.is_system_compatible(v.get("system")): continue # if "platformio" in v.get("engines", {}): # if PkgRepoMixin.PIO_VERSION not in self.parse_semver_spec( # v['engines']['platformio'], raise_exception=True): # continue specver = semantic_version.Version(v['version']) if reqspec and specver not in reqspec: continue if not item or semantic_version.Version(item['version']) < specver: item = v return item def get_latest_repo_version( # pylint: disable=unused-argument self, name, requirements, silent=False): version = None for versions in PackageRepoIterator(name, self.repositories): pkgdata = self.max_satisfying_repo_version(versions, requirements) if not pkgdata: continue if not version or semantic_version.compare(pkgdata['version'], version) == 1: version = pkgdata['version'] return version def get_all_repo_versions(self, name): result = [] for versions in PackageRepoIterator(name, self.repositories): result.extend( [semantic_version.Version(v['version']) for v in versions]) return [str(v) for v in sorted(set(result))]
class PkgRepoMixin(object): PIO_VERSION = semantic_version.Version(util.pepver_to_semver(__version__)) @staticmethod def max_satisfying_repo_version(versions, requirements=None): item = None systype = util.get_systype() reqspec = None if requirements: try: reqspec = semantic_version.Spec(requirements) except ValueError: pass for v in versions: if "system" in v and v['system'] not in ("all", "*") and \ systype not in v['system']: continue if "platformio" in v.get("engines", {}): if PkgRepoMixin.PIO_VERSION not in semantic_version.Spec( v['engines']['platformio']): continue specver = semantic_version.Version(v['version']) if reqspec and specver not in reqspec: continue if not item or semantic_version.Version(item['version']) < specver: item = v return item def get_latest_repo_version( # pylint: disable=unused-argument self, name, requirements, silent=False): version = None for versions in PackageRepoIterator(name, self.repositories): pkgdata = self.max_satisfying_repo_version(versions, requirements) if not pkgdata: continue if not version or semantic_version.compare(pkgdata['version'], version) == 1: version = pkgdata['version'] return version def get_all_repo_versions(self, name): result = [] for versions in PackageRepoIterator(name, self.repositories): result.extend([v['version'] for v in versions]) return sorted(set(result))
def after_upgrade(ctx): terminal_width, _ = click.get_terminal_size() last_version = app.get_state_item("last_version", "0.0.0") if last_version == __version__: return if last_version == "0.0.0": app.set_state_item("last_version", __version__) elif semantic_version.Version.coerce(util.pepver_to_semver( last_version)) > semantic_version.Version.coerce( util.pepver_to_semver(__version__)): click.secho("*" * terminal_width, fg="yellow") click.secho( "Obsolete PIO Core v%s is used (previous was %s)" % (__version__, last_version), fg="yellow") click.secho( "Please remove multiple PIO Cores from a system:", fg="yellow") click.secho( "http://docs.platformio.org/page/faq.html" "#multiple-pio-cores-in-a-system", fg="cyan") click.secho("*" * terminal_width, fg="yellow") return else: click.secho("Please wait while upgrading PlatformIO...", fg="yellow") app.clean_cache() # Update PlatformIO's Core packages update_core_packages(silent=True) u = Upgrader(last_version, __version__) if u.run(ctx): app.set_state_item("last_version", __version__) click.secho( "PlatformIO has been successfully upgraded to %s!\n" % __version__, fg="green") telemetry.on_event( category="Auto", action="Upgrade", label="%s > %s" % (last_version, __version__)) else: raise exception.UpgradeError("Auto upgrading...") click.echo("") # PlatformIO banner click.echo("*" * terminal_width) click.echo("If you like %s, please:" % (click.style("PlatformIO", fg="cyan"))) click.echo("- %s us on Twitter to stay up-to-date " "on the latest project news > %s" % (click.style("follow", fg="cyan"), click.style("https://twitter.com/PlatformIO_Org", fg="cyan"))) click.echo( "- %s it on GitHub > %s" % (click.style("star", fg="cyan"), click.style("https://github.com/platformio/platformio", fg="cyan"))) if not getenv("PLATFORMIO_IDE"): click.echo( "- %s PlatformIO IDE for IoT development > %s" % (click.style("try", fg="cyan"), click.style("http://platformio.org/platformio-ide", fg="cyan"))) if not util.is_ci(): click.echo("- %s us with PlatformIO Plus > %s" % (click.style("support", fg="cyan"), click.style("https://pioplus.com", fg="cyan"))) click.echo("*" * terminal_width) click.echo("")
class PlatformBase(PlatformPackagesMixin, PlatformRunMixin): PIO_VERSION = semantic_version.Version(util.pepver_to_semver(__version__)) _BOARDS_CACHE = {} def __init__(self, manifest_path): self.manifest_path = manifest_path self.silent = False self.verbose = False self._BOARDS_CACHE = {} self._manifest = fs.load_json(manifest_path) self._custom_packages = None self.config = ProjectConfig.get_instance() self.pm = PackageManager(self.config.get_optional_dir("packages"), self.package_repositories) # if self.engines and "platformio" in self.engines: # if self.PIO_VERSION not in semantic_version.SimpleSpec( # self.engines['platformio']): # raise exception.IncompatiblePlatform(self.name, # str(self.PIO_VERSION)) @property def name(self): return self._manifest["name"] @property def title(self): return self._manifest["title"] @property def description(self): return self._manifest["description"] @property def version(self): return self._manifest["version"] @property def homepage(self): return self._manifest.get("homepage") @property def vendor_url(self): return self._manifest.get("url") @property def docs_url(self): return self._manifest.get("docs") @property def repository_url(self): return self._manifest.get("repository", {}).get("url") @property def license(self): return self._manifest.get("license") @property def frameworks(self): return self._manifest.get("frameworks") @property def engines(self): return self._manifest.get("engines") @property def package_repositories(self): return self._manifest.get("packageRepositories") @property def manifest(self): return self._manifest @property def packages(self): packages = self._manifest.get("packages", {}) for item in self._custom_packages or []: name = item version = "*" if "@" in item: name, version = item.split("@", 2) name = name.strip() if name not in packages: packages[name] = {} packages[name].update({ "version": version.strip(), "optional": False }) return packages @property def python_packages(self): return self._manifest.get("pythonPackages") def get_dir(self): return dirname(self.manifest_path) def get_build_script(self): main_script = join(self.get_dir(), "builder", "main.py") if isfile(main_script): return main_script raise NotImplementedError() def is_embedded(self): for opts in self.packages.values(): if opts.get("type") == "uploader": return True return False def get_boards(self, id_=None): def _append_board(board_id, manifest_path): config = PlatformBoardConfig(manifest_path) if "platform" in config and config.get("platform") != self.name: return if "platforms" in config and self.name not in config.get( "platforms"): return config.manifest["platform"] = self.name self._BOARDS_CACHE[board_id] = config bdirs = [ self.config.get_optional_dir("boards"), join(self.config.get_optional_dir("core"), "boards"), join(self.get_dir(), "boards"), ] if id_ is None: for boards_dir in bdirs: if not isdir(boards_dir): continue for item in sorted(os.listdir(boards_dir)): _id = item[:-5] if not item.endswith(".json") or _id in self._BOARDS_CACHE: continue _append_board(_id, join(boards_dir, item)) else: if id_ not in self._BOARDS_CACHE: for boards_dir in bdirs: if not isdir(boards_dir): continue manifest_path = join(boards_dir, "%s.json" % id_) if isfile(manifest_path): _append_board(id_, manifest_path) break if id_ not in self._BOARDS_CACHE: raise exception.UnknownBoard(id_) return self._BOARDS_CACHE[id_] if id_ else self._BOARDS_CACHE def board_config(self, id_): return self.get_boards(id_) def get_package_type(self, name): return self.packages[name].get("type") def configure_default_packages(self, options, targets): # override user custom packages self._custom_packages = options.get("platform_packages") # enable used frameworks for framework in options.get("framework", []): if not self.frameworks: continue framework = framework.lower().strip() if not framework or framework not in self.frameworks: continue _pkg_name = self.frameworks[framework].get("package") if _pkg_name: self.packages[_pkg_name]["optional"] = False # enable upload tools for upload targets if any(["upload" in t for t in targets] + ["program" in targets]): for name, opts in self.packages.items(): if opts.get("type") == "uploader": self.packages[name]["optional"] = False # skip all packages in "nobuild" mode # allow only upload tools and frameworks elif "nobuild" in targets and opts.get("type") != "framework": self.packages[name]["optional"] = True def get_lib_storages(self): storages = {} for opts in (self.frameworks or {}).values(): if "package" not in opts: continue pkg_dir = self.get_package_dir(opts["package"]) if not pkg_dir or not isdir(join(pkg_dir, "libraries")): continue libs_dir = join(pkg_dir, "libraries") storages[libs_dir] = opts["package"] libcores_dir = join(libs_dir, "__cores__") if not isdir(libcores_dir): continue for item in os.listdir(libcores_dir): libcore_dir = join(libcores_dir, item) if not isdir(libcore_dir): continue storages[libcore_dir] = "%s-core-%s" % (opts["package"], item) return [dict(name=name, path=path) for path, name in storages.items()] def on_installed(self): pass def on_uninstalled(self): pass def install_python_packages(self): if not self.python_packages: return None click.echo( "Installing Python packages: %s" % ", ".join(list(self.python_packages.keys())), ) args = [proc.get_pythonexe_path(), "-m", "pip", "install", "--upgrade"] for name, requirements in self.python_packages.items(): if any(c in requirements for c in ("<", ">", "=")): args.append("%s%s" % (name, requirements)) else: args.append("%s==%s" % (name, requirements)) try: return subprocess.call(args) == 0 except Exception as e: # pylint: disable=broad-except click.secho("Could not install Python packages -> %s" % e, fg="red", err=True) def uninstall_python_packages(self): if not self.python_packages: return click.echo("Uninstalling Python packages") args = [proc.get_pythonexe_path(), "-m", "pip", "uninstall", "--yes"] args.extend(list(self.python_packages.keys())) try: subprocess.call(args) == 0 except Exception as e: # pylint: disable=broad-except click.secho("Could not install Python packages -> %s" % e, fg="red", err=True)
def after_upgrade(ctx): terminal_width, _ = click.get_terminal_size() last_version = app.get_state_item("last_version", "0.0.0") if last_version == __version__: return if last_version == "0.0.0": app.set_state_item("last_version", __version__) elif semantic_version.Version.coerce(util.pepver_to_semver( last_version)) > semantic_version.Version.coerce( util.pepver_to_semver(__version__)): click.secho("*" * terminal_width, fg="yellow") click.secho( "Obsolete PIO Core v%s is used (previous was %s)" % (__version__, last_version), fg="yellow") click.secho( "Please remove multiple PIO Cores from a system:", fg="yellow") click.secho( "https://docs.platformio.org/page/faq.html" "#multiple-pio-cores-in-a-system", fg="cyan") click.secho("*" * terminal_width, fg="yellow") return else: click.secho("Please wait while upgrading PlatformIO...", fg="yellow") app.clean_cache() # Update PlatformIO's Core packages update_core_packages(silent=True) u = Upgrader(last_version, __version__) if u.run(ctx): app.set_state_item("last_version", __version__) click.secho( "PlatformIO has been successfully upgraded to %s!\n" % __version__, fg="green") telemetry.on_event( category="Auto", action="Upgrade", label="%s > %s" % (last_version, __version__)) else: raise exception.UpgradeError("Auto upgrading...") click.echo("") # PlatformIO banner click.echo("*" * terminal_width) click.echo( "If you like %s, please:" % (click.style("PlatformIO", fg="cyan"))) click.echo("- %s us on Twitter to stay up-to-date " "on the latest project news > %s" % (click.style("follow", fg="cyan"), click.style("https://twitter.com/PlatformIO_Org", fg="cyan"))) click.echo( "- %s it on GitHub > %s" % (click.style("star", fg="cyan"), click.style("https://github.com/platformio/platformio", fg="cyan"))) if not getenv("PLATFORMIO_IDE"): click.echo( "- %s PlatformIO IDE for IoT development > %s" % (click.style("try", fg="cyan"), click.style("https://platformio.org/platformio-ide", fg="cyan"))) if not util.is_ci(): click.echo("- %s us with PlatformIO Plus > %s" % (click.style( "support", fg="cyan"), click.style( "https://pioplus.com", fg="cyan"))) click.echo("*" * terminal_width) click.echo("")
class PlatformBase( # pylint: disable=too-many-public-methods PlatformPackagesMixin, PlatformRunMixin): PIO_VERSION = semantic_version.Version(util.pepver_to_semver(__version__)) _BOARDS_CACHE = {} def __init__(self, manifest_path): self._BOARDS_CACHE = {} self.manifest_path = manifest_path self._manifest = util.load_json(manifest_path) self.pm = PackageManager( join(util.get_home_dir(), "packages"), self._manifest.get("packageRepositories")) self.silent = False self.verbose = False if self.engines and "platformio" in self.engines: if self.PIO_VERSION not in semantic_version.Spec( self.engines['platformio']): raise exception.IncompatiblePlatform(self.name, str(self.PIO_VERSION)) @property def name(self): return self._manifest['name'] @property def title(self): return self._manifest['title'] @property def description(self): return self._manifest['description'] @property def version(self): return self._manifest['version'] @property def homepage(self): return self._manifest.get("homepage") @property def vendor_url(self): return self._manifest.get("url") @property def repository_url(self): return self._manifest.get("repository", {}).get("url") @property def license(self): return self._manifest.get("license") @property def frameworks(self): return self._manifest.get("frameworks") @property def engines(self): return self._manifest.get("engines") @property def manifest(self): return self._manifest @property def packages(self): if "packages" not in self._manifest: self._manifest['packages'] = {} return self._manifest['packages'] def get_dir(self): return dirname(self.manifest_path) def get_build_script(self): main_script = join(self.get_dir(), "builder", "main.py") if isfile(main_script): return main_script raise NotImplementedError() def is_embedded(self): for opts in self.packages.values(): if opts.get("type") == "uploader": return True return False def get_boards(self, id_=None): def _append_board(board_id, manifest_path): config = PlatformBoardConfig(manifest_path) if "platform" in config and config.get("platform") != self.name: return elif "platforms" in config \ and self.name not in config.get("platforms"): return config.manifest['platform'] = self.name self._BOARDS_CACHE[board_id] = config bdirs = [ util.get_projectboards_dir(), join(util.get_home_dir(), "boards"), join(self.get_dir(), "boards"), ] if id_ is None: for boards_dir in bdirs: if not isdir(boards_dir): continue for item in sorted(os.listdir(boards_dir)): _id = item[:-5] if not item.endswith(".json") or _id in self._BOARDS_CACHE: continue _append_board(_id, join(boards_dir, item)) else: if id_ not in self._BOARDS_CACHE: for boards_dir in bdirs: if not isdir(boards_dir): continue manifest_path = join(boards_dir, "%s.json" % id_) if not isfile(manifest_path): continue _append_board(id_, manifest_path) if id_ not in self._BOARDS_CACHE: raise exception.UnknownBoard(id_) return self._BOARDS_CACHE[id_] if id_ else self._BOARDS_CACHE def board_config(self, id_): return self.get_boards(id_) def get_package_type(self, name): return self.packages[name].get("type") def configure_default_packages(self, variables, targets): # enable used frameworks frameworks = variables.get("pioframework", []) if not isinstance(frameworks, list): frameworks = frameworks.split(", ") for framework in frameworks: if not self.frameworks: continue framework = framework.lower().strip() if not framework or framework not in self.frameworks: continue _pkg_name = self.frameworks[framework].get("package") if _pkg_name: self.packages[_pkg_name]['optional'] = False # enable upload tools for upload targets if any(["upload" in t for t in targets] + ["program" in targets]): for _name, _opts in self.packages.iteritems(): if _opts.get("type") == "uploader": self.packages[_name]['optional'] = False elif "nobuild" in targets: # skip all packages, allow only upload tools self.packages[_name]['optional'] = True def get_lib_storages(self): storages = [] for opts in (self.frameworks or {}).values(): if "package" not in opts: continue pkg_dir = self.get_package_dir(opts['package']) if not pkg_dir or not isdir(join(pkg_dir, "libraries")): continue libs_dir = join(pkg_dir, "libraries") storages.append({"name": opts['package'], "path": libs_dir}) libcores_dir = join(libs_dir, "__cores__") if not isdir(libcores_dir): continue for item in os.listdir(libcores_dir): libcore_dir = join(libcores_dir, item) if not isdir(libcore_dir): continue storages.append({ "name": "%s-core-%s" % (opts['package'], item), "path": libcore_dir }) return storages