def ask(prompt: str, yes_as_default_answer: bool = False, no_confirm: bool = False): """ Ask a question and wait to receive an answer from stdin. It returns yes_as_default_answer if no answer has been received from stdin. """ if no_confirm: return yes_as_default_answer if yes_as_default_answer: default_answer = "Y" other_answer = "n" else: default_answer = "N" other_answer = "y" answer = None while answer not in ['Y', 'N']: messenger.info(f'{prompt} ({default_answer}/{other_answer})') answer = input("> ").upper() if not answer: answer = default_answer return answer == "Y"
def _load_repo(home, repo: str, update_repos=False, verbose: int = 0): m = hashlib.md5() # Add \n for compatibility with previous version of Pearl m.update('{}\n'.format(repo).encode()) md5_sum = m.hexdigest() if not (home / 'repos/{}/.git'.format(md5_sum)).is_dir(): messenger.info('Initializing {} repository...'.format(repo)) clone_command = [ 'git', 'clone', '--depth', '1', repo, '{}/repos/{}'.format(home, md5_sum) ] if not verbose: clone_command.append('--quiet') subprocess.run(clone_command) elif update_repos: messenger.info("Updating {} repository...".format(repo)) # The option -C works only for git 1.8.5 https://stackoverflow.com/a/20115678 pull_command = [ 'git', '-C', '{}/repos/{}'.format(home, md5_sum), 'pull' ] if not verbose: pull_command.append('--quiet') subprocess.run(pull_command) return home / 'repos/{}/pearl-config/repo.conf'.format(md5_sum)
def init_pearl(pearl_env: PearlEnvironment, _: Namespace): """ Initializes the Pearl environment by setting up the PEARL_HOME files and directories and the `pearl.conf` file. """ messenger.print( f'{Color.CYAN}* {Color.NORMAL}Setting up $PEARL_HOME directory as {pearl_env.home}' ) (pearl_env.home / 'bin').mkdir(parents=True, exist_ok=True) (pearl_env.home / 'packages').mkdir(parents=True, exist_ok=True) (pearl_env.home / 'repos').mkdir(parents=True, exist_ok=True) (pearl_env.home / 'var').mkdir(parents=True, exist_ok=True) static = Path(pkg_resources.resource_filename('pearllib', 'static/')) if (pearl_env.home / 'boot').exists(): (pearl_env.home / 'boot').unlink() (pearl_env.home / 'boot').symlink_to(static / 'boot') if not pearl_env.config_filename.exists(): messenger.print( f'{Color.CYAN}* {Color.NORMAL}Creating the Pearl configuration file {pearl_env.config_filename} from template $PEARL_HOME' ) pearl_env.config_filename.parent.mkdir(parents=True, exist_ok=True) pearl_conf_template = static / 'templates/pearl.conf.template' shutil.copyfile(str(pearl_conf_template), str(pearl_env.config_filename)) apply(f"source {pearl_env.home}/boot/sh/pearl.sh", f"{os.environ['HOME']}/.bashrc") messenger.print(f'{Color.CYAN}* {Color.NORMAL}Activated Pearl for Bash') apply(f"source {pearl_env.home}/boot/sh/pearl.sh", f"{os.environ['HOME']}/.zshrc") messenger.print(f'{Color.CYAN}* {Color.NORMAL}Activated Pearl for Zsh') apply(f"source {pearl_env.home}/boot/fish/pearl.fish", f"{os.environ['HOME']}/.config/fish/config.fish") messenger.print( f'{Color.CYAN}* {Color.NORMAL}Activated Pearl for Fish shell') apply(f"source {pearl_env.home}/boot/vim/pearl.vim", f"{os.environ['HOME']}/.vimrc") messenger.print( f'{Color.CYAN}* {Color.NORMAL}Activated Pearl for Vim editor') apply(f"(load-file \"{pearl_env.home}/boot/emacs/pearl.el\")", f"{os.environ['HOME']}/.emacs") messenger.print( f'{Color.CYAN}* {Color.NORMAL}Activated Pearl for Emacs editor') messenger.info('') messenger.info("Done! Open a new terminal and have fun!") messenger.info('') messenger.info("To get the list of Pearl packages available:") messenger.print(" >> pearl list")
def _extract_packages(pearl_env: PearlEnvironment, command: PearlCommand, args) -> List[Package]: try: return [ pearl_env.lookup_package(package_name) for package_name in args.packages ] except (RepoDoesNotExistError, PackageNotInRepoError): if command != PearlCommand.REMOVE: raise if args.force: # The user can still be able to remove a package even if package does not exist in any repository. return [ pearl_env.infer_package(package_name) for package_name in args.packages ] else: messenger.info("To remove the package, use option --force.") raise
def create_package(pearl_env: PearlEnvironment, args: Namespace): """ Creates package from template. """ static = Path(pkg_resources.resource_filename('pearllib', 'static/')) pearl_config_template = static / 'templates/pearl-config.template' dest_pearl_config = args.dest_dir / 'pearl-config' if dest_pearl_config.exists(): raise PackageCreateError( 'The pearl-config directory already exists in {}'.format( args.dest_dir)) shutil.copytree(str(pearl_config_template), str(dest_pearl_config)) messenger.info('Updating {} to add package in local repository...'.format( pearl_env.config_filename)) with pearl_env.config_filename.open('a') as pearl_conf_file: pearl_conf_file.write( 'PEARL_PACKAGES["{}"] = {{"url": "{}"}}\n'.format( args.name, args.dest_dir)) messenger.info( 'Run "pearl search local" to see your new local package available')
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)