Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions docs/ctx.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Import the module like so:

```py
import boldi.ctx

# or:
from boldi.ctx import Ctx
```
Expand Down Expand Up @@ -50,18 +51,15 @@ import subprocess

from boldi.ctx import Ctx


def printing_example(ctx):
print(..., file=ctx.stderr)


def subprocess_example(ctx, args):
# these two are equivalent:
subprocess.run(
args,
check=True,
text=True,
stdin=ctx.stdin, stdout=ctx.stdout, stderr=ctx.stderr,
cwd=ctx.cwd,
env=ctx.env
args, check=True, text=True, stdin=ctx.stdin, stdout=ctx.stdout, stderr=ctx.stderr, cwd=ctx.cwd, env=ctx.env
)
ctx.run(args)
```
Expand All @@ -73,6 +71,7 @@ or when no explicit `ctx` parameter has been provided to a function.
```py
from boldi.ctx import Ctx


# for convenience, allows omitting the ctx parameter
def example(ctx: Ctx | None = None):
ctx = ctx or Ctx()
Expand Down
1 change: 1 addition & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Import the module like so:

```py
import boldi.plugins

# or:
from boldi.plugins import load
```
Expand Down
1 change: 1 addition & 0 deletions docs/proc.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Import the module like so:

```py
import boldi.proc

# or:
from boldi.proc import run, run_py
```
Expand Down
15 changes: 7 additions & 8 deletions pkg/boldi-build/boldi/build.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import contextlib
import json
import logging
Expand Down Expand Up @@ -29,8 +30,7 @@ class BuildDB:

async def load(self, path: Path):
try:
with open(path, "r") as fp:
build_db_json = json.load(fp)
build_db_json = json.loads(await asyncio.to_thread(path.read_text))
except (json.JSONDecodeError, OSError):
build_db_json = {}
build_db_json = build_db_json if isinstance(build_db_json, dict) else {}
Expand All @@ -41,12 +41,11 @@ async def load(self, path: Path):
self.dependencies.update(build_db_json.get("dependencies", {}))

async def save(self, path: Path):
with open(path, "w") as fp:
build_db_json = {
"targets": self.targets,
"dependencies": dict(self.dependencies),
}
json.dump(build_db_json, fp, indent=2)
build_db_json = {
"targets": self.targets,
"dependencies": dict(self.dependencies),
}
await asyncio.to_thread(path.write_text, json.dumps(build_db_json, indent=2))


@dataclass
Expand Down
6 changes: 1 addition & 5 deletions pkg/boldi-cli/boldi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,10 @@
class _CliCtxDefaultConsole(Console):
"""Implementation detail used to set a default value for [boldi.cli.CliCtx.console][]."""

pass


class CliUsageException(Exception):
"""Raised when a CLI usage error is encountered."""

pass


@dataclass
class CliCtx(Ctx):
Expand Down Expand Up @@ -144,7 +140,7 @@ def error_handler(ctx: CliCtx):

exit(1)

except Exception as exc:
except Exception as exc: # noqa: BLE001 - CLI boundary reports unexpected failures consistently.
ctx.msg_FAIL(f"INTERNAL ERROR: {type(exc).__name__}:", *exc.args)
ctx.msg_fail("This is a bug, please report it.")
if ctx.verbose:
Expand Down
9 changes: 4 additions & 5 deletions pkg/boldi-ctx/boldi/ctx.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import os
import subprocess
import sys
from collections.abc import MutableMapping
from contextlib import AbstractContextManager, ExitStack, chdir
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, List, MutableMapping, TextIO, Union

from typing_extensions import Self, Unpack
from typing import Any, Self, TextIO, Unpack

from boldi.proc import RunArgs, run as _run, run_py as _run_py

Expand Down Expand Up @@ -73,7 +72,7 @@ def _set_run_kwargs(self, **kwargs: Unpack[RunArgs]):
kwargs.setdefault("stdout", self.stdout)
kwargs.setdefault("stderr", self.stderr)

