diff --git a/src/viv/viv.py b/src/viv/viv.py index 97ea0d7..9d768fa 100755 --- a/src/viv/viv.py +++ b/src/viv/viv.py @@ -50,7 +50,7 @@ from typing import ( from urllib.error import HTTPError from urllib.request import urlopen -__version__ = "23.5a5-11-g92da092-dev" +__version__ = "23.5a5-12-g1848a7e-dev" class Spinner: @@ -245,14 +245,6 @@ a = Ansi() class Template: - description = f""" - -{a.tagline()} -to create/activate a vivenv: -- from command line: `{a.style("viv -h","bold")}` -- within python script: {a.style('__import__("viv").use("typer", "rich-click")','bold')} -""" - _standalone_func = r"""def _viv_use(*pkgs, track_exe=False, name=""): import hashlib, json, os, site, shutil, sys, venv # noqa from pathlib import Path # noqa @@ -292,20 +284,33 @@ to create/activate a vivenv: return env """ - def noqa(self, txt: str) -> str: + @staticmethod + def description(name: str) -> str: + return f""" + +{a.tagline()} +to create/activate a vivenv: +- from command line: `{a.bold}{name} --help{a.end}` +- within python script: {a.style('__import__("viv").use("typer", "rich-click")','bold')} +""" + + @staticmethod + def noqa(txt: str) -> str: max_length = max(map(len, txt.splitlines())) return "\n".join((f"{line:{max_length}} # noqa" for line in txt.splitlines())) - def _use_str(self, spec: List[str], standalone: bool = False) -> str: + @staticmethod + def _use_str(spec: List[str], standalone: bool = False) -> str: spec_str = ", ".join(f'"{req}"' for req in spec) if standalone: return f"""_viv_use({fill(spec_str,width=90,subsequent_indent=" ",)})""" else: return f"""__import__("viv").use({spec_str})""" - def standalone(self, spec: List[str]) -> str: + @classmethod + def standalone(cls, spec: List[str]) -> str: func_use = "\n".join( - (self._standalone_func, self.noqa(self._use_str(spec, standalone=True))) + (cls._standalone_func, cls.noqa(cls._use_str(spec, standalone=True))) ) return f""" # AUTOGENERATED by viv (v{__version__}) @@ -313,7 +318,8 @@ to create/activate a vivenv: {func_use} """ - def _rel_import(self, local_source: Optional[Path]) -> str: + @staticmethod + def _rel_import(local_source: Optional[Path]) -> str: if not local_source: raise ValueError("local source must exist") @@ -325,29 +331,32 @@ to create/activate a vivenv: f""".path.expanduser("{path_to_viv}")) # noqa""" ) - def _absolute_import(self, local_source: Optional[Path]) -> str: + @staticmethod + def _absolute_import(local_source: Optional[Path]) -> str: if not local_source: raise ValueError("local source must exist") path_to_viv = local_source.resolve().absolute().parent.parent return f"""__import__("sys").path.append("{path_to_viv}") # noqa""" + @classmethod def frozen_import( - self, path: str, local_source: Optional[Path], spec: List[str] + cls, path: str, local_source: Optional[Path], spec: List[str] ) -> str: if path == "abs": - imports = self._absolute_import(local_source) + imports = cls._absolute_import(local_source) elif path == "rel": - imports = self._rel_import(local_source) + imports = cls._rel_import(local_source) else: imports = "" return f"""\ {imports} -{self.noqa(self._use_str(spec))} +{cls.noqa(cls._use_str(spec))} """ + @classmethod def shim( - self, + cls, path: str, local_source: Optional[Path], standalone: bool, @@ -355,11 +364,11 @@ to create/activate a vivenv: bin: str, ) -> str: if standalone: - imports = self._standalone_func + imports = cls._standalone_func elif path == "abs": - imports = self._absolute_import(local_source) + imports = cls._absolute_import(local_source) elif path == "rel": - imports = self._rel_import(local_source) + imports = cls._rel_import(local_source) else: imports = "" return f"""\ @@ -372,12 +381,13 @@ import subprocess import sys if __name__ == "__main__": - vivenv = {self.noqa(self._use_str(spec, standalone))} + vivenv = {cls.noqa(cls._use_str(spec, standalone))} sys.exit(subprocess.run([vivenv / "bin" / "{bin}", *sys.argv[1:]]).returncode) """ + @staticmethod def update( - self, src: Optional[Path], cli: Path, local_version: str, next_version: str + src: Optional[Path], cli: Path, local_version: str, next_version: str ) -> str: return f""" Update source at {a.green}{src}{a.end} @@ -386,15 +396,17 @@ if __name__ == "__main__": """ - def install(self, src: Path, cli: Path) -> str: + @staticmethod + def install(src: Path, cli: Path) -> str: return f""" Install viv.py to {a.green}{src}{a.end} Symlink {a.bold}{src}{a.end} to {a.bold}{cli}{a.end} """ + @staticmethod def show( - self, cli: Optional[Path | str], running: Path, local: Optional[Path | str] + cli: Optional[Path | str], running: Path, local: Optional[Path | str] ) -> str: return ( "\n".join( @@ -1524,7 +1536,7 @@ class Cli: def __init__(self, viv: Viv) -> None: self.viv = viv - self.parser = ArgumentParser(prog=viv.name, description=t.description) + self.parser = ArgumentParser(prog=viv.name, description=t.description(viv.name)) self._cmd_arg_group_map() self.parsers = self._make_parsers() self._add_args()