1212import os
1313import sys
1414import sysconfig
15+ from pathlib import Path
1516
1617TYPE_CHECKING = False
1718if TYPE_CHECKING :
18- from typing import Any
19+ from typing import Any , Literal
20+
21+ type StrPath = str | os .PathLike [str ]
22+ type ValidSchemaVersion = Literal ['1.0' ]
23+
24+
25+ def write_build_details (
26+ * ,
27+ schema_version : ValidSchemaVersion ,
28+ base_path : StrPath | None ,
29+ location : StrPath ,
30+ ) -> None :
31+ data = generate_data (schema_version )
32+ if base_path is not None :
33+ make_paths_relative (data , base_path )
34+
35+ json_output = json .dumps (data , indent = 2 )
36+ with open (location , 'w' , encoding = 'utf-8' ) as f :
37+ f .write (json_output )
38+ f .write ('\n ' )
1939
2040
2141def version_info_to_dict (obj : sys ._version_info ) -> dict [str , Any ]:
@@ -29,7 +49,9 @@ def get_dict_key(container: dict[str, Any], key: str) -> dict[str, Any]:
2949 return container
3050
3151
32- def generate_data (schema_version : str ) -> collections .defaultdict [str , Any ]:
52+ def generate_data (
53+ schema_version : ValidSchemaVersion
54+ ) -> collections .defaultdict [str , Any ]:
3355 """Generate the build-details.json data (PEP 739).
3456
3557 :param schema_version: The schema version of the data we want to generate.
@@ -133,11 +155,7 @@ def generate_data(schema_version: str) -> collections.defaultdict[str, Any]:
133155 return data
134156
135157
136- def make_paths_relative (data : dict [str , Any ], config_path : str | None = None ) -> None :
137- # Make base_prefix relative to the config_path directory
138- if config_path :
139- data ['base_prefix' ] = relative_path (data ['base_prefix' ],
140- os .path .dirname (config_path ))
158+ def make_paths_relative (data : dict [str , Any ], base_path : str | None = None ) -> None :
141159 base_prefix = data ['base_prefix' ]
142160
143161 # Update path values to make them relative to base_prefix
@@ -167,8 +185,12 @@ def make_paths_relative(data: dict[str, Any], config_path: str | None = None) ->
167185 new_path = os .path .join ('.' , new_path )
168186 container [child ] = new_path
169187
188+ if base_path :
189+ # Make base_prefix relative to the base_path directory
190+ config_dir = Path (base_path ).resolve ().parent
191+ data ['base_prefix' ] = relative_path (base_prefix , config_dir )
170192
171- def relative_path (path : str , base : str ) -> str :
193+ def relative_path (path : StrPath , base : StrPath ) -> str :
172194 if os .name != 'nt' :
173195 return os .path .relpath (path , base )
174196
@@ -201,15 +223,18 @@ def main() -> None:
201223 )
202224
203225 args = parser .parse_args ()
204-
205- data = generate_data (args .schema_version )
206- if args .relative_paths :
207- make_paths_relative (data , args .config_file_path )
208-
209- json_output = json .dumps (data , indent = 2 )
210- with open (args .location , 'w' , encoding = 'utf-8' ) as f :
211- f .write (json_output )
212- f .write ('\n ' )
226+ if os .name == 'nt' :
227+ # Windows builds are relocatable; always make paths relative.
228+ base_path = args .config_file_path or args .location
229+ elif args .relative_paths :
230+ base_path = args .config_file_path
231+ else :
232+ base_path = None
233+ write_build_details (
234+ schema_version = args .schema_version ,
235+ base_path = base_path ,
236+ location = args .location ,
237+ )
213238
214239
215240if __name__ == '__main__' :
0 commit comments