Skip to content

Commit 5ff5c07

Browse files
committed
Conditional Preset Writing
1 parent 0968365 commit 5ff5c07

File tree

3 files changed

+76
-26
lines changed

3 files changed

+76
-26
lines changed

cppython/plugins/cmake/builder.py

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
"""Plugin builder"""
22

3-
import json
4-
from copy import deepcopy
53
from pathlib import Path
64

75
from cppython.plugins.cmake.schema import CMakePresets, CMakeSyncData, ConfigurePreset
@@ -18,40 +16,68 @@ def write_provider_preset(provider_directory: Path, data: CMakeSyncData) -> None
1816
provider_directory: The base directory to place the preset files
1917
data: The providers synchronization data
2018
"""
21-
configure_preset = ConfigurePreset(name=data.provider_name, cacheVariables=None)
22-
presets = CMakePresets(configurePresets=[configure_preset])
19+
generated_configure_preset = ConfigurePreset(name=data.provider_name, cacheVariables=None)
20+
generated_preset = CMakePresets(configurePresets=[generated_configure_preset])
2321

24-
json_path = provider_directory / f'{data.provider_name}.json'
22+
provider_preset_file = provider_directory / f'{data.provider_name}.json'
2523

26-
serialized = presets.model_dump_json(exclude_none=True, by_alias=False, indent=4)
27-
with open(json_path, 'w', encoding='utf8') as file:
28-
file.write(serialized)
24+
initial_preset = None
25+
26+
# If the file already exists, we need to compare it
27+
if provider_preset_file.exists():
28+
with open(provider_preset_file, encoding='utf-8') as file:
29+
initial_json = file.read()
30+
initial_preset = CMakePresets.model_validate_json(initial_json)
31+
32+
if generated_preset != initial_preset:
33+
serialized = generated_preset.model_dump_json(exclude_none=True, by_alias=False, indent=4)
34+
with open(provider_preset_file, 'w', encoding='utf8') as file:
35+
file.write(serialized)
2936

3037
@staticmethod
3138
def write_cppython_preset(
32-
cppython_preset_directory: Path, _provider_directory: Path, _provider_data: CMakeSyncData
39+
cppython_preset_directory: Path, provider_directory: Path, provider_data: CMakeSyncData
3340
) -> Path:
3441
"""Write the cppython presets which inherit from the provider presets
3542
3643
Args:
3744
cppython_preset_directory: The tool directory
45+
provider_directory: The base directory containing provider presets
46+
provider_data: The provider's synchronization data
3847
3948
Returns:
4049
A file path to the written data
4150
"""
42-
configure_preset = ConfigurePreset(name='cppython', cacheVariables=None)
43-
presets = CMakePresets(configurePresets=[configure_preset])
51+
generated_configure_preset = ConfigurePreset(name='cppython', inherits=provider_data.provider_name)
52+
generated_preset = CMakePresets(configurePresets=[generated_configure_preset])
53+
54+
# Get the relative path to the provider preset file
55+
provider_preset_file = provider_directory / f'{provider_data.provider_name}.json'
56+
relative_preset = provider_preset_file.relative_to(cppython_preset_directory, walk_up=True).as_posix()
57+
58+
# Set the data
59+
generated_preset.include = [relative_preset]
4460

45-
cppython_json_path = cppython_preset_directory / 'cppython.json'
61+
cppython_preset_file = cppython_preset_directory / 'cppython.json'
4662

47-
serialized = presets.model_dump_json(exclude_none=True, by_alias=False, indent=4)
48-
with open(cppython_json_path, 'w', encoding='utf8') as file:
49-
file.write(serialized)
63+
initial_preset = None
5064

51-
return cppython_json_path
65+
# If the file already exists, we need to compare it
66+
if cppython_preset_file.exists():
67+
with open(cppython_preset_file, encoding='utf-8') as file:
68+
initial_json = file.read()
69+
initial_preset = CMakePresets.model_validate_json(initial_json)
70+
71+
# Only write the file if the data has changed
72+
if generated_preset != initial_preset:
73+
serialized = generated_preset.model_dump_json(exclude_none=True, by_alias=False, indent=4)
74+
with open(cppython_preset_file, 'w', encoding='utf8') as file:
75+
file.write(serialized)
76+
77+
return cppython_preset_file
5278

5379
@staticmethod
54-
def write_root_presets(preset_file: Path, _: Path) -> None:
80+
def write_root_presets(preset_file: Path, cppython_preset_file: Path) -> None:
5581
"""Read the top level json file and insert the include reference.
5682
5783
Receives a relative path to the tool cmake json file
@@ -61,14 +87,33 @@ def write_root_presets(preset_file: Path, _: Path) -> None:
6187
6288
Args:
6389
preset_file: Preset file to modify
90+
cppython_preset_file: Path to the cppython preset file to include
6491
"""
65-
with open(preset_file, encoding='utf-8') as file:
66-
initial_json = file.read()
67-
68-
initial_root_preset = CMakePresets.model_validate_json(initial_json)
69-
70-
# Only write the file if the contents have changed
71-
if (root_preset := deepcopy(initial_root_preset)) != initial_root_preset:
92+
initial_root_preset = None
93+
94+
# If the file already exists, we need to compare it
95+
if preset_file.exists():
96+
with open(preset_file, encoding='utf-8') as file:
97+
initial_json = file.read()
98+
initial_root_preset = CMakePresets.model_validate_json(initial_json)
99+
root_preset = initial_root_preset.model_copy(deep=True)
100+
else:
101+
root_preset = CMakePresets()
102+
103+
# Get the relative path to the cppython preset file
104+
preset_directory = preset_file.parent.absolute()
105+
relative_preset = cppython_preset_file.relative_to(preset_directory, walk_up=True).as_posix()
106+
107+
# If the include key doesn't exist, we know we will write to disk afterwards
108+
if not root_preset.include:
109+
root_preset.include = []
110+
111+
# Only the included preset file if it doesn't exist. Implied by the above check
112+
if str(relative_preset) not in root_preset.include:
113+
root_preset.include.append(str(relative_preset))
114+
115+
# Only write the file if the data has changed
116+
if root_preset != initial_root_preset:
72117
with open(preset_file, 'w', encoding='utf-8') as file:
73118
preset = root_preset.model_dump_json(exclude_none=True, indent=4)
74119
file.write(preset)

cppython/plugins/cmake/resolution.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""Builder to help resolve cmake state"""
22

3-
import json
43
from typing import Any
54

65
from cppython.core.schema import CorePluginData

cppython/plugins/cmake/schema.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class ConfigurePreset(CPPythonModel, extra='allow'):
4747
"""Partial Configure Preset specification to allow cache variable injection"""
4848

4949
name: str
50+
inherits: Annotated[
51+
str | list[str] | None, Field(description='The inherits field allows inheriting from other presets.')
52+
] = None
5053
cacheVariables: dict[str, None | bool | str | CacheVariable] | None = None
5154

5255

@@ -57,8 +60,11 @@ class CMakePresets(CPPythonModel, extra='allow'):
5760
"""
5861

5962
version: Annotated[int, Field(description='The version of the JSON schema.')] = 9
63+
include: Annotated[
64+
list[str] | None, Field(description='The include field allows inheriting from another preset.')
65+
] = None
6066
configurePresets: Annotated[list[ConfigurePreset], Field(description='The list of configure presets')] = [
61-
ConfigurePreset(name='default')
67+
ConfigurePreset(name='default', inherits='cppython')
6268
]
6369

6470

0 commit comments

Comments
 (0)