feat: add support for dependency block

This commit is contained in:
Daylin Morgan 2023-08-03 18:05:49 -05:00
parent ec123b0d7a
commit e613d97200
Signed by: daylin
GPG key ID: C1E52E7DD81DF79F
2 changed files with 54 additions and 2 deletions

13
examples/pep722.py Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env -S viv run -s
# In order to run, this script needs the following 3rd party libraries
#
## Script Dependencies:
## requests
## rich
import requests
from rich.pretty import pprint
resp = requests.get("https://peps.python.org/api/peps.json")
data = resp.json()
pprint([(k, v["title"]) for k, v in data.items()][:10])

View file

@ -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.5a6-5-g7932e13-dev" __version__ = "23.5a6-6-gec123b0-dev"
class Spinner: class Spinner:
@ -1039,6 +1039,37 @@ def uses_viv(txt: str) -> bool:
) )
def _read_metadata_block(txt: str) -> None:
"""check for pep722 style metadata block and parse"""
lines = iter(txt.splitlines())
for line in lines:
if line.startswith("##"):
block_type, sep, extra = line[2:].strip().partition(":")
if not sep:
continue
block_data = []
for line in lines:
if not line.startswith("##"):
break
line = line[2:].strip()
if not line:
continue
block_data.append(line)
yield block_type, extra, block_data
def deps_block(txt: str):
return list(
(
req
for block_type, extra, block_data in _read_metadata_block(txt)
for req in block_data
if block_type == "Script Dependencies"
)
)
class Viv: class Viv:
def __init__(self) -> None: def __init__(self) -> None:
self.t = Template() self.t = Template()
@ -1396,6 +1427,14 @@ class Viv:
script_text = fetch_script(script) script_text = fetch_script(script)
viv_used = uses_viv(script_text) viv_used = uses_viv(script_text)
deps = deps_block(script_text)
if viv_used and deps_block:
error(
"Script Dependencies block and "
"`viv` API can't be used in the same script"
)
scriptpath.write_text(script_text) scriptpath.write_text(script_text)
if not keep: if not keep:
@ -1411,7 +1450,7 @@ class Viv:
).returncode ).returncode
) )
else: else:
vivenv = ViVenv(spec) vivenv = ViVenv(spec + deps)
if not vivenv.loaded or Env().viv_force: if not vivenv.loaded or Env().viv_force:
vivenv.create() vivenv.create()
vivenv.install_pkgs() vivenv.install_pkgs()