Skip to content

Commit e9b7768

Browse files
authored
Integrate Initial Logger Support (#43)
1 parent 4351069 commit e9b7768

File tree

6 files changed

+100
-50
lines changed

6 files changed

+100
-50
lines changed

cppython/console.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
A click CLI for CPPython interfacing
33
"""
44

5+
from logging import Logger
56
from pathlib import Path
67
from typing import Any, Type
7-
from xmlrpc.client import Boolean
88

99
import click
1010
import tomlkit
@@ -54,13 +54,13 @@ def create_project(self) -> Project:
5454

5555

5656
@click.group()
57-
@click.option("-v", "--verbose", is_flag=True, help="Print additional output")
57+
@click.option("-v", "--verbose", count=True, help="Print additional output")
5858
@pass_config
59-
def cli(config, verbose: Boolean):
59+
def cli(config, verbose: int):
6060
"""
6161
entry_point group for the CLI commands
6262
"""
63-
config.configuration.verbose = verbose
63+
config.configuration.verbosity = verbose
6464

6565

6666
@cli.command()
@@ -118,8 +118,7 @@ def write_pyproject(self) -> None:
118118
Write output
119119
"""
120120

121-
def print(self, string: str) -> None:
121+
def register_logger(self, logger: Logger) -> None:
122122
"""
123123
TODO
124124
"""
125-
click.echo(string)

cppython/project.py

+69-26
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
The central delegation of the CPPython project
33
"""
44

5+
import logging
56
from dataclasses import dataclass
67
from importlib import metadata
7-
from pathlib import Path
88
from typing import Any, Type, TypeVar
9-
from xmlrpc.client import Boolean
109

1110
from cppython_core.schema import (
1211
API,
1312
CPPythonData,
1413
Generator,
14+
GeneratorConfiguration,
1515
Interface,
1616
Plugin,
1717
PyProject,
@@ -26,7 +26,21 @@ class ProjectConfiguration:
2626
TODO
2727
"""
2828

29-
verbose: Boolean = False
29+
_verbosity: int = 0
30+
31+
@property
32+
def verbosity(self) -> int:
33+
"""
34+
TODO
35+
"""
36+
return self._verbosity
37+
38+
@verbosity.setter
39+
def verbosity(self, value: int) -> None:
40+
"""
41+
TODO
42+
"""
43+
self._verbosity = min(max(value, 0), 2)
3044

3145

3246
class ProjectBuilder:
@@ -79,13 +93,15 @@ def generate_model(self, plugins: list[Type[Generator]]) -> Type[PyProject]:
7993
__base__=PyProject,
8094
)
8195

82-
def create_generators(self, plugins: list[Type[Generator]], pyproject: PyProject) -> list[Generator]:
96+
def create_generators(
97+
self, plugins: list[Type[Generator]], configuration: GeneratorConfiguration, pyproject: PyProject
98+
) -> list[Generator]:
8399
"""
84100
TODO
85101
"""
86102
_generators = []
87103
for plugin_type in plugins:
88-
_generators.append(plugin_type(pyproject))
104+
_generators.append(plugin_type(configuration, pyproject))
89105

90106
return _generators
91107

@@ -100,39 +116,69 @@ def __init__(
100116
) -> None:
101117

102118
self._enabled = False
103-
self.configuration = configuration
119+
self._configuration = configuration
120+
self._pyproject = None
121+
122+
levels = [logging.WARNING, logging.INFO, logging.DEBUG]
123+
124+
self._logger = logging.getLogger("cppython")
125+
self._logger.setLevel(levels[configuration.verbosity])
104126

105-
if self.configuration.verbose:
106-
interface.print("Starting CPPython project initialization")
127+
interface.register_logger(self._logger)
128+
129+
self._logger.info("Initializing project")
107130

108131
builder = ProjectBuilder(self.configuration)
109132
plugins = builder.gather_plugins(Generator)
110133

111134
if not plugins:
112-
if self.configuration.verbose:
113-
interface.print("No generator plugin was found.")
135+
self._logger.info("No generator plugin was found")
114136
return
115137

116138
extended_pyproject_type = builder.generate_model(plugins)
117-
self.pyproject = extended_pyproject_type(**pyproject_data)
139+
self._pyproject = extended_pyproject_type(**pyproject_data)
140+
141+
if self.pyproject is None:
142+
self._logger.info("Data is not defined")
143+
return
118144

119145
if self.pyproject.tool is None:
120-
if self.configuration.verbose:
121-
interface.print("Table [tool] is not defined")
146+
self._logger.info("Table [tool] is not defined")
122147
return
123148

