Switch legacy platform manager to the new

This commit is contained in:
Ivan Kravets committed 2020-08-15 23:11:01 +03:00
1 parent bb6fb3fdf8
commit 04694b4126
25 files changed
+470 -1271

No files matched your search

+15 -5
View File
@@ -42,17 +42,26 @@ class PackageManagerInstallMixin(object):
with FileUnpacker(src) as fu:
return fu.unpack(dst, with_progress=False)
def install(self, spec, silent=False, force=False):
def install(self, spec, silent=False, skip_dependencies=False, force=False):
try:
self.lock()
pkg = self._install(spec, silent=silent, force=force)
pkg = self._install(
spec, silent=silent, skip_dependencies=skip_dependencies, force=force
)
self.memcache_reset()
self.cleanup_expired_downloads()
return pkg
finally:
self.unlock()
def _install(self, spec, search_filters=None, silent=False, force=False):
def _install( # pylint: disable=too-many-arguments
self,
spec,
search_filters=None,
silent=False,
skip_dependencies=False,
force=False,
):
spec = self.ensure_spec(spec)
# avoid circle dependencies
@@ -104,11 +113,12 @@ class PackageManagerInstallMixin(object):
)
self.memcache_reset()
self._install_dependencies(pkg, silent)
if not skip_dependencies:
self.install_dependencies(pkg, silent)
self._INSTALL_HISTORY[spec] = pkg
return pkg
def _install_dependencies(self, pkg, silent=False):
def install_dependencies(self, pkg, silent=False):
assert isinstance(pkg, PackageItem)
manifest = self.load_manifest(pkg)
if not manifest.get("dependencies"):
+5 -2
View File
@@ -91,6 +91,9 @@ class PackageManageRegistryMixin(object):
self.print_multi_package_issue(packages, spec)
package, version = self.find_best_registry_version(packages, spec)
if not package or not version:
raise UnknownPackageError(spec.humanize())
pkgfile = self._pick_compatible_pkg_file(version["files"]) if version else None
if not pkgfile:
raise UnknownPackageError(spec.humanize())
@@ -189,7 +192,7 @@ class PackageManageRegistryMixin(object):
return (package, version)
if not spec.requirements:
return None
return (None, None)
# if the custom version requirements, check ALL package versions
for package in packages:
@@ -206,7 +209,7 @@ class PackageManageRegistryMixin(object):
if version:
return (package, version)
time.sleep(1)
return None
return (None, None)
def pick_best_registry_version(self, versions, spec=None):
assert not spec or isinstance(spec, PackageSpec)
+2 -2
View File
@@ -44,7 +44,7 @@ class PackageManagerUninstallMixin(object):
# firstly, remove dependencies
if not skip_dependencies:
self._uninstall_dependencies(pkg, silent)
self.uninstall_dependencies(pkg, silent)
if os.path.islink(pkg.path):
os.unlink(pkg.path)
@@ -72,7 +72,7 @@ class PackageManagerUninstallMixin(object):
return pkg
def _uninstall_dependencies(self, pkg, silent=False):
def uninstall_dependencies(self, pkg, silent=False):
assert isinstance(pkg, PackageItem)
manifest = self.load_manifest(pkg)
if not manifest.get("dependencies"):
+25 -18
View File
@@ -74,17 +74,24 @@ class PackageManagerUpdateMixin(object):
).version
)
def update(self, from_spec, to_spec=None, only_check=False, silent=False):
def update( # pylint: disable=too-many-arguments
self,
from_spec,
to_spec=None,
only_check=False,
silent=False,
show_incompatible=True,
):
pkg = self.get_package(from_spec)
if not pkg or not pkg.metadata:
raise UnknownPackageError(from_spec)
if not silent:
click.echo(
"{} {:<45} {:<30}".format(
"{} {:<45} {:<35}".format(
"Checking" if only_check else "Updating",
click.style(pkg.metadata.spec.humanize(), fg="cyan"),
"%s (%s)" % (pkg.metadata.version, to_spec.requirements)
"%s @ %s" % (pkg.metadata.version, to_spec.requirements)
if to_spec and to_spec.requirements
else str(pkg.metadata.version),
),
@@ -97,17 +104,9 @@ class PackageManagerUpdateMixin(object):
outdated = self.outdated(pkg, to_spec)
if not silent:
self.print_outdated_state(outdated)
self.print_outdated_state(outdated, show_incompatible)
up_to_date = any(
[
outdated.detached,
not outdated.latest,
outdated.latest and outdated.current == outdated.latest,
outdated.wanted and outdated.current == outdated.wanted,
]
)
if only_check or up_to_date:
if only_check or not outdated.is_outdated(allow_incompatible=False):
return pkg
try:
@@ -117,18 +116,26 @@ class PackageManagerUpdateMixin(object):
self.unlock()
@staticmethod
def print_outdated_state(outdated):
def print_outdated_state(outdated, show_incompatible=True):
if outdated.detached:
return click.echo("[%s]" % (click.style("Detached", fg="yellow")))
if not outdated.latest or outdated.current == outdated.latest:
if (
not outdated.latest
or outdated.current == outdated.latest
or (not show_incompatible and outdated.current == outdated.wanted)
):
return click.echo("[%s]" % (click.style("Up-to-date", fg="green")))
if outdated.wanted and outdated.current == outdated.wanted:
return click.echo(
"[%s]"
% (click.style("Incompatible (%s)" % outdated.latest, fg="yellow"))
"[%s]" % (click.style("Incompatible %s" % outdated.latest, fg="yellow"))
)
return click.echo(
"[%s]" % (click.style(str(outdated.wanted or outdated.latest), fg="red"))
"[%s]"
% (
click.style(
"Outdated %s" % str(outdated.wanted or outdated.latest), fg="red"
)
)
)
def _update(self, pkg, outdated, silent=False):
+6
View File
@@ -190,6 +190,10 @@ class BasePackageManager( # pylint: disable=too-many-public-methods
return metadata
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)):
pkg_dir = os.path.join(self.package_dir, name)
@@ -213,6 +217,8 @@ class BasePackageManager( # pylint: disable=too-many-public-methods
except MissingPackageManifestError:
pass
result.append(pkg)
self.memcache_set(cache_key, result)
return result
def get_package(self, spec):
+164
View File
@@ -12,8 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from platformio import util
from platformio.exception import APIRequestError, InternetIsOffline
from platformio.package.exception import UnknownPackageError
from platformio.package.manager.base import BasePackageManager
from platformio.package.manager.tool import ToolPackageManager
from platformio.package.meta import PackageType
from platformio.platform.exception import IncompatiblePlatform, UnknownBoard
from platformio.platform.factory import PlatformFactory
from platformio.project.config import ProjectConfig
@@ -28,3 +34,161 @@ class PlatformPackageManager(BasePackageManager): # pylint: disable=too-many-an
@property
def manifest_names(self):
return PackageType.get_manifest_map()[PackageType.PLATFORM]
def install( # pylint: disable=arguments-differ, too-many-arguments
self,
spec,
with_packages=None,
without_packages=None,
skip_default_package=False,
with_all_packages=False,
silent=False,
force=False,
):
pkg = super(PlatformPackageManager, self).install(
spec, silent=silent, force=force, skip_dependencies=True
)
try:
p = PlatformFactory.new(pkg)
p.ensure_engine_compatible()
except IncompatiblePlatform as e:
super(PlatformPackageManager, self).uninstall(
pkg, silent=silent, skip_dependencies=True
)
raise e
if with_all_packages:
with_packages = list(p.packages)
p.install_packages(
with_packages,
without_packages,
skip_default_package,
silent=silent,
force=force,
)
p.install_python_packages()
p.on_installed()
self.cleanup_packages(list(p.packages))
return pkg
def uninstall(self, spec, silent=False, skip_dependencies=False):
pkg = self.get_package(spec)
if not pkg or not pkg.metadata:
raise UnknownPackageError(spec)
p = PlatformFactory.new(pkg)
assert super(PlatformPackageManager, self).uninstall(
pkg, silent=silent, skip_dependencies=True
)
if not skip_dependencies:
p.uninstall_python_packages()
p.on_uninstalled()
self.cleanup_packages(list(p.packages))
return pkg
def update( # pylint: disable=arguments-differ, too-many-arguments
self,
from_spec,
to_spec=None,
only_check=False,
silent=False,
show_incompatible=True,
only_packages=False,
):
pkg = self.get_package(from_spec)
if not pkg or not pkg.metadata:
raise UnknownPackageError(from_spec)
p = PlatformFactory.new(pkg)
pkgs_before = [item.metadata.name for item in p.get_installed_packages()]
new_pkg = None
missed_pkgs = set()
if not only_packages:
new_pkg = super(PlatformPackageManager, self).update(
from_spec,
to_spec,
only_check=only_check,
silent=silent,
show_incompatible=show_incompatible,
)
p = PlatformFactory.new(new_pkg)
missed_pkgs = set(pkgs_before) & set(p.packages)
missed_pkgs -= set(
item.metadata.name for item in p.get_installed_packages()
)
p.update_packages(only_check)
self.cleanup_packages(list(p.packages))
if missed_pkgs:
p.install_packages(
with_packages=list(missed_pkgs), skip_default_package=True
)
return new_pkg or pkg
def cleanup_packages(self, names):
self.memcache_reset()
deppkgs = {}
for platform in PlatformPackageManager().get_installed():
p = PlatformFactory.new(platform)
for pkg in p.get_installed_packages():
if pkg.metadata.name not in deppkgs:
deppkgs[pkg.metadata.name] = set()
deppkgs[pkg.metadata.name].add(pkg.metadata.version)
pm = ToolPackageManager()
for pkg in pm.get_installed():
if pkg.metadata.name not in names:
continue
if (
pkg.metadata.name not in deppkgs
or pkg.metadata.version not in deppkgs[pkg.metadata.name]
):
try:
pm.uninstall(pkg.metadata.spec)
except UnknownPackageError:
pass
self.memcache_reset()
return True
@util.memoized(expire="5s")
def get_installed_boards(self):
boards = []
for pkg in self.get_installed():
p = PlatformFactory.new(pkg)
for config in p.get_boards().values():
board = config.get_brief_data()
if board not in boards:
boards.append(board)
return boards
@staticmethod
def get_registered_boards():
return util.get_api_result("/boards", cache_valid="7d")
def get_all_boards(self):
boards = self.get_installed_boards()
know_boards = ["%s:%s" % (b["platform"], b["id"]) for b in boards]
try:
for board in self.get_registered_boards():
key = "%s:%s" % (board["platform"], board["id"])
if key not in know_boards:
boards.append(board)
except (APIRequestError, InternetIsOffline):
pass
return sorted(boards, key=lambda b: b["name"])
def board_config(self, id_, platform=None):
for manifest in self.get_installed_boards():
if manifest["id"] == id_ and (
not platform or manifest["platform"] == platform
):
return manifest
for manifest in self.get_registered_boards():
if manifest["id"] == id_ and (
not platform or manifest["platform"] == platform
):
return manifest
raise UnknownBoard(id_)
+3 -4
View File
@@ -19,10 +19,9 @@ from platformio.project.config import ProjectConfig
class ToolPackageManager(BasePackageManager): # pylint: disable=too-many-ancestors
def __init__(self, package_dir=None):
self.config = ProjectConfig.get_instance()
super(ToolPackageManager, self).__init__(
PackageType.TOOL, package_dir or self.config.get_optional_dir("packages"),
)
if not package_dir:
package_dir = ProjectConfig.get_instance().get_optional_dir("packages")
super(ToolPackageManager, self).__init__(PackageType.TOOL, package_dir)
@property
def manifest_names(self):