Compare commits

...

7 commits

Author SHA1 Message Date
ed109d65a4
debug 2023-05-25 19:24:14 -05:00
f87aab9ddd
learn to spell 2023-05-25 19:22:49 -05:00
417c8dd4d0
update 2023-05-25 19:22:07 -05:00
b97b4f7894
update 2023-05-25 19:20:26 -05:00
9e622879d0
dev 2023-05-25 19:16:52 -05:00
3b9c2e64ca
WIP 2023-05-25 17:45:14 -05:00
f1b2b14316
wip: start self 2023-05-25 17:45:14 -05:00

View file

@ -21,6 +21,8 @@ import sys
import tempfile import tempfile
import threading import threading
import time import time
from urllib.request import urlopen
from urllib.error import HTTPError
import venv import venv
from argparse import SUPPRESS, Action from argparse import SUPPRESS, Action
from argparse import ArgumentParser as StdArgParser from argparse import ArgumentParser as StdArgParser
@ -49,7 +51,7 @@ from typing import (
Generator, Generator,
) )
__version__ = "22.12a3-41-g5c40210-dev" __version__ = "22.12a3-48-gf87aab9-dev"
@dataclass @dataclass
@ -305,6 +307,16 @@ def echo(
fd.write(output) fd.write(output)
def confirm(question: str) -> bool:
while True:
ans = input(question + a.style(" (Y)es/(n)o: ", "yellow")).strip().lower()
if ans in ("y", "yes"):
return True
elif ans in ("n", "no"):
return False
sys.stdout.write("\nPlease select (Y)es or (n)o.")
def run( def run(
command: List[str], command: List[str],
spinmsg: str = "", spinmsg: str = "",
@ -448,7 +460,7 @@ class ViVenv:
a.table((("key", "value"), *((k, v) for k, v in info.items()))) a.table((("key", "value"), *((k, v) for k, v in info.items())))
def use(*packages: str, track_exe: bool = False, name: str = "") -> None: def use(*packages: str, track_exe: bool = False, name: str = "") -> ViVenv:
"""create a vivenv and append to sys.path """create a vivenv and append to sys.path
Args: Args:
@ -467,6 +479,7 @@ def use(*packages: str, track_exe: bool = False, name: str = "") -> None:
vivenv.dump_info(write=True) vivenv.dump_info(write=True)
modify_sys_path(vivenv.path) modify_sys_path(vivenv.path)
return vivenv
def validate_spec(spec: Tuple[str, ...]) -> None: def validate_spec(spec: Tuple[str, ...]) -> None:
@ -539,6 +552,12 @@ _viv_use({spec})
1: 1:
] ]
SHOW_TEMPLATE = f"""\
{a.style('Version', 'bold')}: {{version}}
{a.style('CLI', 'bold')}: {{cli}}
{a.style('Source File', 'bold')}: {{src}}
"""
def noqa(txt: str) -> str: def noqa(txt: str) -> str:
max_length = max(map(len, txt.splitlines())) max_length = max(map(len, txt.splitlines()))
@ -895,11 +914,83 @@ class Viv:
vivenv.dump_info() vivenv.dump_info()
def manage(self, args: Namespace) -> None:
"""manage viv installation"""
if args.cmd == "show":
# NOTE: could reuse the table output for this?
echo("Installation Info:")
sys.stdout.write(
SHOW_TEMPLATE.format(
version=__version__,
cli=shutil.which("viv"),
src=Path(__file__).resolve(),
)
)
elif args.cmd == "update":
echo(__file__)
echo(Path(__file__))
if str(Path(__file__).resolve()).startswith("/proc/"):
error(
a.style("viv manage update", "bold")
+ "should be used with a locally installed viv",
1,
)
try:
r = urlopen(
"https://raw.githubusercontent.com/daylinmorgan/viv/"
+ args.reference
+ "/src/viv/viv.py"
)
except HTTPError as e:
error(
"Issue updating viv see below:"
+ a.style("-> ", "red").join(["\n"] + repr(e).splitlines())
)
if "404" in repr(e):
echo("Please check your reference is valid.", style="red")
sys.exit(1)
viv_src = r.read()
(hash := hashlib.sha256()).update(viv_src)
sha256 = hash.hexdigest()
(
src_cache := Path(os.getenv("XDG_CACHE_HOME", Path.home() / ".cache"))
/ "viv"
/ "src"
).mkdir(exist_ok=True, parents=True)
cached_version = src_cache / f"{sha256}.py"
if not cached_version.is_file():
with cached_version.open("w") as f:
f.write(viv_src.decode())
sys.path.append(str(src_cache))
next_version = __import__(sha256).__version__
q = (
"Update source at: "
+ a.style(Path(__file__).resolve(), "bold")
+ f" \n from version {__version__} to {next_version}?"
)
if confirm(q):
print("AWAY THEN")
elif args.cmd == "install":
echo("not yet implemented. sorry")
def _get_subcmd_parser( def _get_subcmd_parser(
self, subparsers: _SubParsersAction[ArgumentParser], name: str, **kwargs: Any self,
subparsers: _SubParsersAction[ArgumentParser],
name: str,
attr: Optional[str] = None,
**kwargs: Any,
) -> ArgumentParser: ) -> ArgumentParser:
aliases = kwargs.pop("aliases", [name[0]]) aliases = kwargs.pop("aliases", [name[0]])
cmd = getattr(self, name) cmd = getattr(self, attr if attr else name)
parser: ArgumentParser = subparsers.add_parser( parser: ArgumentParser = subparsers.add_parser(
name, name,
help=cmd.__doc__.splitlines()[0], help=cmd.__doc__.splitlines()[0],
@ -955,16 +1046,15 @@ class Viv:
nargs="*", nargs="*",
) )
p_exe_python = p_exe_sub.add_parser( p_exe_sub.add_parser(
"python", "python",
help="run command with python", help="run command with python",
parents=[p_vivenv_arg, p_exe_shared], parents=[p_vivenv_arg, p_exe_shared],
) ).set_defaults(func=self.exe, exe="python")
p_exe_pip = p_exe_sub.add_parser(
p_exe_sub.add_parser(
"pip", help="run command with pip", parents=[p_vivenv_arg, p_exe_shared] "pip", help="run command with pip", parents=[p_vivenv_arg, p_exe_shared]
) ).set_defaults(func=self.exe, exe="pip")
p_exe_python.set_defaults(func=self.exe, exe="python")
p_exe_pip.set_defaults(func=self.exe, exe="pip")
p_remove = self._get_subcmd_parser( p_remove = self._get_subcmd_parser(
subparsers, subparsers,
@ -1009,6 +1099,33 @@ class Viv:
parents=[p_vivenv_arg], parents=[p_vivenv_arg],
) )
p_manage_sub = self._get_subcmd_parser(
subparsers, name="manage"
).add_subparsers(title="subcommand", metavar="<sub-cmd>", required=True)
p_manage_sub.add_parser(
"install",
help="install viv",
).set_defaults(func=self.manage, cmd="install")
(
p_manage_update := p_manage_sub.add_parser(
"update",
help="update viv version",
)
).set_defaults(func=self.manage, cmd="update")
p_manage_update.add_argument(
"-r",
"--reference",
help="git reference (branch/tag/commit)",
default="main",
)
p_manage_sub.add_parser(
"show", help="show current installation info"
).set_defaults(func=self.manage, cmd="show")
args = parser.parse_args() args = parser.parse_args()
args.func(args) args.func(args)