def activate(self, env: VirtualEnv) -> None: if WINDOWS: return env.execute(self.path) import shlex terminal = Terminal() with env.temp_environ(): c = pexpect.spawn(self._path, ["-i"], dimensions=(terminal.height, terminal.width)) if self._name == "zsh": c.setecho(False) activate_script = self._get_activate_script() bin_dir = "Scripts" if WINDOWS else "bin" activate_path = env.path / bin_dir / activate_script c.sendline("{} {}".format(self._get_source_command(), shlex.quote(str(activate_path)))) def resize(sig: Any, data: Any) -> None: terminal = Terminal() c.setwinsize(terminal.height, terminal.width) signal.signal(signal.SIGWINCH, resize) # Interact with the new shell. c.interact(escape_character=None) c.close() sys.exit(c.exitstatus)
def test_dimensions(self): os.environ['COLUMNS'] = '100' os.environ['LINES'] = '50' terminal = Terminal() self.assertEqual(100, terminal.width) self.assertEqual(50, terminal.height)
def __init__( self, stream: TextIO, sections: List["SectionOutput"], verbosity: Verbosity = Verbosity.NORMAL, decorated: Optional[bool] = None, formatter: Optional[Formatter] = None, ) -> None: super().__init__(stream, verbosity=verbosity, decorated=decorated, formatter=formatter) self._content = [] self._lines = 0 sections.insert(0, self) self._sections = sections self._terminal = Terminal()
def __init__( self, io: Union[IO, Output], max: int = 0, min_seconds_between_redraws: float = 0.1, ) -> None: # If we have an IO, ensure we write to the error output if isinstance(io, IO): io = io.error_output self._io = io self._terminal = Terminal() self._max = 0 self._step_width = None self._set_max_steps(max) self._step = 0 self._percent = 0.0 self._format = None self._internal_format = None self._format_line_count = 0 self._previous_message = None self._should_overwrite = True self._min_seconds_between_redraws = 0 self._max_seconds_between_redraws = 1 self._write_count = 0 if min_seconds_between_redraws > 0: self.redraw_freq = None self._min_seconds_between_redraws = min_seconds_between_redraws if not self._io.formatter.is_decorated(): # Disable overwrite when output does not support ANSI codes. self._should_overwrite = False # Set a reasonable redraw frequency so output isn't flooded self.redraw_freq = None self._messages = {} self._start_time = time.time() self._last_write_time = 0 self._cursor = Cursor(self._io)
def activate(self, env: "VirtualEnv") -> Optional[int]: activate_script = self._get_activate_script() bin_dir = "Scripts" if WINDOWS else "bin" activate_path = env.path / bin_dir / activate_script # mypy requires using sys.platform instead of WINDOWS constant # in if statements to properly type check on Windows if sys.platform == "win32": if self._name in ("powershell", "pwsh"): args = ["-NoExit", "-File", str(activate_path)] else: # /K will execute the bat file and # keep the cmd process from terminating args = ["/K", str(activate_path)] completed_proc = subprocess.run([self.path, *args]) return completed_proc.returncode import shlex terminal = Terminal() with env.temp_environ(): c = pexpect.spawn(self._path, ["-i"], dimensions=(terminal.height, terminal.width)) if self._name == "zsh": c.setecho(False) c.sendline( f"{self._get_source_command()} {shlex.quote(str(activate_path))}") def resize(sig: Any, data: Any) -> None: terminal = Terminal() c.setwinsize(terminal.height, terminal.width) signal.signal(signal.SIGWINCH, resize) # Interact with the new shell. c.interact(escape_character=None) c.close() sys.exit(c.exitstatus)
def resize(sig: Any, data: Any) -> None: terminal = Terminal() c.setwinsize(terminal.height, terminal.width)
def handle(self) -> Optional[int]: from cleo.io.null_io import NullIO from cleo.terminal import Terminal from poetry.puzzle.solver import Solver from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.repositories.repository import Repository from poetry.utils.helpers import get_package_version_display_string package = self.argument("package") if self.option("tree"): self.init_styles(self.io) if self.option("outdated"): self._io.input.set_option("latest", True) excluded_groups = [] included_groups = [] only_groups = [] if self.option("no-dev"): self.line( "<warning>The `<fg=yellow;options=bold>--no-dev</>` option is deprecated," "use the `<fg=yellow;options=bold>--without dev</>` notation instead.</warning>" ) excluded_groups.append("dev") excluded_groups.extend([ group.strip() for groups in self.option("without") for group in groups.split(",") ]) included_groups.extend([ group.strip() for groups in self.option("with") for group in groups.split(",") ]) only_groups.extend([ group.strip() for groups in self.option("only") for group in groups.split(",") ]) if self.option("default"): only_groups.append("default") locked_repo = self.poetry.locker.locked_repository(True) if only_groups: root = self.poetry.package.with_dependency_groups(only_groups, only=True) else: root = self.poetry.package.with_dependency_groups( included_groups).without_dependency_groups(excluded_groups) # Show tree view if requested if self.option("tree") and not package: requires = root.all_requires packages = locked_repo.packages for pkg in packages: for require in requires: if pkg.name == require.name: self.display_package_tree(self._io, pkg, locked_repo) break return 0 table = self.table(style="compact") locked_packages = locked_repo.packages pool = Pool(ignore_repository_names=True) pool.add_repository(locked_repo) solver = Solver( root, pool=pool, installed=Repository(), locked=locked_repo, io=NullIO(), ) solver.provider.load_deferred(False) with solver.use_environment(self.env): ops = solver.solve() required_locked_packages = set( [op.package for op in ops if not op.skipped]) if package: pkg = None for locked in locked_packages: if package.lower() == locked.name: pkg = locked break if not pkg: raise ValueError("Package {} not found".format(package)) if self.option("tree"): self.display_package_tree(self.io, pkg, locked_repo) return 0 rows = [ ["<info>name</>", " : <c1>{}</>".format(pkg.pretty_name)], [ "<info>version</>", " : <b>{}</b>".format(pkg.pretty_version) ], ["<info>description</>", " : {}".format(pkg.description)], ] table.add_rows(rows) table.render() if pkg.requires: self.line("") self.line("<info>dependencies</info>") for dependency in pkg.requires: self.line(" - <c1>{}</c1> <b>{}</b>".format( dependency.pretty_name, dependency.pretty_constraint)) return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = Terminal() width = terminal.width name_length = version_length = latest_length = 0 latest_packages = {} latest_statuses = {} installed_repo = InstalledRepository.load(self.env) # Computing widths for locked in locked_packages: if locked not in required_locked_packages and not show_all: continue current_length = len(locked.pretty_name) if not self._io.output.is_decorated(): installed_status = self.get_installed_status( locked, installed_repo) if installed_status == "not-installed": current_length += 4 if show_latest: latest = self.find_latest_package(locked, root) if not latest: latest = locked latest_packages[locked.pretty_name] = latest update_status = latest_statuses[ locked.pretty_name] = self.get_update_status( latest, locked) if not self.option( "outdated") or update_status != "up-to-date": name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) latest_length = max( latest_length, len( get_package_version_display_string( latest, root=self.poetry.file.parent)), ) else: name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) write_version = name_length + version_length + 3 <= width write_latest = name_length + version_length + latest_length + 3 <= width write_description = name_length + version_length + latest_length + 24 <= width for locked in locked_packages: color = "cyan" name = locked.pretty_name install_marker = "" if locked not in required_locked_packages: if not show_all: continue color = "black;options=bold" else: installed_status = self.get_installed_status( locked, installed_repo) if installed_status == "not-installed": color = "red" if not self._io.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" if (show_latest and self.option("outdated") and latest_statuses[locked.pretty_name] == "up-to-date"): continue line = "<fg={}>{:{}}{}</>".format( color, name, name_length - len(install_marker), install_marker) if write_version: line += " <b>{:{}}</b>".format( get_package_version_display_string( locked, root=self.poetry.file.parent), version_length, ) if show_latest: latest = latest_packages[locked.pretty_name] update_status = latest_statuses[locked.pretty_name] if write_latest: color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" line += " <fg={}>{:{}}</>".format( color, get_package_version_display_string( latest, root=self.poetry.file.parent), latest_length, ) if write_description: description = locked.description remaining = width - name_length - version_length - 4 if show_latest: remaining -= latest_length if len(locked.description) > remaining: description = description[:remaining - 3] + "..." line += " " + description self.line(line)
def resize(sig, data): # type: (Any, Any) -> None terminal = Terminal() c.setwinsize(terminal.height, terminal.width)
def handle(self) -> int: from cleo.io.null_io import NullIO from cleo.terminal import Terminal from poetry.puzzle.solver import Solver from poetry.repositories.installed_repository import InstalledRepository from poetry.repositories.pool import Pool from poetry.utils.helpers import get_package_version_display_string package = self.argument("package") if self.option("tree"): self.init_styles(self.io) if self.option("why"): if self.option("tree") and package is None: self.line_error( "<error>Error: --why requires a package when combined with" " --tree.</error>") return 1 if not self.option("tree") and package: self.line_error( "<error>Error: --why cannot be used without --tree when displaying" " a single package.</error>") return 1 if self.option("outdated"): self.io.input.set_option("latest", True) if not self.poetry.locker.is_locked(): self.line_error( "<error>Error: poetry.lock not found. Run `poetry lock` to create" " it.</error>") return 1 locked_repo = self.poetry.locker.locked_repository() root = self.project_with_activated_groups_only() # Show tree view if requested if self.option("tree") and package is None: requires = root.all_requires packages = locked_repo.packages for p in packages: for require in requires: if p.name == require.name: self.display_package_tree(self.io, p, packages) break return 0 table = self.table(style="compact") locked_packages = locked_repo.packages pool = Pool(ignore_repository_names=True) pool.add_repository(locked_repo) solver = Solver( root, pool=pool, installed=[], locked=locked_packages, io=NullIO(), ) solver.provider.load_deferred(False) with solver.use_environment(self.env): ops = solver.solve().calculate_operations() required_locked_packages = {op.package for op in ops if not op.skipped} if package: pkg = None for locked in locked_packages: if canonicalize_name(package) == locked.name: pkg = locked break if not pkg: raise ValueError(f"Package {package} not found") required_by = reverse_deps(pkg, locked_repo) if self.option("tree"): if self.option("why"): # The default case if there's no reverse dependencies is to query # the subtree for pkg but if any rev-deps exist we'll query for each # of them in turn packages = [pkg] if required_by: packages = [ p for p in locked_packages for r in required_by.keys() if p.name == r ] else: # if no rev-deps exist we'll make this clear as it can otherwise # look very odd for packages that also have no or few direct # dependencies self.io.write_line( f"Package {package} is a direct dependency.") for p in packages: self.display_package_tree(self.io, p, locked_packages, why_package=pkg) else: self.display_package_tree(self.io, pkg, locked_packages) return 0 rows = [ ["<info>name</>", f" : <c1>{pkg.pretty_name}</>"], ["<info>version</>", f" : <b>{pkg.pretty_version}</b>"], ["<info>description</>", f" : {pkg.description}"], ] table.add_rows(rows) table.render() if pkg.requires: self.line("") self.line("<info>dependencies</info>") for dependency in pkg.requires: self.line(f" - <c1>{dependency.pretty_name}</c1>" f" <b>{dependency.pretty_constraint}</b>") if required_by: self.line("") self.line("<info>required by</info>") for parent, requires_version in required_by.items(): self.line( f" - <c1>{parent}</c1> <b>{requires_version}</b>") return 0 show_latest = self.option("latest") show_all = self.option("all") terminal = Terminal() width = terminal.width name_length = version_length = latest_length = required_by_length = 0 latest_packages = {} latest_statuses = {} installed_repo = InstalledRepository.load(self.env) # Computing widths for locked in locked_packages: if locked not in required_locked_packages and not show_all: continue current_length = len(locked.pretty_name) if not self.io.output.is_decorated(): installed_status = self.get_installed_status( locked, installed_repo.packages) if installed_status == "not-installed": current_length += 4 if show_latest: latest = self.find_latest_package(locked, root) if not latest: latest = locked latest_packages[locked.pretty_name] = latest update_status = latest_statuses[ locked.pretty_name] = self.get_update_status( latest, locked) if not self.option( "outdated") or update_status != "up-to-date": name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) latest_length = max( latest_length, len( get_package_version_display_string( latest, root=self.poetry.file.parent)), ) if self.option("why"): required_by = reverse_deps(locked, locked_repo) required_by_length = max( required_by_length, len(" from " + ",".join(required_by.keys())), ) else: name_length = max(name_length, current_length) version_length = max( version_length, len( get_package_version_display_string( locked, root=self.poetry.file.parent)), ) if self.option("why"): required_by = reverse_deps(locked, locked_repo) required_by_length = max( required_by_length, len(" from " + ",".join(required_by.keys()))) write_version = name_length + version_length + 3 <= width write_latest = name_length + version_length + latest_length + 3 <= width why_end_column = (name_length + version_length + latest_length + required_by_length) write_why = self.option("why") and (why_end_column + 3) <= width write_description = (why_end_column + 24) <= width for locked in locked_packages: color = "cyan" name = locked.pretty_name install_marker = "" if locked not in required_locked_packages: if not show_all: continue color = "black;options=bold" else: installed_status = self.get_installed_status( locked, installed_repo.packages) if installed_status == "not-installed": color = "red" if not self.io.output.is_decorated(): # Non installed in non decorated mode install_marker = " (!)" if (show_latest and self.option("outdated") and latest_statuses[locked.pretty_name] == "up-to-date"): continue line = ( f"<fg={color}>" f"{name:{name_length - len(install_marker)}}{install_marker}</>" ) if write_version: version = get_package_version_display_string( locked, root=self.poetry.file.parent) line += f" <b>{version:{version_length}}</b>" if show_latest: latest = latest_packages[locked.pretty_name] update_status = latest_statuses[locked.pretty_name] if write_latest: color = "green" if update_status == "semver-safe-update": color = "red" elif update_status == "update-possible": color = "yellow" version = get_package_version_display_string( latest, root=self.poetry.file.parent) line += f" <fg={color}>{version:{latest_length}}</>" if write_why: required_by = reverse_deps(locked, locked_repo) if required_by: content = ",".join(required_by.keys()) # subtract 6 for ' from ' line += f" from {content:{required_by_length - 6}}" else: line += " " * required_by_length if write_description: description = locked.description remaining = (width - name_length - version_length - required_by_length - 4) if show_latest: remaining -= latest_length if len(locked.description) > remaining: description = description[:remaining - 3] + "..." line += " " + description self.line(line) return 0