124149
if self.pyproject.tool.cppython is None:
125-
if self.configuration.verbose:
126-
interface.print("Table [tool.cppython] is not defined")
150+
self._logger.info("Table [tool.cppython] is not defined")
127151
return
128152

129153
self._enabled = True
130154

131155
self._interface = interface
132-
self._generators = builder.create_generators(plugins, self.pyproject)
133156

134-
if self.configuration.verbose:
135-
interface.print("CPPython project initialized")
157+
generator_configuration = GeneratorConfiguration(self._logger)
158+
self._generators = builder.create_generators(plugins, generator_configuration, self.pyproject)
159+
160+
self._logger.info("Initialized project")
161+
162+
@property
163+
def enabled(self) -> bool:
164+
"""
165+
TODO
166+
"""
167+
return self._enabled
168+
169+
@property
170+
def configuration(self) -> ProjectConfiguration:
171+
"""
172+
TODO
173+
"""
174+
return self._configuration
175+
176+
@property
177+
def pyproject(self) -> PyProject | None:
178+
"""
179+
TODO
180+
"""
181+
return self._pyproject
136182

137183
def download(self):
138184
"""
@@ -148,35 +194,32 @@ def download(self):
148194
path.mkdir(parents=True, exist_ok=True)
149195

150196
if not generator.generator_downloaded(path):
151-
self._interface.print(f"Downloading the {generator.name()} tool")
197+
self._logger.info(f"Downloading the {generator.name()} tool")
152198

153199
# TODO: Make async with progress bar
154200
generator.download_generator(path)
155-
self._interface.print("Download complete")
201+
self._logger.info("Download complete")
156202

157203
# API Contract
158204

159205
def install(self) -> None:
160206
if self._enabled:
161-
if self.configuration.verbose:
162-
self._interface.print("CPPython: Installing...")
207+
self._logger.info("Installing project")
163208
self.download()
164209

165210
for generator in self._generators:
166211
generator.install()
167212

168213
def update(self) -> None:
169214
if self._enabled:
170-
if self.configuration.verbose:
171-
self._interface.print("CPPython: Updating...")
215+
self._logger.info("Updating project")
172216

173217
for generator in self._generators:
174218
generator.update()
175219

176220
def build(self) -> None:
177221
if self._enabled:
178-
if self.configuration.verbose:
179-
self._interface.print("CPPython: Building...")
222+
self._logger.info("Building project")
180223

181224
for generator in self._generators:
182225
generator.build()

pdm.lock

+11-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ requires-python = ">=3.10"
1616
dependencies = [
1717
"click>=8.1.2",
1818
"tomlkit>=0.10.1",
19-
"cppython-core>=0.2.1",
19+
"cppython-core>=0.3.2",
2020
"pydantic>=1.9.0",
2121
]
2222

@@ -40,7 +40,7 @@ test = [
4040
"pytest>=7.1.1",
4141
"pytest-cov>=3.0.0",
4242
"pytest-mock>=3.7.0",
43-
"pytest-cppython>=0.1.4",
43+
"pytest-cppython>=0.1.6",
4444
]
4545

4646
[project.scripts]

tests/unit/test_interface.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@ def test_verbosity(self):
7575

7676
assert result.exit_code == 0
7777

78-
assert config.configuration.verbose
78+
assert config.configuration.verbosity

tests/unit/test_project.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@
22
Test the functions related to the internal interface implementation and the 'Interface' interface itself
33
"""
44

5-
from pathlib import Path
6-
7-
from cppython_core.schema import Generator, GeneratorData, PyProject
5+
import logging
6+
7+
from cppython_core.schema import (
8+
Generator,
9+
GeneratorConfiguration,
10+
GeneratorData,
11+
PyProject,
12+
)
813
from pytest_mock import MockerFixture
914

1015
from cppython.data import default_pyproject
@@ -85,11 +90,13 @@ def test_generator_creation(self, mocker: MockerFixture):
8590

8691
configuration = ProjectConfiguration()
8792
builder = ProjectBuilder(configuration)
88-
generators = builder.create_generators([], default_pyproject)
93+
94+
generator_configuration = GeneratorConfiguration(logging.getLogger(__name__))
95+
generators = builder.create_generators([], generator_configuration, default_pyproject)
8996

9097
assert not generators
9198

9299
generator = mocker.Mock(spec=Generator)
93-
generators = builder.create_generators([generator], default_pyproject)
100+
generators = builder.create_generators([generator], generator_configuration, default_pyproject)
94101

95102
assert len(generators) == 1

0 commit comments

Comments
 (0)