Beispiel #1
0
    def test_depends_install(self):
        deps = DependencyUtils.install(PackageIdentifier.parse_list([]),
                                       self.pm.list_available_packages(),
                                       self.pm.list_installed_packages())
        self.__assert_deps(deps, [], AvailablePackage)

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_1.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, [
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0"
        ], AvailablePackage)

        self.pm.install_packages(
            PackageIdentifier.parse_list(["container-A_1.0"]))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_1.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, [], AvailablePackage)

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["container-A_2.0"]),
            self.pm.list_available_packages(),
            self.pm.list_installed_packages())
        self.__assert_deps(deps, ["container-D_1.0", "container-A_2.0"],
                           AvailablePackage)
Beispiel #2
0
    def test_resolve_latest(self):

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP, {})
        self.assertEqual(["version_2.0", "testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP,
            filtermap(IPMAP, "version_1.0"))
        self.assertEqual(["version_2.0", "testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["testlatest_1.0"]), APMAP,
            filtermap(IPMAP, "version_2.0"))
        self.assertEqual(["testlatest_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["testlatest_2.0"]), APMAP, {})
        self.assertEqual(["version_2.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))

        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["testlatest_2.0", "testlatest_2.1"]),
            APMAP, {})
        self.assertEqual(["version_2.0"],
                         list(map(str, map(IDENTIFIER_GETTER, deps))))
    def test_depends_installed(self):
        deps = DependencyUtils.installed(PackageIdentifier.parse_list(["container-A_1.0"]), self.pm.list_installed_packages(), ignore_unknown=True)
        self.__assert_deps(deps, [], InstalledPackage)

        self.pm.install_packages(PackageIdentifier.parse_list(["container-A_1.0"]))

        deps = DependencyUtils.installed(PackageIdentifier.parse_list(["container-A_1.0"]), self.pm.list_installed_packages())
        self.__assert_deps(deps, ["container-E_1.0", "container-B_1.0", "container-C_1.0", "container-A_1.0"], InstalledPackage)
Beispiel #4
0
    def test_upgrade(self):
        ideps, udeps = DependencyUtils.upgrade(None, APMAP,
                                               filtermap(IPMAP, "upgrade_1.0"))
        self.assertEqual([], [str(mf.identifier) for mf in ideps])
        self.assertEqual([], [str(mf.identifier) for mf in udeps])

        ideps, udeps = DependencyUtils.upgrade(
            None, APMAP,
            filtermap(IPMAP, "upgrade_1.0", "upgrade_1.1", "upgrade_1.2"))
        self.assertEqual(["upgrade_2.0"], [str(mf.identifier) for mf in ideps])
        self.assertEqual(["upgrade_1.1", "upgrade_1.2"],
                         [str(mf.identifier) for mf in udeps])
Beispiel #5
0
    def test_depends_prereq(self):
        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_2.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages()
        )
        self.__assert_deps(deps, ["prereq-A_1.0", "prereq-B_2.0"], AvailablePackage)

        self.pm.install_packages(PackageIdentifier.parse_list(["pkg-with-prereq_1.0"]))
        deps = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_2.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages()
        )
        self.__assert_deps(deps, ["prereq-A_1.0", "prereq-B_2.0"], None)
        self.assertIsInstance(deps[0], InstalledPackage)
        self.assertIsInstance(deps[1], AvailablePackage)
Beispiel #6
0
 def __execute_steps(self,
                     pi: PackageIdentifier,
                     ipmap: dict,
                     se_func: callable,
                     env: Environment = None):
     # Find the package
     ip = find_manifest(pi, ipmap)
     # The environment
     if env is None:
         env = Environment.build(self.build_builtin_environment(),
                                 self.build_user_environment())
     # build the dependencies
     deps = DependencyUtils.installed([pi],
                                      ipmap,
                                      env=env,
                                      ignore_unknown=True)
     # Update env
     env.append(self.build_packages_environment(deps))
     # Fix PREREQ_ROOT
     env.set_variable("LEAF_PREREQ_ROOT", self.install_folder)
     # The Variable resolver
     vr = VariableResolver(ip, ipmap.values())
     # Execute steps
     se = StepExecutor(self.logger, ip, vr, env=env)
     se_func(se)
Beispiel #7
0
 def get_profile_dependencies(self, profile, ipmap=None):
     """
     Returns all latest packages needed by a profile
     """
     return DependencyUtils.installed(
         profile.packages,
         ipmap or self.list_installed_packages(),
         only_keep_latest=True,
         env=self.build_pf_environment(profile))
    def test_prereq_order(self):
        pi = "prereq-D_1.0"

        prereqs = APMAP[PackageIdentifier.parse(pi)].requires_packages
        self.assertEqual(["prereq-true_1.0", "prereq-false_1.0"], prereqs)
        prereqs = DependencyUtils.prereq(PackageIdentifier.parse_list([pi]),
                                         APMAP, {})
        self.assertEqual(["prereq-false_1.0", "prereq-true_1.0"],
                         list(map(str, map(IDENTIFIER_GETTER, prereqs))))
Beispiel #9
0
    def test_uninstall(self):

        ipmap = OrderedDict()
        for ap in DependencyUtils.install(
                PackageIdentifier.parse_list(
                    ["container-A_1.0", "container-A_2.0"]), APMAP, {}):
            ipmap[ap.identifier] = IPMAP[ap.identifier]

        self.assertEqual([
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0", "container-D_1.0", "container-A_2.0"
        ], deps2strlist(ipmap.values()))

        deps = DependencyUtils.uninstall(
            PackageIdentifier.parse_list(["container-A_1.0"]), ipmap)

        self.assertEqual(
            ["container-A_1.0", "container-B_1.0", "container-E_1.0"],
            deps2strlist(deps))
Beispiel #10
0
    def test_latest_strategy(self):
        deps = DependencyUtils.installed(
            PackageIdentifier.parse_list(
                ["container-A_1.0", "container-A_2.0"]), IPMAP)
        self.assertEqual(
            [
                "container-E_1.0", "container-B_1.0", "container-C_1.0",
                "container-A_1.0", "container-D_1.0", "container-A_2.0"
            ],
            list(map(str, map(IDENTIFIER_GETTER, deps))),
        )

        deps = DependencyUtils.installed(PackageIdentifier.parse_list(
            ["container-A_1.0", "container-A_2.0"]),
                                         IPMAP,
                                         only_keep_latest=True)
        self.assertEqual(
            ["container-C_1.0", "container-D_1.0", "container-A_2.0"],
            list(map(str, map(IDENTIFIER_GETTER, deps))))
Beispiel #11
0
    def test_install(self):
        deps = DependencyUtils.install(PackageIdentifier.parse_list(
            ["container-A_1.0", "container-A_2.0"]),
                                       APMAP, {},
                                       env=Environment())
        self.assertEqual([
            "container-E_1.0", "container-B_1.0", "container-C_1.0",
            "container-A_1.0", "container-D_1.0", "container-A_2.0"
        ], deps2strlist(deps))

        deps = DependencyUtils.install(PackageIdentifier.parse_list(
            ["container-A_1.0", "container-A_2.0"]),
                                       APMAP,
                                       filtermap(IPMAP, "container-E_1.0"),
                                       env=Environment())
        self.assertEqual([
            "container-B_1.0", "container-C_1.0", "container-A_1.0",
            "container-D_1.0", "container-A_2.0"
        ], deps2strlist(deps))
    def test_depends_with_custom_env(self):
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-B_1.0", "condition-D_1.0", "condition-F_1.0", "condition-H_1.0", "condition_1.0"], AvailablePackage)

        self.pm.update_user_environment(set_map={"FOO": "HELLO"})
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-A_1.0", "condition-D_1.0", "condition-F_1.0", "condition-H_1.0", "condition_1.0"], AvailablePackage)

        self.pm.update_user_environment(set_map={"FOO": "HELLO"})
        env = Environment.build(self.pm.build_builtin_environment(), self.pm.build_user_environment(), Environment("Custom env", {"FOO": "BAR"}))
        deps = DependencyUtils.install(
            PackageIdentifier.parse_list(["condition_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages(), env=env
        )
        self.__assert_deps(deps, ["condition-A_1.0", "condition-C_1.0", "condition-F_1.0", "condition_1.0"], AvailablePackage)
Beispiel #13
0
    def test_rdepends(self):

        for mfmap in (IPMAP, APMAP):
            pilist = DependencyUtils.rdepends(
                PackageIdentifier.parse_list(["condition-A_1.0"]), mfmap)
            self.assertEqual(["condition_1.0"], list(map(str, pilist)))

            pilist = DependencyUtils.rdepends(PackageIdentifier.parse_list(
                ["condition-A_1.0"]),
                                              mfmap,
                                              env=Environment(None, {}))
            self.assertEqual([], list(map(str, pilist)))

            pilist = DependencyUtils.rdepends(
                PackageIdentifier.parse_list(["condition-A_1.0"]),
                mfmap,
                env=Environment(None, {"FOO": "BAR"}))
            self.assertEqual(["condition_1.0"], list(map(str, pilist)))

            pilist = DependencyUtils.rdepends(PackageIdentifier.parse_list(
                ["condition-B_1.0"]),
                                              mfmap,
                                              env=Environment(None, {}))
            self.assertEqual(["condition_1.0"], list(map(str, pilist)))

            pilist = DependencyUtils.rdepends(
                PackageIdentifier.parse_list(["condition-B_1.0"]),
                mfmap,
                env=Environment(None, {"FOO": "BAR"}))
            self.assertEqual([], list(map(str, pilist)))

            pilist = DependencyUtils.rdepends(
                PackageIdentifier.parse_list(["condition-B_1.0"]), {})
            self.assertEqual([], list(map(str, pilist)))
Beispiel #14
0
    def provision_profile(self, profile):
        if not profile.folder.is_dir():
            # Create folder if needed
            profile.folder.mkdir(parents=True)
        else:
            # Clean folder content
            for item in profile.folder.glob("*"):
                if item.is_symlink():
                    item.unlink()
                else:
                    shutil.rmtree(str(item))

        # Check if all needed packages are installed
        missing_packages = DependencyUtils.install(
            profile.packages,
            self.list_available_packages(),
            self.list_installed_packages(),
            env=self.build_pf_environment(profile))
        if len(missing_packages) == 0:
            self.logger.print_verbose("All packages are already installed")
        else:
            self.logger.print_default("Profile is out of sync")
            try:
                self.install_packages(profile.packages,
                                      env=self.build_pf_environment(profile))
            except Exception as e:
                raise ProfileProvisioningException(e)

        # Do all needed links
        errors = 0
        for ip in self.get_profile_dependencies(profile):
            pi_folder = profile.folder / ip.identifier.name
            if pi_folder.exists():
                pi_folder = profile.folder / str(ip.identifier)
            try:
                env = self.build_pf_environment(profile)
                self.sync_packages([ip.identifier], env=env)
                pi_folder.symlink_to(ip.folder)
            except Exception as e:
                errors += 1
                self.logger.print_error(
                    "Error while sync operation on {ip.identifier}".format(
                        ip=ip))
                self.logger.print_error(str(e))
                print_trace()

        # Touch folder when provisionning is done without error
        if errors == 0:
            profile.folder.touch(exist_ok=True)
Beispiel #15
0
    def execute(self, args, uargs):
        pm = PackageManager()

        env = Environment.build(pm.build_builtin_environment(),
                                pm.build_user_environment())

        install_list, uninstall_list = DependencyUtils.upgrade(
            None if len(args.packages) == 0 else args.packages,
            pm.list_available_packages(),
            pm.list_installed_packages(),
            env=env)

        pm.logger.print_verbose(
            "{count} package(s) to be upgraded: {text}".format(
                count=len(install_list),
                text=" ".join([str(ap.identifier) for ap in install_list])))
        if args.clean:
            pm.logger.print_verbose(
                "{count} package(s) to be removed: {text}".format(
                    count=len(uninstall_list),
                    text=" ".join(
                        [str(ip.identifier) for ip in uninstall_list])))

        if len(install_list) == 0:
            pm.logger.print_default("No package to upgrade")
        else:
            pm.install_packages(map(IDENTIFIER_GETTER, install_list), env=env)
            if len(uninstall_list) > 0:
                if args.clean:
                    pm.uninstall_packages(
                        map(IDENTIFIER_GETTER, uninstall_list))
                else:
                    pm.logger.print_default(
                        "These packages can be removed:",
                        " ".join([str(ip.identifier)
                                  for ip in uninstall_list]))
Beispiel #16
0
    def uninstall_packages(self, pilist: list):
        """
        Remove given package
        """
        with self.application_lock.acquire():
            ipmap = self.list_installed_packages()

            iplist_to_remove = DependencyUtils.uninstall(pilist,
                                                         ipmap,
                                                         logger=self.logger)

            if len(iplist_to_remove) == 0:
                self.logger.print_default("No package to remove")
            else:
                # Confirm
                text = ", ".join(
                    [str(ip.identifier) for ip in iplist_to_remove])
                self.logger.print_quiet(
                    "Packages to uninstall: {packages}".format(packages=text))
                self.print_with_confirm(raise_on_decline=True)
                for ip in iplist_to_remove:
                    if ip.read_only:
                        raise LeafException(
                            "Cannot uninstall system package {ip.identifier}".
                            format(ip=ip))
                    self.logger.print_default(
                        "Removing {ip.identifier}".format(ip=ip))
                    self.__execute_steps(ip.identifier, ipmap,
                                         StepExecutor.uninstall)
                    self.logger.print_verbose(
                        "Remove folder: {ip.folder}".format(ip=ip))
                    rmtree_force(ip.folder)
                    del ipmap[ip.identifier]

                self.logger.print_default("{count} package(s) removed".format(
                    count=len(iplist_to_remove)))
Beispiel #17
0
    def test_prereq(self):
        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_1.0"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
        for p in prereqs:
            self.assertTrue(isinstance(p, AvailablePackage))

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_1.0"]), APMAP,
            IPMAP)
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
        for p in prereqs:
            self.assertTrue(isinstance(p, InstalledPackage))

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_2.0"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_2.0"])

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-prereq_0.1"]), APMAP, {})
        self.assertEqual(list(map(str, prereqs)), ["prereq-A_0.1-fail"])

        prereqs = DependencyUtils.prereq(
            PackageIdentifier.parse_list(["pkg-with-deps-with-prereq_1.0"]),
            APMAP, {})
        self.assertEqual(list(map(str, prereqs)), [])
        install = DependencyUtils.install(
            PackageIdentifier.parse_list(["pkg-with-deps-with-prereq_1.0"]),
            APMAP, {})
        prereqs = DependencyUtils.prereq([x.identifier for x in install],
                                         APMAP, {})
        self.assertEqual(list(map(str, prereqs)),
                         ["prereq-A_1.0", "prereq-B_1.0"])
Beispiel #18
0
    def install_packages(self,
                         pilist: list,
                         env: Environment = None,
                         keep_folder_on_error: bool = False):
        """
        Compute dependency tree, check compatibility, download from remotes and extract needed packages
        @return: InstalledPackage list
        """
        with self.application_lock.acquire():
            prereq_install_folder = None
            ipmap = self.list_installed_packages()
            apmap = self.list_available_packages()
            out = []

            # Build env to resolve dynamic dependencies
            if env is None:
                env = Environment.build(self.build_builtin_environment(),
                                        self.build_user_environment())

            try:
                ap_to_install = DependencyUtils.install(pilist,
                                                        apmap,
                                                        ipmap,
                                                        env=env)

                # Check leaf min version
                min_version = check_leaf_min_version(ap_to_install)
                if min_version:
                    raise LeafOutOfDateException(
                        "You need to upgrade leaf to v{version} to install {text}"
                        .format(version=min_version,
                                text=", ".join([
                                    str(ap.identifier) for ap in ap_to_install
                                ])))

                # Check nothing to do
                if len(ap_to_install) == 0:
                    self.logger.print_default("All packages are installed")
                else:
                    # Check available size
                    download_totalsize = 0
                    for ap in ap_to_install:
                        if ap.size is not None:
                            download_totalsize += ap.size
                    fs_check_free_space(self.download_cache_folder,
                                        download_totalsize)

                    # Confirm
                    text = ", ".join(
                        [str(ap.identifier) for ap in ap_to_install])
                    self.logger.print_quiet(
                        "Packages to install: {packages}".format(
                            packages=text))
                    if download_totalsize > 0:
                        self.logger.print_default(
                            "Total size:", sizeof_fmt(download_totalsize))
                    self.print_with_confirm(raise_on_decline=True)

                    # Install prereq
                    prereq_to_install = DependencyUtils.prereq(pilist,
                                                               apmap,
                                                               ipmap,
                                                               env=env)

                    if len(prereq_to_install) > 0:
                        self.logger.print_default("Check required packages")
                        prereq_install_folder = mkdir_tmp_leaf_dir()
                        self.install_prereq(
                            [p.identifier for p in prereq_to_install],
                            prereq_install_folder,
                            apmap=apmap,
                            env=env)

                    # Download ap list
                    self.logger.print_default(
                        "Downloading {size} package(s)".format(
                            size=len(ap_to_install)))
                    la_to_install = []
                    for ap in ap_to_install:
                        la_to_install.append(self.__download_ap(ap))

                    # Check the extracted size
                    extracted_totalsize = 0
                    for la in la_to_install:
                        if la.final_size is not None:
                            extracted_totalsize += la.final_size
                        else:
                            extracted_totalsize += la.get_total_size()
                    fs_check_free_space(self.install_folder,
                                        extracted_totalsize)

                    # Extract la list
                    for la in la_to_install:
                        self.logger.print_default(
                            "[{current}/{total}] Installing {la.identifier}".
                            format(current=(len(out) + 1),
                                   total=len(la_to_install),
                                   la=la))
                        ip = self.__extract_artifact(
                            la,
                            env,
                            self.install_folder,
                            ipmap=ipmap,
                            keep_folder_on_error=keep_folder_on_error)
                        out.append(ip)

            finally:
                if not keep_folder_on_error and prereq_install_folder is not None:
                    self.logger.print_verbose(
                        "Remove prereq root folder {folder}".format(
                            folder=prereq_install_folder))
                    rmtree_force(prereq_install_folder)

            return out
Beispiel #19
0
    def execute(self, args, uargs):
        pm = PackageManager()
        env = None
        # If the user specified env values, build a complete env
        if args.custom_envlist is not None:
            env = Environment.build(
                pm.build_builtin_environment(), pm.build_user_environment(),
                Environment("Custom env",
                            env_list_to_map(args.custom_envlist)))

        items = None
        if args.dependency_type == "available":
            items = DependencyUtils.install(PackageIdentifier.parse_list(
                args.packages),
                                            pm.list_available_packages(), {},
                                            env=env)
        elif args.dependency_type == "install":
            items = DependencyUtils.install(PackageIdentifier.parse_list(
                args.packages),
                                            pm.list_available_packages(),
                                            pm.list_installed_packages(),
                                            env=env)
        elif args.dependency_type == "installed":
            items = DependencyUtils.installed(PackageIdentifier.parse_list(
                args.packages),
                                              pm.list_installed_packages(),
                                              env=env,
                                              ignore_unknown=True)
        elif args.dependency_type == "uninstall":
            items = DependencyUtils.uninstall(PackageIdentifier.parse_list(
                args.packages),
                                              pm.list_installed_packages(),
                                              env=env)
        elif args.dependency_type == "prereq":
            items = DependencyUtils.prereq(PackageIdentifier.parse_list(
                args.packages),
                                           pm.list_available_packages(),
                                           pm.list_installed_packages(),
                                           env=env)
        elif args.dependency_type == "upgrade":
            items, _ = DependencyUtils.upgrade(
                None if len(args.packages) == 0 else args.packages,
                pm.list_available_packages(),
                pm.list_installed_packages(),
                env=env)
        elif args.dependency_type == "rdepends":
            mfmap = OrderedDict()
            mfmap.update(
                DependencyUtils.rdepends(PackageIdentifier.parse_list(
                    args.packages),
                                         pm.list_available_packages(),
                                         env=env))
            mfmap.update(
                DependencyUtils.rdepends(PackageIdentifier.parse_list(
                    args.packages),
                                         pm.list_installed_packages(),
                                         env=env))
            items = mfmap.values()
        else:
            raise ValueError()

        rend = ManifestListRenderer()
        rend.extend(items)
        pm.print_renderer(rend)
Beispiel #20
0
    def execute(self, args, uargs):
        pm = PackageManager()
        wm = self.get_workspacemanager()
        profilename = wm.current_profile_name
        profile = wm.get_profile(profilename)

        env = Environment.build(pm.build_builtin_environment(),
                                pm.build_user_environment())

        install_list, upgraded_list = DependencyUtils.upgrade(
            None if len(args.packages) == 0 else args.packages,
            pm.list_available_packages(),
            pm.list_installed_packages(),
            env=env)

        pm.logger.print_verbose(
            "{count} package(s) to be upgraded: {text}".format(
                count=len(install_list),
                text=" ".join([str(ap.identifier) for ap in install_list])))
        if args.clean:
            pm.logger.print_verbose(
                "{count} package(s) to be removed: {text}".format(
                    count=len(upgraded_list),
                    text=" ".join([str(ip.identifier)
                                   for ip in upgraded_list])))

        if len(install_list) == 0:
            pm.logger.print_default("No package to upgrade")
        else:
            pm.install_packages(map(IDENTIFIER_GETTER, install_list), env=env)
            if len(upgraded_list) > 0:
                if args.clean:
                    pm.uninstall_packages(map(IDENTIFIER_GETTER,
                                              upgraded_list))
                else:
                    pm.logger.print_default(
                        "Packages upgraded:",
                        " ".join([str(ip.identifier) for ip in upgraded_list]))
                    pm.logger.print_default(
                        'Hint: Use "leaf profile config -p {PACKAGENAME}" to add these packages to your workspace profile'
                    )

        update_pilist = install_list
        profile_pkg_map = profile.pkg_map

        installed_packages = group_package_identifiers_by_name(
            wm.list_installed_packages())
        pkg_list = args.packages if args.packages else profile_pkg_map.keys()

        for pkg in pkg_list:
            pi = None
            if pkg in installed_packages.keys():
                # Get latest version
                pi = installed_packages[pkg][-1]

            if pi is not None and pi not in update_pilist:
                # Get PI in profile
                previous_pi = PackageIdentifier(pi.name, profile_pkg_map[
                    pi.name]) if pi.name in profile_pkg_map else None
                if previous_pi is None:
                    # Package is not in profile yet, add it
                    update_pilist.append(pi)
                elif previous_pi != pi:
                    # Package is already in profile with a different version, update it
                    update_pilist.append(pi)
                else:
                    # Package is already in profile with same version, do nothing
                    pass

        if len(update_pilist) == 0:
            pm.logger.print_default(
                "Packages are already in profile with same version")
        else:
            pm.logger.print_default(
                "Packages to be updated in profile:",
                " ".join([str(pi) for pi in update_pilist]))
            profile.add_packages(update_pilist)
            wm.update_profile(profile)
Beispiel #21
0
    def execute(self, args, uargs):
        wm = self.get_workspacemanager(check_initialized=False)

        ipmap = wm.list_installed_packages()
        searching_iplist = None

        if args.package is not None:
            # User forces the package
            searching_iplist = DependencyUtils.installed(
                [args.package],
                ipmap,
                env=Environment.build(wm.build_builtin_environment(),
                                      wm.build_user_environment()))
        else:
            # Use installed packages
            searching_iplist = keep_latest_mf(ipmap.values())

        topics = self.get_topics(searching_iplist)
        if args.topic is not None:
            topic = self.find_topic(topics, args.topic)
            fmt = args.format
            if fmt is None:
                # No format given
                if LeafSettings.HELP_DEFAULT_FORMAT.value in topic.resources.keys(
                ):
                    # Default format is available
                    fmt = LeafSettings.HELP_DEFAULT_FORMAT.value
                elif len(topic.resources.keys()) == 1:
                    # Only one format available
                    fmt = next(iter(topic.resources.keys()))

            if fmt is None or fmt not in topic.resources.keys():
                # Ensure that this topic is available for needed format
                raise LeafException(
                    "You need to specify a format for topic '{topic}'".format(
                        topic=args.topic),
                    hints=[
                        "For example 'leaf help --format {fmt} {topic}'".
                        format(fmt=fmt, topic=args.topic)
                        for fmt in topic.resources.keys()
                    ],
                )

            # Resolve resource path since it can contain @{} variables
            resource = VariableResolver(topic.installed_package,
                                        ipmap.values()).resolve(
                                            topic.resources[fmt])
            if fmt == "man":
                # If format is 'man', use manpage reader
                command = [
                    "man", "-P", "cat"
                ] if LeafSettings.NON_INTERACTIVE.as_boolean() else ["man"]
                command.append(resource)
                subprocess.check_call(command)
            else:
                # Use default resource handler
                subprocess.check_call(
                    [LeafSettings.HELP_DEFAULT_OPEN.value, resource])
        else:
            # Print mode
            scope = "installed packages"
            if args.package is not None:
                scope = args.package
            rend = HelpTopicListRenderer(scope, filter_format=args.format)
            rend.extend(searching_iplist)
            wm.print_renderer(rend)
 def test_depends_prereq(self):
     deps = DependencyUtils.prereq(PackageIdentifier.parse_list(["prereq-D_1.0"]), self.pm.list_available_packages(), self.pm.list_installed_packages())
     self.__assert_deps(deps, ["prereq-false_1.0", "prereq-true_1.0"], AvailablePackage)
Beispiel #23
0
    def execute(self, args, uargs):
        wm = self.get_workspacemanager(check_initialized=False)

        ipmap = wm.list_installed_packages()
        searching_iplist = None
        env = None

        if args.package is not None:
            # User forces the package
            env = Environment.build(wm.build_builtin_environment(),
                                    wm.build_user_environment())
            searching_iplist = DependencyUtils.installed([args.package],
                                                         ipmap,
                                                         env=env)
            env.append(wm.build_packages_environment(searching_iplist))
        elif wm.is_initialized:
            # We are in a workspace, use the current profile
            pfname = wm.current_profile_name
            profile = wm.get_profile(pfname)
            wm.is_profile_sync(profile, raise_if_not_sync=True)
            searching_iplist = wm.get_profile_dependencies(profile)
            env = wm.build_full_environment(profile)
        else:
            # Use installed packages
            searching_iplist = sorted(ipmap.values(), key=IDENTIFIER_GETTER)

        # Execute
        if args.binary is None:
            # Print mode
            scope = "installed packages"
            if args.package is not None:
                scope = args.package
            elif wm.is_initialized:
                scope = "workspace"
            rend = EntrypointListRenderer(scope)
            rend.extend(searching_iplist)
            wm.print_renderer(rend,
                              verbosity=Verbosity.QUIET
                              if args.oneline else Verbosity.DEFAULT)
        elif args.oneline:
            # User gave BIN and --oneline
            raise LeafException(
                "You must specify a binary or '--oneline', not both",
                hints=[
                    "Run 'leaf run --oneline' to list all binaries",
                    "Run 'leaf run {bin} -- --oneline {uargs}' pass --oneline to the binary"
                    .format(bin=args.binary, uargs=" ".join(uargs)),
                ],
            )
        else:
            # Search entry point
            candidate_ip = None
            for ip in searching_iplist:
                if args.binary in ip.binaries:
                    if candidate_ip is None:
                        candidate_ip = ip
                    elif candidate_ip.name != ip.name:
                        raise LeafException(
                            "Binary {bin} is declared by multiple packages".
                            format(bin=args.binary))
                    elif ip.identifier > candidate_ip.identifier:
                        candidate_ip = ip
            if candidate_ip is None:
                raise LeafException(
                    "Cannot find binary {bin}".format(bin=args.binary))

            if env is None:
                env = Environment.build(wm.build_builtin_environment(),
                                        wm.build_user_environment())
                env.append(
                    wm.build_packages_environment(
                        DependencyUtils.installed([candidate_ip.identifier],
                                                  ipmap=ipmap,
                                                  env=env)))

            ep = candidate_ip.binaries[args.binary]
            vr = VariableResolver(candidate_ip, ipmap.values())
            return execute_command(vr.resolve(ep.command),
                                   *uargs,
                                   print_stdout=True,
                                   env=env)
Beispiel #24
0
 def _getdeps(env, ipmap):
     return DependencyUtils.install(PackageIdentifier.parse_list(
         ["condition_1.0"]),
                                    APMAP,
                                    ipmap,
                                    env=env)
Beispiel #25
0
    def install_packages(self,
                         items: list,
                         env: Environment = None,
                         keep_folder_on_error: bool = False):
        """
        Compute dependency tree, check compatibility, download from remotes and extract needed packages
        @return: InstalledPackage list
        """
        with self.application_lock.acquire():
            ipmap = self.list_installed_packages()
            apmap = self.list_available_packages()
            pilist = []
            for item in items:
                if isinstance(item, PackageIdentifier):
                    # Package identifier is given
                    pilist.append(item)
                elif PackageIdentifier.is_valid_identifier(item):
                    # Package identifier string given
                    pilist.append(PackageIdentifier.parse(item))
                else:
                    # If leaf artifacts are given, add/replace identifiers of available packages
                    la = LeafArtifact(Path(item))
                    pilist.append(la.identifier)
                    apmap[la.identifier] = la
            out = []

            # Build env to resolve dynamic dependencies
            if env is None:
                env = Environment.build(self.build_builtin_environment(),
                                        self.build_user_environment())

            ap_to_install = DependencyUtils.install(pilist,
                                                    apmap,
                                                    ipmap,
                                                    env=env)

            # Check leaf min version
            min_version = check_leaf_min_version(ap_to_install)
            if min_version:
                raise LeafOutOfDateException(
                    "You need to upgrade leaf to v{version} to install {text}".
                    format(version=min_version,
                           text=", ".join(
                               [str(ap.identifier) for ap in ap_to_install])))

            # Check nothing to do
            if len(ap_to_install) == 0:
                self.logger.print_default("All packages are installed")
            else:
                # Check available size
                download_totalsize = 0
                download_count = 0
                for ap in [
                        ap for ap in ap_to_install
                        if isinstance(ap, AvailablePackage)
                ]:
                    download_count += 1
                    if ap.size is not None:
                        download_totalsize += ap.size
                fs_check_free_space(self.download_cache_folder,
                                    download_totalsize)

                # Confirm
                text = ", ".join([str(ap.identifier) for ap in ap_to_install])
                self.logger.print_quiet(
                    "Packages to install: {packages}".format(packages=text))
                if download_totalsize > 0:
                    self.logger.print_default("Total size:",
                                              sizeof_fmt(download_totalsize))
                self.print_with_confirm(raise_on_decline=True)

                # Install prereq
                prereq_to_install = DependencyUtils.prereq(
                    [ap.identifier for ap in ap_to_install],
                    apmap,
                    ipmap,
                    env=env)

                if len(prereq_to_install) > 0:
                    try:
                        self.__install_prereq(
                            prereq_to_install,
                            ipmap,
                            env=env,
                            keep_folder_on_error=keep_folder_on_error)
                    except BaseException as e:
                        raise PrereqException(e)

                # Download ap list
                self.logger.print_default(
                    "Downloading {size} package(s)".format(
                        size=download_count))
                la_to_install = []
                for mf in ap_to_install:
                    if isinstance(mf, AvailablePackage):
                        la_to_install.append(self.__download_ap(mf))
                    elif isinstance(mf, LeafArtifact):
                        la_to_install.append(mf)

                # Check the extracted size
                extracted_totalsize = 0
                for la in la_to_install:
                    if la.final_size is not None:
                        extracted_totalsize += la.final_size
                    else:
                        extracted_totalsize += la.get_total_size()
                fs_check_free_space(self.install_folder, extracted_totalsize)

                # Extract la list
                for la in la_to_install:
                    self.logger.print_default(
                        "[{current}/{total}] Installing {la.identifier}".
                        format(current=(len(out) + 1),
                               total=len(la_to_install),
                               la=la))
                    ip = self.__extract_artifact(
                        la,
                        env,
                        ipmap,
                        keep_folder_on_error=keep_folder_on_error)
                    out.append(ip)

            return out