Convert CliOptions to a dataclass

This commit is contained in:
Adam Turner 2025-01-07 09:05:03 +00:00
parent 8732b2324a
commit fd3e7d3902
2 changed files with 42 additions and 36 deletions

View File

@ -263,18 +263,19 @@ def main(argv: Sequence[str] = (), /) -> int:
sphinx.locale.init_console()
parser = get_parser()
args: CliOptions = parser.parse_args(argv or sys.argv[1:])
args = parser.parse_args(argv or sys.argv[1:])
rootpath = os.path.abspath(args.module_path)
args.module_path = rootpath = Path(args.module_path).resolve()
# normalize opts
if args.header is None:
args.header = rootpath.split(os.path.sep)[-1]
args.header = str(rootpath).split(os.path.sep)[-1]
args.suffix = args.suffix.removeprefix('.')
if not Path(rootpath).is_dir():
logger.error(__('%s is not a directory.'), rootpath)
raise SystemExit(1)
args.destdir = destdir = Path(args.destdir)
if not args.dryrun:
ensuredir(args.destdir)
excludes = tuple(
@ -285,7 +286,9 @@ def main(argv: Sequence[str] = (), /) -> int:
args.automodule_options = set()
elif isinstance(args.automodule_options, str):
args.automodule_options = set(args.automodule_options.split(','))
written_files, modules = recurse_tree(rootpath, excludes, args, args.templatedir)
opts = CliOptions(**args.__dict__)
written_files, modules = recurse_tree(rootpath, excludes, opts, args.templatedir)
if args.full:
from sphinx.cmd import quickstart as qs
@ -299,7 +302,7 @@ def main(argv: Sequence[str] = (), /) -> int:
prev_module = module
text += f' {module}\n'
d: dict[str, Any] = {
'path': args.destdir,
'path': str(destdir),
'sep': False,
'dot': '_',
'project': args.header,
@ -320,7 +323,7 @@ def main(argv: Sequence[str] = (), /) -> int:
'mastertocmaxdepth': args.maxdepth,
'mastertoctree': text,
'language': 'en',
'module_path': rootpath,
'module_path': str(rootpath),
'append_syspath': args.append_syspath,
}
if args.extensions:
@ -339,10 +342,10 @@ def main(argv: Sequence[str] = (), /) -> int:
)
elif args.tocfile:
written_files.append(
create_modules_toc_file(modules, args, args.tocfile, args.templatedir)
create_modules_toc_file(modules, opts, args.tocfile, args.templatedir)
)
if args.remove_old and not args.dryrun:
_remove_old_files(written_files, Path(args.destdir), args.suffix)
_remove_old_files(written_files, destdir, args.suffix)
return 0

View File

@ -1,11 +1,12 @@
from __future__ import annotations
import dataclasses
import glob
import os
import os.path
from importlib.machinery import EXTENSION_SUFFIXES
from pathlib import Path
from typing import TYPE_CHECKING, Protocol
from typing import TYPE_CHECKING
from sphinx import package_dir
from sphinx.ext.apidoc import logger
@ -267,7 +268,7 @@ def has_child_module(
def recurse_tree(
rootpath: str,
rootpath: str | os.PathLike[str],
excludes: Sequence[re.Pattern[str]],
opts: CliOptions,
user_template_dir: str | None = None,
@ -277,6 +278,7 @@ def recurse_tree(
ReST files.
"""
# check if the base directory is a package and get its name
rootpath = os.fspath(rootpath)
if is_packagedir(rootpath) or opts.implicit_namespaces:
root_package = rootpath.split(os.path.sep)[-1]
else:
@ -349,34 +351,35 @@ def is_excluded(root: str | Path, excludes: Sequence[re.Pattern[str]]) -> bool:
return any(exclude.match(root_str) for exclude in excludes)
class CliOptions(Protocol):
"""Arguments parsed from the command line."""
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class CliOptions:
"""Options for apidoc."""
module_path: str
module_path: Path
exclude_pattern: list[str]
destdir: str
quiet: bool
maxdepth: int
force: bool
followlinks: bool
dryrun: bool
separatemodules: bool
includeprivate: bool
tocfile: str
noheadings: bool
modulefirst: bool
implicit_namespaces: bool
automodule_options: set[str]
suffix: str
destdir: Path
quiet: bool = False
maxdepth: int = 4
force: bool = False
followlinks: bool = False
dryrun: bool = False
separatemodules: bool = False
includeprivate: bool = False
tocfile: str = 'modules'
noheadings: bool = False
modulefirst: bool = False
implicit_namespaces: bool = False
automodule_options: set[str] = dataclasses.field(default_factory=set)
suffix: str = 'rst'
remove_old: bool
remove_old: bool = False
# --full only
full: bool
append_syspath: bool
header: str
author: str | None
version: str | None
release: str | None
extensions: list[str] | None
templatedir: str | None
full: bool = False
append_syspath: bool = False
header: str = ''
author: str | None = None
version: str | None = None
release: str | None = None
extensions: list[str] | None = None
templatedir: str | None = None