11"""Plugin builder"""
22
3- import json
4- from copy import deepcopy
53from pathlib import Path
64
75from cppython .plugins .cmake .schema import CMakePresets , CMakeSyncData , ConfigurePreset
108class Builder :
119 """Aids in building the information needed for the CMake plugin"""
1210
11+ def __init__ (self ) -> None :
12+ """Initialize the builder"""
13+
1314 @staticmethod
14- def write_provider_preset (provider_directory : Path , data : CMakeSyncData ) -> None :
15+ def write_provider_preset (provider_directory : Path , provider_data : CMakeSyncData ) -> None :
1516 """Writes a provider preset from input sync data
1617
1718 Args:
1819 provider_directory: The base directory to place the preset files
19- data : The providers synchronization data
20+ provider_data : The providers synchronization data
2021 """
21- configure_preset = ConfigurePreset (name = data .provider_name , cacheVariables = None )
22- presets = CMakePresets (configurePresets = [configure_preset ])
22+ generated_configure_preset = ConfigurePreset (name = provider_data .provider_name )
23+
24+ # Toss in that sync data from the provider
25+ generated_configure_preset .cacheVariables = {
26+ 'CMAKE_PROJECT_TOP_LEVEL_INCLUDES' : str (provider_data .top_level_includes .as_posix ()),
27+ }
28+
29+ generated_preset = CMakePresets (configurePresets = [generated_configure_preset ])
2330
24- json_path = provider_directory / f'{ data .provider_name } .json'
31+ provider_preset_file = provider_directory / f'{ provider_data .provider_name } .json'
2532
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 )
33+ initial_preset = None
34+
35+ # If the file already exists, we need to compare it
36+ if provider_preset_file .exists ():
37+ with open (provider_preset_file , encoding = 'utf-8' ) as file :
38+ initial_json = file .read ()
39+ initial_preset = CMakePresets .model_validate_json (initial_json )
40+
41+ if generated_preset != initial_preset :
42+ serialized = generated_preset .model_dump_json (exclude_none = True , by_alias = False , indent = 4 )
43+ with open (provider_preset_file , 'w' , encoding = 'utf8' ) as file :
44+ file .write (serialized )
2945
3046 @staticmethod
3147 def write_cppython_preset (
32- cppython_preset_directory : Path , _provider_directory : Path , _provider_data : CMakeSyncData
48+ cppython_preset_directory : Path , provider_directory : Path , provider_data : CMakeSyncData
3349 ) -> Path :
3450 """Write the cppython presets which inherit from the provider presets
3551
3652 Args:
3753 cppython_preset_directory: The tool directory
54+ provider_directory: The base directory containing provider presets
55+ provider_data: The provider's synchronization data
3856
3957 Returns:
4058 A file path to the written data
4159 """
42- configure_preset = ConfigurePreset (name = 'cppython' , cacheVariables = None )
43- presets = CMakePresets (configurePresets = [configure_preset ])
60+ generated_configure_preset = ConfigurePreset (name = 'cppython' , inherits = provider_data .provider_name )
61+ generated_preset = CMakePresets (configurePresets = [generated_configure_preset ])
62+
63+ # Get the relative path to the provider preset file
64+ provider_preset_file = provider_directory / f'{ provider_data .provider_name } .json'
65+ relative_preset = provider_preset_file .relative_to (cppython_preset_directory , walk_up = True ).as_posix ()
4466
45- cppython_json_path = cppython_preset_directory / 'cppython.json'
67+ # Set the data
68+ generated_preset .include = [relative_preset ]
4669
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 )
70+ cppython_preset_file = cppython_preset_directory / 'cppython.json'
5071
51- return cppython_json_path
72+ initial_preset = None
73+
74+ # If the file already exists, we need to compare it
75+ if cppython_preset_file .exists ():
76+ with open (cppython_preset_file , encoding = 'utf-8' ) as file :
77+ initial_json = file .read ()
78+ initial_preset = CMakePresets .model_validate_json (initial_json )
79+
80+ # Only write the file if the data has changed
81+ if generated_preset != initial_preset :
82+ serialized = generated_preset .model_dump_json (exclude_none = True , by_alias = False , indent = 4 )
83+ with open (cppython_preset_file , 'w' , encoding = 'utf8' ) as file :
84+ file .write (serialized )
85+
86+ return cppython_preset_file
5287
5388 @staticmethod
54- def write_root_presets (preset_file : Path , _ : Path ) -> None :
89+ def write_root_presets (preset_file : Path , cppython_preset_file : Path ) -> None :
5590 """Read the top level json file and insert the include reference.
5691
5792 Receives a relative path to the tool cmake json file
@@ -61,14 +96,37 @@ def write_root_presets(preset_file: Path, _: Path) -> None:
6196
6297 Args:
6398 preset_file: Preset file to modify
99+ cppython_preset_file: Path to the cppython preset file to include
64100 """
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 :
101+ initial_root_preset = None
102+
103+ # If the file already exists, we need to compare it
104+ if preset_file .exists ():
105+ with open (preset_file , encoding = 'utf-8' ) as file :
106+ initial_json = file .read ()
107+ initial_root_preset = CMakePresets .model_validate_json (initial_json )
108+ root_preset = initial_root_preset .model_copy (deep = True )
109+ else :
110+ # If the file doesn't exist, we need to default it for the user
111+
112+ # Forward the tool's build directory
113+ default_configure_preset = ConfigurePreset (name = 'default' , inherits = 'cppython' , binaryDir = 'build' )
114+ root_preset = CMakePresets (configurePresets = [default_configure_preset ])
115+
116+ # Get the relative path to the cppython preset file
117+ preset_directory = preset_file .parent .absolute ()
118+ relative_preset = cppython_preset_file .relative_to (preset_directory , walk_up = True ).as_posix ()
119+
120+ # If the include key doesn't exist, we know we will write to disk afterwards
121+ if not root_preset .include :
122+ root_preset .include = []
123+
124+ # Only the included preset file if it doesn't exist. Implied by the above check
125+ if str (relative_preset ) not in root_preset .include :
126+ root_preset .include .append (str (relative_preset ))
127+
128+ # Only write the file if the data has changed
129+ if root_preset != initial_root_preset :
72130 with open (preset_file , 'w' , encoding = 'utf-8' ) as file :
73131 preset = root_preset .model_dump_json (exclude_none = True , indent = 4 )
74132 file .write (preset )
0 commit comments