11import sys
22import time
3- from typing import List , Dict , Any
3+ from typing import List , Any
44import argparse
55import json
66import logging
77from pathlib import Path
8- from subprocess import check_call , getoutput
8+ from subprocess import check_call
99import shutil
1010import re
1111import os
3333 gen_dpg ,
3434 dpg_relative_folder ,
3535 gen_typespec ,
36- return_origin_path ,
37- check_api_version_in_subfolder ,
38- call_build_config ,
3936 del_outdated_generated_files ,
4037)
4138from .conf import CONF_NAME
@@ -53,13 +50,6 @@ def execute_func_with_timeout(func, timeout: int = 900) -> Any:
5350 return multiprocessing .Pool (processes = 1 ).apply_async (func ).get (timeout )
5451
5552
56- def is_multiapi_package (python_md_content : List [str ]) -> bool :
57- for line in python_md_content :
58- if re .findall (r"\s*multiapi\s*:\s*true" , line ):
59- return True
60- return False
61-
62-
6353# return relative path like: network/azure-mgmt-network
6454def extract_sdk_folder (python_md : List [str ]) -> str :
6555 pattern = ["$(python-sdks-folder)" , "azure-mgmt-" ]
@@ -84,7 +74,6 @@ def get_readme_python_content(readme: str) -> List[str]:
8474def del_outdated_files (readme : str ):
8575 content = get_readme_python_content (readme )
8676 sdk_folder = extract_sdk_folder (content )
87- is_multiapi = is_multiapi_package (content )
8877 if sdk_folder :
8978 # remove tsp-location.yaml
9079 tsp_location = Path (f"sdk/{ sdk_folder } /tsp-location.yaml" )
@@ -94,127 +83,16 @@ def del_outdated_files(readme: str):
9483 # remove generated_samples
9584 sample_folder = Path (f"sdk/{ sdk_folder } /generated_samples" )
9685 if sample_folder .exists ():
97- # rdbms is generated from different swagger folder;multiapi package may don't generate every time
98- if "azure-mgmt-rdbms" not in str (sample_folder ) and not is_multiapi :
86+ # rdbms is generated from different swagger folder
87+ if "azure-mgmt-rdbms" not in str (sample_folder ):
9988 shutil .rmtree (sample_folder )
10089 _LOGGER .info (f"remove sample folder: { sample_folder } " )
10190 else :
102- _LOGGER .info (f"we don't remove sample folder for rdbms or multiapi package " )
91+ _LOGGER .info (f"we don't remove sample folder for rdbms" )
10392 else :
10493 _LOGGER .info (f"sample folder does not exist: { sample_folder } " )
10594 else :
106- _LOGGER .info (f"do not find valid sdk_folder in { python_readme } " )
107-
108-
109- # look for fines in tag like:
110- # ``` yaml $(tag) == 'package-2023-05-01-preview-only'
111- # input-file:
112- # - Microsoft.Insights/preview/2023-05-01-preview/tenantActionGroups_API.json
113- # ```
114- def get_related_swagger (readme_content : List [str ], tag : str ) -> List [str ]:
115- result = []
116- for idx in range (len (readme_content )):
117- line = readme_content [idx ]
118- if tag in line and "```" in line and "tag" in line and "==" in line and "yaml" in line :
119- idx += 1
120- while idx < len (readme_content ):
121- if "```" in readme_content [idx ]:
122- break
123- if ".json" in readme_content [idx ] and (
124- re .compile (r"\d{4}-\d{1,2}-\d{1,2}" ).findall (readme_content [idx ])
125- or "Microsoft." in readme_content [idx ]
126- ):
127- result .append (readme_content [idx ].strip ("\n -" ))
128- idx += 1
129- break
130- return result
131-
132-
133- def get_last_commit_info (files : List [str ]) -> str :
134- result = [getoutput (f'git log -1 --pretty="format:%ai %H" { f } ' ).strip ("\n " ) + " " + f for f in files ]
135- result .sort ()
136- return result [- 1 ]
137-
138-
139- # input_readme: "specification/paloaltonetworks/resource-manager/readme.md"
140- # source: content of readme.python.md
141- # work directory is in root folder of azure-rest-api-specs
142- @return_origin_path
143- def choose_tag_and_update_meta (
144- idx : int , source : List [str ], target : List [str ], input_readme : str , meta : Dict [str , Any ], need_regenerate : bool
145- ) -> int :
146- os .chdir (str (Path (input_readme ).parent ))
147- with open ("readme.md" , "r" ) as file_in :
148- readme_content = file_in .readlines ()
149-
150- while idx < len (source ):
151- if "```" in source [idx ]:
152- break
153- if "tag:" in source [idx ]:
154- tag = source [idx ].split ("tag:" )[- 1 ].strip ("\n " )
155- related_files = get_related_swagger (readme_content , tag )
156- if related_files :
157- commit_info = get_last_commit_info (related_files )
158- recorded_info = meta .get (tag , "" )
159- # there may be new commit after last release
160- if need_regenerate or commit_info > recorded_info :
161- _LOGGER .info (f"update tag: { tag } with commit info { commit_info } " )
162- meta [tag ] = commit_info
163- target .append (source [idx ])
164- else :
165- _LOGGER .info (f"skip tag: { tag } since commit info doesn't change" )
166- else :
167- _LOGGER .warning (f"do not find related swagger for tag: { tag } " )
168- else :
169- target .append (source [idx ])
170- idx += 1
171- return idx
172-
173-
174- def extract_version_info (config : Dict [str , Any ]) -> str :
175- autorest_version = config .get ("autorest" , "" )
176- autorest_modelerfour_version = config .get ("use" , [])
177- return autorest_version + "" .join (autorest_modelerfour_version )
178-
179-
180- def if_need_regenerate (meta : Dict [str , Any ]) -> bool :
181- with open (str (Path ("../azure-sdk-for-python" , CONFIG_FILE )), "r" ) as file_in :
182- config = json .load (file_in )
183- current_info = config ["meta" ]["autorest_options" ]["version" ] + "" .join (
184- sorted (config ["meta" ]["autorest_options" ]["use" ])
185- )
186- recorded_info = meta ["autorest" ] + "" .join (sorted (meta ["use" ]))
187- return recorded_info != current_info
188-
189-
190- # spec_folder: "../azure-rest-api-specs"
191- # input_readme: "specification/paloaltonetworks/resource-manager/readme.md"
192- @return_origin_path
193- def need_regen_for_multiapi_package (spec_folder : str , input_readme : str ) -> bool :
194- os .chdir (spec_folder )
195- python_readme = (Path (input_readme ).parent / "readme.python.md" ).absolute ()
196- if not python_readme .exists ():
197- _LOGGER .info (f"do not find python configuration: { python_readme } " )
198- return False
199-
200- with open (python_readme , "r" ) as file_in :
201- python_md_content = file_in .readlines ()
202- is_multiapi = is_multiapi_package (python_md_content )
203- if not is_multiapi :
204- _LOGGER .info (f"do not find multiapi configuration in { python_readme } " )
205- return False
206-
207- after_handle = []
208- for idx in range (len (python_md_content )):
209- if re .findall (r"\s*clear-output-folder\s*:\s*true\s*" , python_md_content [idx ]):
210- continue
211- if re .findall (r"\s*-\s*tag\s*:" , python_md_content [idx ]):
212- continue
213- after_handle .append (python_md_content [idx ])
214-
215- with open (python_readme , "w" ) as file_out :
216- file_out .writelines (after_handle )
217- return True
95+ _LOGGER .info (f"do not find valid sdk_folder in readme.python.md" )
21896
21997
22098def main (generate_input , generate_output ):
@@ -232,6 +110,7 @@ def main(generate_input, generate_output):
232110 run_in_pipeline = data .get ("runMode" ) is not None
233111 for input_type , readme_or_tsp in readme_and_tsp :
234112 _LOGGER .info (f"[CODEGEN]({ readme_or_tsp } )codegen begin" )
113+ config = None
235114 try :
236115 code_generation_start_time = time .time ()
237116 if input_type == "relatedTypeSpecProjectFolder" :
@@ -248,8 +127,7 @@ def main(generate_input, generate_output):
248127 elif "resource-manager" in readme_or_tsp :
249128 relative_path_readme = str (Path (spec_folder , readme_or_tsp ))
250129 del_outdated_files (relative_path_readme )
251- generate_mgmt = partial (
252- generate ,
130+ config = generate (
253131 CONFIG_FILE ,
254132 sdk_folder ,
255133 [],
@@ -258,9 +136,6 @@ def main(generate_input, generate_output):
258136 force_generation = True ,
259137 python_tag = python_tag ,
260138 )
261- config = generate_mgmt ()
262- if need_regen_for_multiapi_package (spec_folder , readme_or_tsp ):
263- generate_mgmt ()
264139 else :
265140 config = gen_dpg (readme_or_tsp , data .get ("autorestConfig" , "" ), dpg_relative_folder (spec_folder ))
266141 _LOGGER .info (f"code generation cost time: { int (time .time () - code_generation_start_time )} seconds" )
@@ -296,8 +171,6 @@ def main(generate_input, generate_output):
296171 package_entry ["path" ] = [folder_name ]
297172 package_entry [spec_word ] = [readme_or_tsp ]
298173 package_entry ["tagIsStable" ] = not judge_tag_preview (sdk_code_path , package_name )
299- readme_python_content = get_readme_python_content (str (Path (spec_folder ) / readme_or_tsp ))
300- package_entry ["isMultiapi" ] = is_multiapi_package (readme_python_content )
301174 package_entry ["targetReleaseDate" ] = data .get ("targetReleaseDate" , "" )
302175 package_entry ["allowInvalidNextVersion" ] = data .get ("allowInvalidNextVersion" , False )
303176 result [package_name ] = package_entry
@@ -322,15 +195,18 @@ def main(generate_input, generate_output):
322195
323196 # Update metadata
324197 try :
325- update_servicemetadata (
326- sdk_folder ,
327- data ,
328- config ,
329- folder_name ,
330- package_name ,
331- spec_folder ,
332- readme_or_tsp ,
333- )
198+ if config is not None :
199+ update_servicemetadata (
200+ sdk_folder ,
201+ data ,
202+ config ,
203+ folder_name ,
204+ package_name ,
205+ spec_folder ,
206+ readme_or_tsp ,
207+ )
208+ else :
209+ _LOGGER .warning (f"Skip metadata update for { package_name } as config is not available" )
334210 except Exception as e :
335211 _LOGGER .warning (f"Fail to update meta: { str (e )} " )
336212
@@ -343,15 +219,6 @@ def main(generate_input, generate_output):
343219 except Exception as e :
344220 _LOGGER .warning (f"Fail to setup package { package_name } in { readme_or_tsp } : { str (e )} " )
345221
346- # check whether multiapi package has only one api-version in per subfolder
347- try :
348- if result [package_name ]["isMultiapi" ]:
349- check_api_version_in_subfolder (sdk_code_path )
350- except Exception as e :
351- _LOGGER .warning (
352- f"Fail to check api version in subfolder for { package_name } in { readme_or_tsp } : { str (e )} "
353- )
354-
355222 # Changelog generation
356223 try :
357224 last_version , last_stable_release = get_version_info (package_name , result [package_name ]["tagIsStable" ])
@@ -362,7 +229,6 @@ def main(generate_input, generate_output):
362229 result [package_name ]["tagIsStable" ],
363230 last_stable_release = last_stable_release ,
364231 prefolder = folder_name ,
365- is_multiapi = result [package_name ]["isMultiapi" ],
366232 )
367233
368234 changelog_generation_start_time = time .time ()
0 commit comments