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