mirror of
https://github.com/daylinmorgan/viv.git
synced 2024-09-20 12:07:18 -05:00
Compare commits
No commits in common. "d3f4bf9db908042f7b29eaa4cb3d3047d56c1fe2" and "0e40aeb15d77dfc5c7a99d10edfa3222bf9f41eb" have entirely different histories.
d3f4bf9db9
...
0e40aeb15d
1 changed files with 25 additions and 90 deletions
115
src/viv/viv.py
115
src/viv/viv.py
|
@ -52,7 +52,7 @@ from typing import (
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
|
|
||||||
__version__ = "23.5a2-5-g4e6acac-dev"
|
__version__ = "23.5a2-2-gebb657c-dev"
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -226,8 +226,7 @@ class Ansi:
|
||||||
Args:
|
Args:
|
||||||
output: text output from subprocess, usually from p.stdout
|
output: text output from subprocess, usually from p.stdout
|
||||||
"""
|
"""
|
||||||
if not output:
|
|
||||||
return
|
|
||||||
echo("subprocess output:")
|
echo("subprocess output:")
|
||||||
new_output = [f"{self.red}->{self.end} {line}" for line in output.splitlines()]
|
new_output = [f"{self.red}->{self.end} {line}" for line in output.splitlines()]
|
||||||
sys.stdout.write("\n".join(new_output) + "\n")
|
sys.stdout.write("\n".join(new_output) + "\n")
|
||||||
|
@ -560,7 +559,7 @@ class ViVenv:
|
||||||
name: str = "",
|
name: str = "",
|
||||||
path: Path | None = None,
|
path: Path | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.spec = self._validate_spec(spec)
|
self.spec = spec
|
||||||
self.exe = str(Path(sys.executable).resolve()) if track_exe else "N/A"
|
self.exe = str(Path(sys.executable).resolve()) if track_exe else "N/A"
|
||||||
self.id = id if id else get_hash(spec, track_exe)
|
self.id = id if id else get_hash(spec, track_exe)
|
||||||
self.name = name if name else self.id
|
self.name = name if name else self.id
|
||||||
|
@ -584,18 +583,6 @@ class ViVenv:
|
||||||
|
|
||||||
return vivenv
|
return vivenv
|
||||||
|
|
||||||
def _validate_spec(self, spec: Tuple[str, ...]) -> List[str]:
|
|
||||||
"""ensure spec is at least of sequence of strings
|
|
||||||
|
|
||||||
Args:
|
|
||||||
spec: sequence of package specifications
|
|
||||||
"""
|
|
||||||
if not set(map(type, spec)) == {str}:
|
|
||||||
error("unexepected input in package spec")
|
|
||||||
error(f"check your packages definitions: {spec}", code=1)
|
|
||||||
else:
|
|
||||||
return sorted(spec)
|
|
||||||
|
|
||||||
def create(self, quiet: bool = False) -> None:
|
def create(self, quiet: bool = False) -> None:
|
||||||
if not quiet:
|
if not quiet:
|
||||||
echo(f"new unique vivenv -> {self.name}")
|
echo(f"new unique vivenv -> {self.name}")
|
||||||
|
@ -649,6 +636,7 @@ def use(*packages: str, track_exe: bool = False, name: str = "") -> Path:
|
||||||
track_exe: if true make env python exe specific
|
track_exe: if true make env python exe specific
|
||||||
name: use as vivenv name, if not provided id is used
|
name: use as vivenv name, if not provided id is used
|
||||||
"""
|
"""
|
||||||
|
validate_spec(packages)
|
||||||
vivenv = ViVenv(list(packages), track_exe=track_exe, name=name)
|
vivenv = ViVenv(list(packages), track_exe=track_exe, name=name)
|
||||||
|
|
||||||
if vivenv.name not in [d.name for d in c.venvcache.iterdir()] or os.getenv(
|
if vivenv.name not in [d.name for d in c.venvcache.iterdir()] or os.getenv(
|
||||||
|
@ -662,6 +650,18 @@ def use(*packages: str, track_exe: bool = False, name: str = "") -> Path:
|
||||||
return vivenv.path
|
return vivenv.path
|
||||||
|
|
||||||
|
|
||||||
|
def validate_spec(spec: Tuple[str, ...]) -> None:
|
||||||
|
"""ensure spec is at least of sequence of strings
|
||||||
|
|
||||||
|
Args:
|
||||||
|
spec: sequence of package specifications
|
||||||
|
"""
|
||||||
|
# ? make this a part of ViVenv?
|
||||||
|
if not set(map(type, spec)) == {str}:
|
||||||
|
error("unexepected input in package spec")
|
||||||
|
error(f"check your packages definitions: {spec}", code=1)
|
||||||
|
|
||||||
|
|
||||||
def modify_sys_path(new_path: Path) -> None:
|
def modify_sys_path(new_path: Path) -> None:
|
||||||
# remove user-site
|
# remove user-site
|
||||||
for i, path in enumerate(sys.path):
|
for i, path in enumerate(sys.path):
|
||||||
|
@ -1025,7 +1025,7 @@ class Viv:
|
||||||
f"{pip_path} {' '.join(args.cmd)}"
|
f"{pip_path} {' '.join(args.cmd)}"
|
||||||
if args.exe == "pip"
|
if args.exe == "pip"
|
||||||
else f"{python_path} {' '.join(args.cmd)}"
|
else f"{python_path} {' '.join(args.cmd)}"
|
||||||
) + " ".join(args.rest)
|
)
|
||||||
|
|
||||||
echo(f"executing {cmd}")
|
echo(f"executing {cmd}")
|
||||||
run(shlex.split(cmd), verbose=True)
|
run(shlex.split(cmd), verbose=True)
|
||||||
|
@ -1240,42 +1240,6 @@ class Viv:
|
||||||
|
|
||||||
make_executable(output)
|
make_executable(output)
|
||||||
|
|
||||||
def run(self, args: Namespace) -> None:
|
|
||||||
"""\
|
|
||||||
run an app w/ an on-demand venv
|
|
||||||
|
|
||||||
examples:
|
|
||||||
viv r pycowsay -- "Viv isn't venv\!"
|
|
||||||
viv r rich -b python -- -m rich
|
|
||||||
"""
|
|
||||||
if not args.reqs:
|
|
||||||
error("please specify at lease one dependency", code=1)
|
|
||||||
|
|
||||||
default_bin = re.split(r"[=><~!*]+", args.reqs[0])[0]
|
|
||||||
bin = default_bin if not args.bin else args.bin
|
|
||||||
spec = combined_spec(args.reqs, args.requirements)
|
|
||||||
vivenv = ViVenv(spec)
|
|
||||||
|
|
||||||
if vivenv.name not in [d.name for d in c.venvcache.iterdir()] or os.getenv(
|
|
||||||
"VIV_FORCE"
|
|
||||||
):
|
|
||||||
if not args.keep:
|
|
||||||
with tempfile.TemporaryDirectory(prefix="viv-") as tmpdir:
|
|
||||||
vivenv.path = Path(tmpdir)
|
|
||||||
vivenv.create()
|
|
||||||
vivenv.install_pkgs()
|
|
||||||
sys.exit(
|
|
||||||
subprocess.run(
|
|
||||||
[vivenv.path / "bin" / bin, *args.rest]
|
|
||||||
).returncode
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
vivenv.create()
|
|
||||||
vivenv.install_pkgs()
|
|
||||||
vivenv.dump_info(write=True)
|
|
||||||
|
|
||||||
sys.exit(subprocess.run([vivenv.path / "bin" / bin, *args.rest]).returncode)
|
|
||||||
|
|
||||||
def _get_subcmd_parser(
|
def _get_subcmd_parser(
|
||||||
self,
|
self,
|
||||||
subparsers: _SubParsersAction[ArgumentParser],
|
subparsers: _SubParsersAction[ArgumentParser],
|
||||||
|
@ -1445,10 +1409,11 @@ class Viv:
|
||||||
"purge", help="remove traces of viv", aliases="p", parents=[p_manage_shared]
|
"purge", help="remove traces of viv", aliases="p", parents=[p_manage_shared]
|
||||||
).set_defaults(func=self.manage, cmd="purge")
|
).set_defaults(func=self.manage, cmd="purge")
|
||||||
|
|
||||||
p_shim = self._get_subcmd_parser(
|
(
|
||||||
subparsers, "shim", parents=[p_freeze_shim_shared]
|
p_shim := self._get_subcmd_parser(
|
||||||
)
|
subparsers, "shim", parents=[p_freeze_shim_shared]
|
||||||
|
)
|
||||||
|
).set_defaults(func=self.shim, cmd="shim")
|
||||||
p_shim.add_argument(
|
p_shim.add_argument(
|
||||||
"-f",
|
"-f",
|
||||||
"--freeze",
|
"--freeze",
|
||||||
|
@ -1462,41 +1427,11 @@ class Viv:
|
||||||
type=Path,
|
type=Path,
|
||||||
metavar="<path>",
|
metavar="<path>",
|
||||||
)
|
)
|
||||||
p_shim.add_argument(
|
p_shim.add_argument("-b", "--bin", help="console_script/script to invoke")
|
||||||
"-b", "--bin", help="console_script/script to invoke", metavar="<bin>"
|
|
||||||
)
|
|
||||||
|
|
||||||
p_run = self._get_subcmd_parser(subparsers, "run")
|
args = parser.parse_args()
|
||||||
|
|
||||||
p_run.add_argument(
|
args.func(args)
|
||||||
"-r",
|
|
||||||
"--requirements",
|
|
||||||
help="path/to/requirements.txt file",
|
|
||||||
metavar="<path>",
|
|
||||||
)
|
|
||||||
p_run.add_argument(
|
|
||||||
"-k",
|
|
||||||
"--keep",
|
|
||||||
help="preserve environment",
|
|
||||||
action="store_true",
|
|
||||||
)
|
|
||||||
p_run.add_argument("reqs", help="requirements specifiers", nargs="*")
|
|
||||||
|
|
||||||
p_run.add_argument(
|
|
||||||
"-b", "--bin", help="console_script/script to invoke", metavar="<bin>"
|
|
||||||
)
|
|
||||||
|
|
||||||
if "--" in sys.argv:
|
|
||||||
i = sys.argv.index("--")
|
|
||||||
args = parser.parse_args(sys.argv[1:i])
|
|
||||||
args.rest = sys.argv[i + 1 :]
|
|
||||||
else:
|
|
||||||
args = parser.parse_args()
|
|
||||||
args.rest = []
|
|
||||||
|
|
||||||
args.func(
|
|
||||||
args,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
|
Loading…
Reference in a new issue