Skip to content
This repository has been archived by the owner on Jun 18, 2024. It is now read-only.

Commit

Permalink
fix: can_skip, logging, and type cli.task
Browse files Browse the repository at this point in the history
  • Loading branch information
KyleKing committed Feb 18, 2023
1 parent 3c36ca7 commit 3c26256
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ multi_line_output = 5

[tool.poetry]
name = "shoal"
version = "0.3.0"
version = "0.4.1"
description = "Lazy, Python-first, alternative to make, just, doit, and invoke"
license = "MIT"
authors = ["Kyle King <dev.act.kyle@gmail.com>"]
Expand Down
6 changes: 4 additions & 2 deletions shoal/can_skip.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

from beartype import beartype
from beartype.typing import List
from ._log import get_logger

logger = get_logger()

@beartype
def can_skip(*, prerequisites: List[Path], targets: List[Path]) -> bool:
Expand All @@ -22,12 +24,12 @@ def test(ctx: Context) -> None:
```
"""
ts_prerequisites = [pth.getmtime() for pth in prerequisites]
ts_prerequisites = [pth.stat().st_mtime for pth in prerequisites]
if not ts_prerequisites:
raise ValueError('Required files do not exist', prerequisites)

# TODO: Triple check this logic (https://stackoverflow.com/a/22960700/3219667)
ts_targets = [pth.getmtime() for pth in targets]
ts_targets = [pth.stat().st_mtime for pth in targets]
if ts_targets and max(ts_prerequisites) >= min(ts_targets):
logger.info('Skipping because targets are newer', targets=targets)
return False
Expand Down
33 changes: 23 additions & 10 deletions shoal/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import sys
from pathlib import Path

from beartype.typing import Callable
from beartype.typing import Any, Callable
from beartype import beartype
from beartype.typing import List
from invoke import Collection, Config, Context, Program
from invoke import Task, Collection, Config, Context, Program
from functools import wraps
from contextlib import suppress
import logging
from ._log import configure_logger
from invoke import task as invoke_task
from pydantic import BaseModel
from ._log import get_logger

logger = get_logger()


class GlobalTaskOptions(BaseModel):
Expand Down Expand Up @@ -50,7 +53,7 @@ def start_program(pkg_name: str, pkg_version: str, module) -> None:
"""
# Manipulate 'sys.argv' to hide arguments that invoke can't parse
file_argv: List[Path] = []
verbose_argv: int = 0
verbose_argv: int = 1
sys_argv: List[str] = []
last_argv = ''
for argv in sys.argv:
Expand All @@ -75,18 +78,28 @@ class ShoalConfig(Config):
).run()


def task(*task_args, **task_kwargs) -> Callable:
def outer(func) -> Callable:
"""Wrap Invoke.task to configure logging."""
@beartype
def task(*task_args, **task_kwargs) -> Callable[[Any], Task]:
"""Wrapper to accept arguments for an invoke task."""
@beartype
def wrapper(func) -> Task:
"""Wraps the decorated task."""
@invoke_task(*task_args, **task_kwargs)
@beartype
@wraps(func)
def inner(ctx: Context, *args, **kwargs) -> None:
def inner(ctx: Context, *args, **kwargs) -> Task:
"""Configure logging, then run actual task."""
verbose = 2
with suppress(AttributeError):
verbose = ctx.config.gto.verbose
log_lookup = {3: logging.NOTSET, 2: logging.DEBUG, 1: logging.INFO, 0: logging.WARNING}
configure_logger(log_level=log_lookup.get(verbose) or logging.ERROR)
raw_log_level = log_lookup.get(verbose)
configure_logger(log_level=logging.ERROR if raw_log_level is None else raw_log_level)

print('') # noqa: T201
logger.info(f'Running {func.__name__}', summary=func.__doc__)
logger.debug('Task arguments', args=args, kwargs=kwargs)

func(ctx, *args, **kwargs)
return func(ctx, *args, **kwargs)
return inner
return outer
return wrapper

0 comments on commit 3c26256

Please sign in to comment.