|
1 | | -from cppython.project import Project |
2 | | -from cppython.schema import Interface, PEP621 |
| 1 | +""" |
| 2 | +A click CLI for CPPython interfacing |
| 3 | +""" |
| 4 | + |
3 | 5 | from pathlib import Path |
| 6 | +from typing import Type |
4 | 7 |
|
5 | 8 | import click |
6 | 9 | import tomlkit |
7 | 10 |
|
| 11 | +from cppython.project import Project |
| 12 | +from cppython.schema import GeneratorData, GeneratorDataType, Interface, PyProject |
| 13 | + |
| 14 | + |
| 15 | +def _create_pyproject(): |
8 | 16 |
|
9 | | -def _read_data(): |
| 17 | + # Search for a path upward |
10 | 18 | path = Path.cwd() |
11 | 19 |
|
12 | 20 | while not path.glob("pyproject.toml"): |
13 | 21 | if path.is_absolute(): |
14 | 22 | assert ( |
15 | | - "This is not a valid project. No pyproject.toml found in the current directory or any of its parents." |
16 | | - ) |
| 23 | + False |
| 24 | + ), "This is not a valid project. No pyproject.toml found in the current directory or any of its parents." |
17 | 25 |
|
18 | | - return tomlkit.loads(Path(path / "pyproject.toml").read_text(encoding="utf-8")) |
| 26 | + path = Path(path / "pyproject.toml") |
19 | 27 |
|
| 28 | + # Load file |
| 29 | + data = tomlkit.loads(path.read_text(encoding="utf-8")) |
20 | 30 |
|
21 | | -class Config(object): |
| 31 | + # Interpret and validate data |
| 32 | + return PyProject(**data) |
| 33 | + |
| 34 | + |
| 35 | +class Config: |
22 | 36 | """ |
23 | 37 | The data object that will be expanded alongside 'pass_obj' |
24 | 38 | """ |
25 | 39 |
|
26 | 40 | def __init__(self): |
27 | | - |
28 | | - data = _read_data() |
| 41 | + pyproject = _create_pyproject() |
29 | 42 |
|
30 | 43 | # Initialize the object hook into CPPython |
31 | | - interface = ConsoleInterface(data) |
| 44 | + interface = ConsoleInterface(pyproject) |
32 | 45 |
|
33 | 46 | # Initialize the CPPython context |
34 | 47 | self.project = Project(interface) |
35 | 48 |
|
36 | | - def load(self): |
37 | | - self.project.load() |
38 | | - |
39 | 49 |
|
40 | 50 | pass_config = click.make_pass_decorator(Config) |
41 | 51 |
|
42 | 52 |
|
43 | 53 | @click.group() |
44 | 54 | @click.pass_context |
45 | 55 | def cli(context): |
| 56 | + """ |
| 57 | + entry_point group for the CLI commands |
| 58 | + """ |
46 | 59 | context.ensure_object(Config) |
47 | 60 |
|
48 | | - # Initialize cppython |
49 | | - context.obj.load() |
50 | | - |
51 | 61 |
|
52 | 62 | @cli.command() |
53 | 63 | @pass_config |
54 | 64 | def install(config): |
| 65 | + """ |
| 66 | + Fulfills the 'install' API requirement |
| 67 | + """ |
55 | 68 | config.project.install() |
56 | 69 |
|
57 | 70 |
|
58 | 71 | @cli.command() |
59 | 72 | @pass_config |
60 | 73 | def update(config): |
| 74 | + """ |
| 75 | + Fulfills the 'update' API requirement |
| 76 | + """ |
61 | 77 | config.project.update() |
62 | 78 |
|
63 | 79 |
|
64 | | -@cli.result_callback() |
| 80 | +@cli.command() |
65 | 81 | @pass_config |
66 | | -def cleanup(config, result): |
67 | | - pass |
68 | | - |
69 | | - |
70 | | -class ConsoleInterface(Interface): |
| 82 | +def build(config): |
71 | 83 | """ |
72 | | - TODO: Description |
| 84 | + Fulfills the 'build' API requirement |
73 | 85 | """ |
| 86 | + config.project.build() |
74 | 87 |
|
75 | | - def __init__(self, data: dict) -> None: |
76 | | - self._data = data |
77 | 88 |
|
| 89 | +@cli.result_callback() |
| 90 | +@pass_config |
| 91 | +def cleanup(config, result): |
78 | 92 | """ |
79 | | - Plugin Contract |
| 93 | + Post-command cleanup |
80 | 94 | """ |
81 | 95 |
|
82 | | - @staticmethod |
83 | | - def name() -> str: |
84 | | - """ |
85 | | - The name of the generator |
86 | | - """ |
87 | | - return "console" |
88 | 96 |
|
| 97 | +class ConsoleInterface(Interface): |
89 | 98 | """ |
90 | | - Interface Contract |
| 99 | + Interface implementation to pass to the project |
91 | 100 | """ |
92 | 101 |
|
93 | | - @staticmethod |
94 | | - def external_config() -> bool: |
95 | | - """ |
96 | | - True if the plugin can read its own configuration. |
97 | | - False otherwise |
98 | | - """ |
99 | | - |
100 | | - return False |
101 | | - |
102 | | - @staticmethod |
103 | | - def parse_pep_621(data: dict) -> PEP621: |
| 102 | + def read_generator_data(self, generator_data_type: Type[GeneratorDataType]) -> GeneratorDataType: |
104 | 103 | """ |
105 | | - Requests the plugin to read the available PEP 621 information. Only requested if the plugin is not the entrypoint |
| 104 | + Requests generator information |
106 | 105 | """ |
107 | | - raise NotImplementedError() |
| 106 | + return generator_data_type() |
108 | 107 |
|
109 | | - def pep_621(self) -> PEP621: |
| 108 | + def write_pyproject(self) -> None: |
110 | 109 | """ |
111 | | - Requests PEP 621 information from the pyproject |
| 110 | + Write output |
112 | 111 | """ |
113 | | - return self.parse_pep_621(self._data) |
114 | | - |
115 | | - def write_pyproject(self) -> None: |
116 | | - raise NotImplementedError() |
117 | | - |
118 | | - def read_pyproject(self) -> dict: |
119 | | - return self._data |
| 112 | + pass |
0 commit comments