def run(self, *args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
def run(self, *args: str | list[Any], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
"""
Run a subprocess using the provided command line arguments and updated defaults.

Expand All @@ -90,7 +89,7 @@ def run(self, *args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subpro
self._set_run_kwargs(**kwargs)
return _run(*args, **kwargs)

def run_py(self, *args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
def run_py(self, *args: str | list[Any], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
"""
Run a subprocess using the current Python interpreter, the provided command line arguments and updated defaults.

Expand Down
2 changes: 1 addition & 1 deletion pkg/boldi-githooks/boldi/githooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import shlex
import stat
import sys
from collections.abc import Iterable
from dataclasses import dataclass
from functools import cached_property, partial
from itertools import chain
from pathlib import Path
from subprocess import CompletedProcess
from typing import Iterable

from boldi.cli import CliCtx, CliUsageException, esc, main as cli_main

Expand Down
4 changes: 2 additions & 2 deletions pkg/boldi-plugins/boldi/plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import importlib.metadata
from collections.abc import Callable
from typing import Iterable, NamedTuple
from collections.abc import Callable, Iterable
from typing import NamedTuple


class Plugin(NamedTuple):
Expand Down
13 changes: 6 additions & 7 deletions pkg/boldi-proc/boldi/proc.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import shlex
import subprocess
import sys
from collections.abc import Callable, Iterable, Mapping
from pathlib import Path
from typing import IO, Any, Callable, Iterable, List, Mapping, TypedDict, Union

from typing_extensions import Unpack
from typing import IO, Any, TypedDict, Unpack


class RunArgs(TypedDict, total=False):
Expand Down Expand Up @@ -38,7 +37,7 @@ class RunArgs(TypedDict, total=False):
user: str | int


def args_iter(*args: Union[str, List[Any]]) -> Iterable[str]:
def args_iter(*args: str | list[Any]) -> Iterable[str]:
"""
Split mixed and/or quoted command line arguments into a simple list of arguments.

Expand Down Expand Up @@ -80,7 +79,7 @@ def args_iter(*args: Union[str, List[Any]]) -> Iterable[str]:
yield str(arg)


def run(*args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
def run(*args: str | list[Any], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
"""
Run a subprocess using the provided command line arguments and updated defaults.

Expand All @@ -101,10 +100,10 @@ def run(*args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subprocess.C
kwargs.setdefault("stdout", sys.stdout)
kwargs.setdefault("stderr", sys.stderr)
args_list = list(args_iter(*args))
return subprocess.run(args_list, **kwargs)
return subprocess.run(args_list, **kwargs) # noqa: PLW1510 - check defaults to true above.


def run_py(*args: Union[str, List[Any]], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
def run_py(*args: str | list[Any], **kwargs: Unpack[RunArgs]) -> subprocess.CompletedProcess:
"""
Run a subprocess using the current Python interpreter, the provided command line arguments and updated defaults.

Expand Down
10 changes: 6 additions & 4 deletions pkg/boldi-sitebuilder/boldi/sitebuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import tomllib
from argparse import ArgumentParser
from collections.abc import Iterator, Mapping
from functools import cache, partial
from functools import partial
from pathlib import Path
from shutil import copytree
from types import MappingProxyType
Expand Down Expand Up @@ -34,6 +34,7 @@ def __init__(self, source_dir: Path, target_dir: Path, site_name: str):
self._md = self._md.use(anchors_plugin, permalink=True, permalinkSymbol="#")
self._md = self._md.use(front_matter_plugin)
self._jinja = Environment(loader=FileSystemLoader(source_dir / "template"))
self._source_pages_list: list[Path] | None = None

def build_all(self) -> None:
for source_file in self.source_pages_list():
Expand All @@ -49,9 +50,10 @@ def source_pages(self) -> Iterator[Path]:
if source_file.is_file() and source_file.suffix == ".md":
yield Path(source_file.name)

@cache
def source_pages_list(self) -> list[Path]:
return list(self.source_pages())
if self._source_pages_list is None:
self._source_pages_list = list(self.source_pages())
return self._source_pages_list

@property
def source_to_target(self) -> Mapping[Path, Path]:
Expand Down Expand Up @@ -79,7 +81,7 @@ def walk(tokens: list[Token]):
if token.type == "front_matter":
try:
_front_matter: dict[str, object] | Exception = tomllib.loads(token.content)
except Exception as ex:
except tomllib.TOMLDecodeError as ex:
_front_matter = ex
if token.type == "link_open" and (href := token.attrGet("href")):
assert isinstance(href, str)
Expand Down
Loading
Loading