def get_installed(self): cache_key = "get_installed" if self.memcache_get(cache_key): return self.memcache_get(cache_key) result = [] for name in sorted(os.listdir(self.package_dir)): if name.startswith("_tmp_installing"): # legacy tmp folder continue pkg_dir = os.path.join(self.package_dir, name) if not os.path.isdir(pkg_dir): continue pkg = PackageItem(pkg_dir) if not pkg.metadata: try: spec = self.build_legacy_spec(pkg_dir) pkg.metadata = self.build_metadata(pkg_dir, spec) except MissingPackageManifestError: pass if not pkg.metadata: continue if self.pkg_type == PackageType.TOOL: try: if not self.is_system_compatible( self.load_manifest(pkg).get("system") ): continue except MissingPackageManifestError: pass result.append(pkg) self.memcache_set(cache_key, result) return result
def install_from_url(self, url, spec, checksum=None, silent=False): spec = self.ensure_spec(spec) tmp_dir = tempfile.mkdtemp(prefix="pkg-installing-", dir=self.get_tmp_dir()) vcs = None try: if url.startswith("file://"): _url = url[7:] if os.path.isfile(_url): self.unpack(_url, tmp_dir) else: fs.rmtree(tmp_dir) shutil.copytree(_url, tmp_dir, symlinks=True) elif url.startswith(("http://", "https://")): dl_path = self.download(url, checksum, silent=silent) assert os.path.isfile(dl_path) self.unpack(dl_path, tmp_dir) else: vcs = VCSClientFactory.new(tmp_dir, url) assert vcs.export() root_dir = self.find_pkg_root(tmp_dir, spec) pkg_item = PackageItem( root_dir, self.build_metadata( root_dir, spec, vcs.get_current_revision() if vcs else None), ) pkg_item.dump_meta() return self._install_tmp_pkg(pkg_item) finally: if os.path.isdir(tmp_dir): fs.rmtree(tmp_dir)
def build_contrib_pysite_deps(target_dir): if os.path.isdir(target_dir): fs.rmtree(target_dir) os.makedirs(target_dir) # build dependencies pythonexe = get_pythonexe_path() for dep in get_contrib_pysite_deps(): subprocess.check_call([ pythonexe, "-m", "pip", "install", # "--no-cache-dir", "--no-compile", "--no-binary", ":all:", "-t", target_dir, dep, ]) # build manifests with open(os.path.join(target_dir, "package.json"), "w") as fp: json.dump( dict( name="contrib-pysite", version="2.%d%d.%s" % ( sys.version_info.major, sys.version_info.minor, date.today().strftime("%y%m%d"), ), system=util.get_systype(), ), fp, ) pm = ToolPackageManager() pkg = PackageItem(target_dir) pkg.metadata = pm.build_metadata( target_dir, PackageSpec(owner="platformio", name="contrib-pysite")) pkg.dump_meta() return True
def legacy_load_manifest(self, pkg): if not isinstance(pkg, PackageItem): assert os.path.isdir(pkg) pkg = PackageItem(pkg) manifest = self.load_manifest(pkg) manifest["__pkg_dir"] = pkg.path for key in ("name", "version"): if not manifest.get(key): manifest[key] = str(getattr(pkg.metadata, key)) if pkg.metadata and pkg.metadata.spec and pkg.metadata.spec.external: manifest["__src_url"] = pkg.metadata.spec.url manifest["version"] = str(pkg.metadata.version) if pkg.metadata and pkg.metadata.spec.owner: manifest["ownername"] = pkg.metadata.spec.owner return manifest
def _print_deps_tree(root, level=0): margin = "| " * (level) for lb in root.depbuilders: title = "<%s>" % lb.name pkg = PackageItem(lb.path) if pkg.metadata: title += " %s" % pkg.metadata.version elif lb.version: title += " %s" % lb.version click.echo("%s|-- %s" % (margin, title), nl=False) if int(ARGUMENTS.get("PIOVERBOSE", 0)): if pkg.metadata and pkg.metadata.spec.external: click.echo(" [%s]" % pkg.metadata.spec.url, nl=False) click.echo(" (", nl=False) click.echo(lb.path, nl=False) click.echo(")", nl=False) click.echo("") if lb.depbuilders: _print_deps_tree(lb, level + 1)
def _install_tmp_pkg(self, tmp_pkg): assert isinstance(tmp_pkg, PackageItem) # validate package version and declared requirements if (tmp_pkg.metadata.spec.requirements and tmp_pkg.metadata.version not in tmp_pkg.metadata.spec.requirements): raise PackageException( "Package version %s doesn't satisfy requirements %s based on %s" % ( tmp_pkg.metadata.version, tmp_pkg.metadata.spec.requirements, tmp_pkg.metadata, )) dst_pkg = PackageItem( os.path.join(self.package_dir, tmp_pkg.get_safe_dirname())) # what to do with existing package? action = "overwrite" if tmp_pkg.metadata.spec.has_custom_name(): action = "overwrite" dst_pkg = PackageItem( os.path.join(self.package_dir, tmp_pkg.metadata.spec.name)) elif dst_pkg.metadata: if dst_pkg.metadata.spec.external: if dst_pkg.metadata.spec.url != tmp_pkg.metadata.spec.url: action = "detach-existing" elif (dst_pkg.metadata.version != tmp_pkg.metadata.version or dst_pkg.metadata.spec.owner != tmp_pkg.metadata.spec.owner): action = ("detach-existing" if tmp_pkg.metadata.version > dst_pkg.metadata.version else "detach-new") def _cleanup_dir(path): if os.path.isdir(path): fs.rmtree(path) if action == "detach-existing": target_dirname = "%s@%s" % ( tmp_pkg.get_safe_dirname(), dst_pkg.metadata.version, ) if dst_pkg.metadata.spec.url: target_dirname = "%s@src-%s" % ( tmp_pkg.get_safe_dirname(), hashlib.md5( compat.hashlib_encode_data( dst_pkg.metadata.spec.url)).hexdigest(), ) # move existing into the new place pkg_dir = os.path.join(self.package_dir, target_dirname) _cleanup_dir(pkg_dir) shutil.move(dst_pkg.path, pkg_dir) # move new source to the destination location _cleanup_dir(dst_pkg.path) shutil.move(tmp_pkg.path, dst_pkg.path) return PackageItem(dst_pkg.path) if action == "detach-new": target_dirname = "%s@%s" % ( tmp_pkg.get_safe_dirname(), tmp_pkg.metadata.version, ) if tmp_pkg.metadata.spec.external: target_dirname = "%s@src-%s" % ( tmp_pkg.get_safe_dirname(), hashlib.md5( compat.hashlib_encode_data( tmp_pkg.metadata.spec.url)).hexdigest(), ) pkg_dir = os.path.join(self.package_dir, target_dirname) _cleanup_dir(pkg_dir) shutil.move(tmp_pkg.path, pkg_dir) return PackageItem(pkg_dir) # otherwise, overwrite existing _cleanup_dir(dst_pkg.path) shutil.move(tmp_pkg.path, dst_pkg.path) return PackageItem(dst_pkg.path)
def PrintConfiguration(env): # pylint: disable=too-many-statements platform = env.PioPlatform() pkg_metadata = PackageItem(platform.get_dir()).metadata board_config = env.BoardConfig() if "BOARD" in env else None def _get_configuration_data(): return (None if not board_config else [ "CONFIGURATION:", "https://docs.platformio.org/page/boards/%s/%s.html" % (platform.name, board_config.id), ]) def _get_plaform_data(): data = [ "PLATFORM: %s (%s)" % ( platform.title, pkg_metadata.version if pkg_metadata else platform.version, ) ] if (int(ARGUMENTS.get("PIOVERBOSE", 0)) and pkg_metadata and pkg_metadata.spec.external): data.append("(%s)" % pkg_metadata.spec.url) if board_config: data.extend([">", board_config.get("name")]) return data def _get_hardware_data(): data = ["HARDWARE:"] mcu = env.subst("$BOARD_MCU") f_cpu = env.subst("$BOARD_F_CPU") if mcu: data.append(mcu.upper()) if f_cpu: f_cpu = int("".join([c for c in str(f_cpu) if c.isdigit()])) data.append("%dMHz," % (f_cpu / 1000000)) if not board_config: return data ram = board_config.get("upload", {}).get("maximum_ram_size") flash = board_config.get("upload", {}).get("maximum_size") data.append("%s RAM, %s Flash" % (fs.humanize_file_size(ram), fs.humanize_file_size(flash))) return data def _get_debug_data(): debug_tools = (board_config.get("debug", {}).get("tools") if board_config else None) if not debug_tools: return None data = [ "DEBUG:", "Current", "(%s)" % board_config.get_debug_tool_name( env.GetProjectOption("debug_tool")), ] onboard = [] external = [] for key, value in debug_tools.items(): if value.get("onboard"): onboard.append(key) else: external.append(key) if onboard: data.extend(["On-board", "(%s)" % ", ".join(sorted(onboard))]) if external: data.extend(["External", "(%s)" % ", ".join(sorted(external))]) return data def _get_packages_data(): data = [] for item in platform.dump_used_packages(): original_version = get_original_version(item["version"]) info = "%s %s" % (item["name"], item["version"]) extra = [] if original_version: extra.append(original_version) if "src_url" in item and int(ARGUMENTS.get("PIOVERBOSE", 0)): extra.append(item["src_url"]) if extra: info += " (%s)" % ", ".join(extra) data.append(info) if not data: return None return ["PACKAGES:"] + ["\n - %s" % d for d in sorted(data)] for data in ( _get_configuration_data(), _get_plaform_data(), _get_hardware_data(), _get_debug_data(), _get_packages_data(), ): if data and len(data) > 1: print(" ".join(data))
def build_contrib_pysite_package(target_dir, with_metadata=True): systype = util.get_systype() if os.path.isdir(target_dir): fs.rmtree(target_dir) os.makedirs(target_dir) # build dependencies args = [ get_pythonexe_path(), "-m", "pip", "install", "--no-compile", "-t", target_dir, ] if "linux" in systype: args.extend(["--no-binary", ":all:"]) for dep in get_contrib_pysite_deps(): subprocess.check_call(args + [dep]) # build manifests with open(os.path.join(target_dir, "package.json"), "w") as fp: json.dump( dict( name="contrib-pysite", version="2.%d%d.%s" % ( sys.version_info.major, sys.version_info.minor, date.today().strftime("%y%m%d"), ), system=list( set([systype, "linux_armv6l", "linux_armv7l", "linux_armv8l"]) ) if systype.startswith("linux_arm") else systype, description="Extra Python package for PlatformIO Core", keywords=["platformio", "platformio-core"], homepage="https://docs.platformio.org/page/core/index.html", repository={ "type": "git", "url": "https://github.com/platformio/platformio-core", }, ), fp, ) # generate package metadata if with_metadata: pm = ToolPackageManager() pkg = PackageItem(target_dir) pkg.metadata = pm.build_metadata( target_dir, PackageSpec(owner="platformio", name="contrib-pysite") ) pkg.dump_meta() # remove unused files for root, dirs, files in os.walk(target_dir): for t in ("_test", "test", "tests"): if t in dirs: shutil.rmtree(os.path.join(root, t)) for name in files: if name.endswith((".chm", ".pyc")): os.remove(os.path.join(root, name)) return target_dir