def __init__(self, from_version, to_version): self.from_version = pepver_to_semver(from_version) self.to_version = pepver_to_semver(to_version) self._upgraders = [ (semantic_version.Version("3.5.0-a.2"), self._update_dev_platforms), (semantic_version.Version("4.4.0-a.8"), self._update_pkg_metadata), ]
def _append_pio_macros(): core_version = pepver_to_semver(__version__) env.AppendUnique(CPPDEFINES=[( "PLATFORMIO", int("{0:02d}{1:02d}{2:02d}".format( core_version.major, core_version.minor, core_version.patch)), )])
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) http.ensure_internet_on(raise_exception=True) # Update PlatformIO's Core packages update_core_packages(silent=True) latest_version = get_latest_version() if pepver_to_semver(latest_version) <= 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 _get_installed_pip_packages(): result = {} packages = {} pip_output = subprocess.check_output( [env.subst("$PYTHONEXE"), "-m", "pip", "list", "--format=json"]) try: packages = json.loads(pip_output) except: print( "Warning! Couldn't extract the list of installed Python packages." ) return {} for p in packages: result[p["name"]] = pepver_to_semver(p["version"]) return result
class PlatformBase( # pylint: disable=too-many-instance-attributes,too-many-public-methods PlatformPackagesMixin, PlatformRunMixin): CORE_SEMVER = pepver_to_semver(__version__) _BOARDS_CACHE = {} def __init__(self, manifest_path): self.manifest_path = manifest_path self.silent = False self.verbose = False self._manifest = fs.load_json(manifest_path) self._BOARDS_CACHE = {} self._custom_packages = None self.config = ProjectConfig.get_instance() self.pm = ToolPackageManager(self.config.get_optional_dir("packages")) @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 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): packages = self._manifest.get("packages", {}) for item in self._custom_packages or []: name = item version = "*" if "@" in item: name, version = item.split("@", 1) spec = self.pm.ensure_spec(name) options = {"version": version.strip(), "optional": False} if spec.owner: options["owner"] = spec.owner if spec.name not in packages: packages[spec.name] = {} packages[spec.name].update(**options) return packages @property def python_packages(self): return self._manifest.get("pythonPackages") def ensure_engine_compatible(self): if not self.engines or "platformio" not in self.engines: return True core_spec = semantic_version.SimpleSpec(self.engines["platformio"]) if self.CORE_SEMVER in core_spec: return True # PIO Core 5 is compatible with dev-platforms for PIO Core 2.0, 3.0, 4.0 if any( semantic_version.Version.coerce(str(v)) in core_spec for v in (2, 3, 4)): return True raise IncompatiblePlatform(self.name, str(self.CORE_SEMVER), str(core_spec)) def get_dir(self): return os.path.dirname(self.manifest_path) def get_build_script(self): main_script = os.path.join(self.get_dir(), "builder", "main.py") if os.path.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"), os.path.join(self.config.get_optional_dir("core"), "boards"), os.path.join(self.get_dir(), "boards"), ] if id_ is None: for boards_dir in bdirs: if not os.path.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, os.path.join(boards_dir, item)) else: if id_ not in self._BOARDS_CACHE: for boards_dir in bdirs: if not os.path.isdir(boards_dir): continue manifest_path = os.path.join(boards_dir, "%s.json" % id_) if os.path.isfile(manifest_path): _append_board(id_, manifest_path) break if id_ not in self._BOARDS_CACHE: raise 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 configure_debug_options(self, initial_debug_options, ide_data): raise NotImplementedError def get_lib_storages(self): storages = {} for opts in (self.frameworks or {}).values(): if "package" not in opts: continue pkg = self.get_package(opts["package"]) if not pkg or not os.path.isdir(os.path.join( pkg.path, "libraries")): continue libs_dir = os.path.join(pkg.path, "libraries") storages[libs_dir] = opts["package"] libcores_dir = os.path.join(libs_dir, "__cores__") if not os.path.isdir(libcores_dir): continue for item in os.listdir(libcores_dir): libcore_dir = os.path.join(libcores_dir, item) if not os.path.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) return None 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 pepver_to_semver(last_version) > 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-platformio-cores-in-a-system", fg="cyan", ) click.secho("*" * terminal_width, fg="yellow") return else: click.secho("Please wait while upgrading PlatformIO...", fg="yellow") try: cleanup_content_cache("http") except: # pylint: disable=bare-except pass # 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.send_event( category="Auto", action="Upgrade", label="%s > %s" % (last_version, __version__), ) else: raise exception.UpgradeError("Auto upgrading...") # 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 embedded development > %s" % ( click.style("try", fg="cyan"), click.style("https://platformio.org/platformio-ide", fg="cyan"), ) ) click.echo("*" * terminal_width) click.echo("")