-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add minimal Python API and task runner (#5903)
- Loading branch information
1 parent
5c3dafc
commit ea4d848
Showing
3 changed files
with
64 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
def uv(args: "str") -> int: | ||
"""Execute `uv` with the given arguments.""" | ||
import shlex | ||
import subprocess | ||
|
||
from ._find_uv import find_uv_bin | ||
|
||
return subprocess.run([find_uv_bin()] + shlex.split(args)).returncode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
tasks = {} | ||
|
||
|
||
def task(needs: "str | None" = None): | ||
"""Define a task and optionally add task dependencies to the uv-managed project.""" | ||
|
||
if callable(needs): | ||
return task()(needs) | ||
|
||
def decorator(func): | ||
import functools | ||
|
||
@functools.wraps(func) | ||
def wrapper(*args, **kwargs): | ||
if needs: | ||
from ._api import uv | ||
|
||
uv(f"add {needs}") | ||
return func(*args, **kwargs) | ||
|
||
tasks[wrapper.__name__] = wrapper | ||
return wrapper | ||
|
||
return decorator | ||
|
||
|
||
def run_tasks() -> None: | ||
"""Run tasks from an autogenerated CLI.""" | ||
import argparse | ||
import inspect | ||
|
||
parser = argparse.ArgumentParser() | ||
subparsers = parser.add_subparsers(dest="task") | ||
|
||
for name, func in tasks.items(): | ||
docstring = func.__doc__ | ||
subparser = subparsers.add_parser(name, help=docstring, description=docstring) | ||
for param in inspect.signature(func).parameters.values(): | ||
if param.default == param.empty: | ||
subparser.add_argument(param.name, type=param.annotation) | ||
else: | ||
subparser.add_argument( | ||
f"--{param.name}", type=param.annotation, default=param.default | ||
) | ||
|
||
if (args := parser.parse_args()).task: | ||
func = tasks[args.task] | ||
kwargs = {k: v for k, v in vars(args).items() if k != "task"} | ||
func(**kwargs) | ||
else: | ||
parser.print_help() |