def test_package_raise_missing_values(): with pytest.raises(ValueError): Package(Path('/home'), None, 'pkg', 'url') with pytest.raises(ValueError): Package(Path('/home'), 'repo', None, 'url') with pytest.raises(ValueError): Package(Path('/home'), 'repo', 'pkg', None)
def install_package(pearl_env: PearlEnvironment, package: Package, args: Namespace): """ Installs the Pearl package. """ if package.is_installed(): raise PackageAlreadyInstalledError( '{} package is already installed.'.format(package)) messenger.print('{cyan}* {normal}Installing {pkg} package'.format( cyan=Color.CYAN, normal=Color.NORMAL, pkg=package, )) package.dir.mkdir(parents=True, exist_ok=True) if package.is_local(): check_and_copy(Path(package.url), package.dir) else: quiet = "false" if args.verbose else "true" script = dedent(""" install_git_repo {pkgurl} {pkgdir} "" {quiet} """).format(pkgdir=package.dir, pkgurl=package.url, quiet=quiet) run_pearl_bash(script, pearl_env, input=_DEFAULT_INPUT if args.no_confirm else None) package.vardir.mkdir(parents=True, exist_ok=True) hook = 'post_install' try: _run( hook, pearl_env, package, input=_DEFAULT_INPUT if args.no_confirm else None, enable_xtrace=(args.verbose >= 2), enable_errexit=(not args.force), ) except Exception as exc: msg = "Error while performing {} hook function. Rolling back...".format( hook) if args.force: message = "{}: {}".format(msg, exc.args) if args.verbose: messenger.exception(message) else: messenger.error(message) else: args.force = True remove_package( pearl_env, package, args=args, ) raise HookFunctionError(msg) from exc
def test_list_packages_not_matching(tmp_path): home_dir = create_pearl_home(tmp_path) (home_dir / 'packages/repo-test/pkg-a-test').mkdir(parents=True) pearl_env = mock.Mock() pearl_env.packages = { 'repo-test': { 'pkg-a-test': Package(home_dir, 'repo-test', 'pkg-a-test', 'url', 'descr'), 'pkg-b-test': Package(home_dir, 'repo-test', 'pkg-b-test', 'url', 'descr'), } } result = list_packages(pearl_env, PackageArgs(pattern='pkg2')) assert result == []
def test_list_packages_match_keyword(tmp_path): home_dir = create_pearl_home(tmp_path) (home_dir / 'packages/repo-test/pkg-a-test').mkdir(parents=True) pearl_env = mock.Mock() pearl_env.packages = { 'repo-test': { 'pkg-a-test': Package(home_dir, 'repo-test', 'pkg-a-test', 'url', 'descr', keywords=('pkg', 'pkg-manager')), 'pkg-b-test': Package(home_dir, 'repo-test', 'pkg-b-test', 'url', 'descr', keywords=('pkg',)), } } result = list_packages(pearl_env, PackageArgs(pattern='pkg-manager')) assert ['pkg-a-test'] == [pkg.name for pkg in result]
def test_list_packages_installed_only(tmp_path): home_dir = create_pearl_home(tmp_path) (home_dir / 'packages/repo-test/pkg-a-test').mkdir(parents=True) pearl_env = mock.Mock() pearl_env.packages = { 'repo-test': { 'pkg-a-test': Package(home_dir, 'repo-test', 'pkg-a-test', 'url', 'descr'), 'pkg-b-test': Package(home_dir, 'repo-test', 'pkg-b-test', 'url', 'descr'), } } result = list_packages(pearl_env, PackageArgs(pattern='pkg', installed_only=True)) assert ['pkg-a-test'] == [pkg.name for pkg in result]
def test_list_packages(tmp_path): home_dir = create_pearl_home(tmp_path) (home_dir / 'packages/repo-test/pkg-a-test').mkdir(parents=True) pearl_env = mock.Mock() pearl_env.packages = { 'repo-test': { 'pkg-a-test': Package(home_dir, 'repo-test', 'pkg-a-test', 'url', 'descr'), 'pkg-b-test': Package(home_dir, 'repo-test', 'pkg-b-test', 'url', 'descr'), } } result = list_packages(pearl_env, PackageArgs(pattern='pkg')) assert len(result) == 2 assert 'pkg-a-test' in [pkg.name for pkg in result] assert 'pkg-b-test' in [pkg.name for pkg in result]
def test_required_by(tmp_path): home_dir = create_pearl_home(tmp_path) packages_info = { "repo-test": { "pkg-test": { "repo_name": "repo-test", "name": "pkg-test", "url": "/blah", "depends": ["repo-test/pkg-test2"] }, "pkg-test2": { "repo_name": "repo-test", "name": "pkg-test2", "url": "/blah", "depends": [] } } } builder = PackageBuilder(home_dir) packages = builder.build_packages(packages_info) pearl_env = PearlEnvironment(home_dir, env_initialized=False) pearl_env._packages = packages requires = pearl_env.required_by( Package(home_dir, "repo-test", "pkg-test2", "/blah")) assert requires[0].full_name == 'repo-test/pkg-test'
def add_git_package( self, hooks_sh_script, repo_name='repo-test', package_name='pkg-test', url='https://github.com/pkg', git_url=None, is_installed=False, depends=(), ): if is_installed: if git_url is None: git_url = url self._install_package(hooks_sh_script, repo_name='repo-test', package_name='pkg-test', git_url=git_url) package = Package(self.home_dir, repo_name, package_name, url, '', depends=depends) self._update_packages(package)
def add_local_package( self, tmp_path, hooks_sh_script, repo_name='repo-test', package_name='pkg-test', is_installed=False, depends=(), ): """Install a package somewhere locally""" pkg_dir = tmp_path / '{}/{}'.format(repo_name, package_name) (pkg_dir / 'pearl-config').mkdir(parents=True) hooks_sh = pkg_dir / 'pearl-config/hooks.sh' hooks_sh.touch() hooks_sh.write_text(hooks_sh_script) if is_installed: self._install_package( hooks_sh_script, repo_name=repo_name, package_name=package_name, ) package = Package(self.home_dir, repo_name, package_name, str(pkg_dir), '', depends=depends) self._update_packages(package)
def test_list_packages_dependency_tree(tmp_path): home_dir = create_pearl_home(tmp_path) (home_dir / 'packages/repo-test/pkg-a-test').mkdir(parents=True) pearl_env = mock.Mock() pkg_a = Package(home_dir, 'repo-test', 'pkg-a-test', 'url', 'descr') pkg_b = Package(home_dir, 'repo-test', 'pkg-b-test', 'url', 'descr', depends=(pkg_a,)) pkg_c = Package(home_dir, 'repo-test', 'pkg-c-test', 'url', 'descr', depends=(pkg_b,)) pearl_env.packages = { 'repo-test': { 'pkg-a-test': pkg_a, 'pkg-b-test': pkg_b, 'pkg-c-test': pkg_c, } } result = list_packages(pearl_env, PackageArgs(pattern='pkg', dependency_tree=True)) assert ['pkg-a-test', 'pkg-b-test', 'pkg-c-test'] == [pkg.name for pkg in result]
def test_package_default_values(): pkg = Package(Path('/home'), 'repo', 'pkg', 'https://pkg.com') assert pkg.description == "None" assert pkg.homepage == "None" assert pkg.author == "None" assert pkg.license == "None" assert pkg.os == () assert pkg.depends == () assert pkg.keywords == ()
def emerge_package(pearl_env: PearlEnvironment, package: Package, args: Namespace): """ Installs or updates the Pearl package. This function is idempotent. """ if package.is_installed(): update_package(pearl_env, package, args=args) else: install_package(pearl_env, package, args=args)
def test_package(): pkg = Package(Path('/home'), 'repo', 'pkg1', 'https://pkg1', 'pkg1 descr') assert pkg.name == 'pkg1' assert pkg.repo_name == 'repo' assert pkg.full_name == 'repo/pkg1' assert pkg.url == 'https://pkg1' assert pkg.description == 'pkg1 descr' assert pkg.dir == Path('/home/packages/repo/pkg1') assert pkg.vardir == Path('/home/var/repo/pkg1') assert not pkg.is_local() pkg = Package(Path('/home'), 'repo', 'pkg1', '/pkg1', 'pkg1 descr') assert pkg.is_local()
def info_package(pearl_env: PearlEnvironment, package: Package, args: Namespace): """ Provide info about a package. """ requires = pearl_env.required_by(package) messenger.print( dedent(""" {cyan}Name{normal}: {full_name} {cyan}Description{normal}: {description} {cyan}Homepage{normal}: {homepage} {cyan}URL{normal}: {url} {cyan}Author{normal}: {author} {cyan}License{normal}: {license} {cyan}Operating Systems{normal}: {os} {cyan}Keywords{normal}: {keywords} {cyan}Installed{normal}: {installed} {cyan}Pkg Directory{normal}: {pkg_dir} {cyan}Var Directory{normal}: {var_dir} {cyan}Depends on{normal}: {depends} {cyan}Required by{normal}: {requires} """.format( cyan=Color.CYAN, normal=Color.NORMAL, full_name=package.full_name, description=package.description, homepage=package.homepage, url=package.url, author=package.author, license=package.license, os=tuple(o.name.lower() for o in package.os), keywords=package.keywords, installed=package.is_installed(), pkg_dir=package.dir, var_dir=package.vardir, depends=tuple(d.full_name for d in package.depends), requires=tuple(r.full_name for r in requires), ))) return package, requires
def remove_package(pearl_env: PearlEnvironment, package: Package, args: Namespace): """ Remove the Pearl package. """ if not package.is_installed(): raise PackageNotInstalledError( '{} package has not been installed.'.format(package)) messenger.print('{cyan}* {normal}Removing {pkg} package'.format( cyan=Color.CYAN, normal=Color.NORMAL, pkg=package, )) hook = 'pre_remove' try: _run( hook, pearl_env, package, input=_DEFAULT_INPUT if args.no_confirm else None, enable_xtrace=(args.verbose >= 2), enable_errexit=(not args.force), ) except Exception as exc: msg = "Error while performing {} hook function".format(hook) if not args.force: raise HookFunctionError(msg) from exc message = "{}: {}".format(msg, exc.args) if args.verbose: messenger.exception(message) else: messenger.error(message) shutil.rmtree(str(package.dir))
def update_package(pearl_env: PearlEnvironment, package: Package, args: Namespace): """ Updates the Pearl package. """ if not package.is_installed(): raise PackageNotInstalledError( '{} package has not been installed.'.format(package)) messenger.print('{cyan}* {normal}Updating {pkg} package'.format( cyan=Color.CYAN, normal=Color.NORMAL, pkg=package, )) if package.has_url_changed(): messenger.info("The package URL for {} has changed to {}".format( package.full_name, package.url)) messenger.info("Replacing the package with the new repository...") remove_package(pearl_env, package, args) install_package(pearl_env, package, args) hook = 'pre_update' try: _run( hook, pearl_env, package, input=_DEFAULT_INPUT if args.no_confirm else None, enable_xtrace=(args.verbose >= 2), enable_errexit=(not args.force), ) except Exception as exc: msg = "Error while performing {} hook function".format(hook) if not args.force: raise HookFunctionError(msg) from exc message = "{}: {}".format(msg, exc.args) if args.verbose: messenger.exception(message) else: messenger.error(message) if package.is_local(): check_and_copy(Path(package.url), package.dir) else: quiet = "false" if args.verbose else "true" script = dedent(""" update_git_repo {pkgdir} "" {quiet} """).format(pkgdir=package.dir, quiet=quiet) run_pearl_bash(script, pearl_env, input=_DEFAULT_INPUT if args.no_confirm else None) hook = 'post_update' try: _run( hook, pearl_env, package, input=_DEFAULT_INPUT if args.no_confirm else None, enable_xtrace=(args.verbose >= 2), enable_errexit=(not args.force), ) except Exception as exc: msg = "Error while performing {} hook function".format(hook) if not args.force: raise HookFunctionError(msg) from exc message = "{}: {}".format(msg, exc.args) if args.verbose: messenger.exception(message) else: messenger.error(message)