• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

abravalheri / validate-pyproject / 5226968556240896

pending completion
5226968556240896

push

cirrus-ci

GitHub
Typo: validate-project => validate-pyproject (#78)

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/validate_pyproject/pre_compile/cli.py
1
import json
8✔
2
import logging
8✔
3
import sys
8✔
4
from functools import partial, wraps
8✔
5
from pathlib import Path
8✔
6
from types import MappingProxyType
8✔
7
from typing import Any, Dict, List, Mapping, NamedTuple, Sequence
8✔
8

9
from .. import cli
8✔
10
from ..plugins import PluginWrapper
8✔
11
from ..plugins import list_from_entry_points as list_plugins_from_entry_points
8✔
12
from . import pre_compile
8✔
13

14
if sys.platform == "win32":  # pragma: no cover
15
    from subprocess import list2cmdline as arg_join
16
elif sys.version_info[:2] >= (3, 8):  # pragma: no cover
17
    from shlex import join as arg_join
18
else:  # pragma: no cover
19
    from shlex import quote
20

21
    def arg_join(args: Sequence[str]) -> str:
22
        return " ".join(quote(x) for x in args)
23

24

25
_logger = logging.getLogger(__package__)
8✔
26

27

28
def JSON_dict(name: str, value: str):
8✔
29
    try:
8✔
30
        return ensure_dict(name, json.loads(value))
8✔
31
    except json.JSONDecodeError as ex:
8✔
32
        raise ValueError(f"Invalid JSON: {value}") from ex
8✔
33

34

35
META: Dict[str, dict] = {
8✔
36
    "output_dir": dict(
37
        flags=("-O", "--output-dir"),
38
        default=".",
39
        type=Path,
40
        help="Path to the directory where the files for embedding will be generated "
41
        "(default: current working directory)",
42
    ),
43
    "main_file": dict(
44
        flags=("-M", "--main-file"),
45
        default="__init__.py",
46
        help="Name of the file that will contain the main `validate` function"
47
        "(default: `%(default)s`)",
48
    ),
49
    "replacements": dict(
50
        flags=("-R", "--replacements"),
51
        default="{}",
52
        type=wraps(JSON_dict)(partial(JSON_dict, "replacements")),
53
        help="JSON string (don't forget to quote) representing a map between strings "
54
        "that should be replaced in the generated files and their replacement, "
55
        "for example: \n"
56
        '-R \'{"from packaging import": "from .._vendor.packaging import"}\'',
57
    ),
58
}
59

60

61
def ensure_dict(name: str, value: Any) -> dict:
8✔
62
    if not isinstance(value, dict):
8✔
63
        msg = f"`{value.__class__.__name__}` given (value = {value!r})."
8✔
64
        raise ValueError(f"`{name}` should be a dict. {msg}")
8✔
65
    return value
8✔
66

67

68
class CliParams(NamedTuple):
8✔
69
    plugins: List[PluginWrapper]
8✔
70
    output_dir: Path = Path(".")
8✔
71
    main_file: str = "__init__.py"
8✔
72
    replacements: Mapping[str, str] = MappingProxyType({})
8✔
73
    loglevel: int = logging.WARNING
8✔
74

75

76
def parser_spec(plugins: Sequence[PluginWrapper]) -> Dict[str, dict]:
8✔
77
    common = ("version", "enable", "disable", "verbose", "very_verbose")
8✔
78
    cli_spec = cli.__meta__(plugins)
8✔
79
    meta = {k: v.copy() for k, v in META.items()}
8✔
80
    meta.update({k: cli_spec[k].copy() for k in common})
8✔
81
    return meta
8✔
82

83

84
def run(args: Sequence[str] = ()):
8✔
85
    args = args if args else sys.argv[1:]
8✔
86
    cmd = f"python -m {__package__} " + arg_join(args)
8✔
87
    plugins = list_plugins_from_entry_points()
8✔
88
    desc = 'Generate files for "pre-compiling" `validate-pyproject`'
8✔
89
    prms = cli.parse_args(args, plugins, desc, parser_spec, CliParams)
8✔
90
    cli.setup_logging(prms.loglevel)
8✔
91
    pre_compile(prms.output_dir, prms.main_file, cmd, prms.plugins, prms.replacements)
8✔
92
    return 0
8✔
93

94

95
main = cli.exceptions2exit()(run)
8✔
96

97

98
if __name__ == "__main__":
99
    main()
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc