5
5
import os
6
6
import glob
7
7
8
- import typing
9
8
from typing import Dict , List
10
9
11
- CONFIG_FILE = os .path .join (os .path .dirname (os .path .abspath (__file__ )), "package_service_mapping.json" )
12
10
GENERATED_PACKAGES_LIST_FILE = "toc_tree.rst"
13
11
14
12
_LOGGER = logging .getLogger (__name__ )
@@ -73,117 +71,112 @@ def make_title(title):
73
71
74
72
"""
75
73
76
- # Update the code to compute this list automatically
77
- MULTIAPI_VERSION_NAMESPACE = [
78
- "azure.mgmt.storage" ,
79
- "azure.mgmt.web" ,
80
- "azure.mgmt.network" ,
81
- "azure.mgmt.compute" ,
82
- "azure.mgmt.containerregistry" ,
83
- "azure.mgmt.containerservice" ,
84
- "azure.mgmt.dns" ,
85
- "azure.mgmt.eventhub" ,
86
- "azure.mgmt.resource.resources" ,
87
- "azure.mgmt.resource.features" ,
88
- "azure.mgmt.resource.links" ,
89
- "azure.mgmt.resource.locks" ,
90
- "azure.mgmt.resource.policy" ,
91
- "azure.mgmt.resource.subscriptions" ,
92
- ]
93
-
94
-
95
- def get_updated_config (config_path : str , package_root : str ) -> Dict [str , Dict [str , typing .Union [str , List [str ]]]]:
96
- with Path (config_path ).open () as config_fd :
97
- config = json .load (config_fd )
98
74
99
- namespace_folders = os .path .basename (package_root ).split ("-" )
100
- package_name = "-" .join (namespace_folders )
101
- namespace = "." .join (namespace_folders )
102
-
103
- api_directory = os .path .join (package_root , * namespace_folders )
75
+ def get_valid_versions (api_directory : str ) -> List [str ]:
104
76
glob_path = os .path .join (api_directory , "v20*/" )
105
- valid_versions = glob .glob (glob_path )
77
+ return glob .glob (glob_path )
106
78
107
- for version_path in valid_versions :
108
- api_version = os .path .relpath (version_path , start = api_directory )
109
- full_namespace = namespace + f".{ api_version } "
110
79
111
- if package_name in config :
112
- if "namespaces" in config [package_name ]:
113
- ns = config [package_name ]["namespaces" ]
114
- if ns :
115
- if full_namespace not in ns :
116
- ns .append (full_namespace )
80
+ def is_subnamespace (version : str ) -> bool :
81
+ return not version .startswith ("v20" )
117
82
118
- return config
119
83
84
+ def get_package_namespaces (package_root : str ) -> List [str ]:
85
+ namespace_folders = os .path .basename (package_root ).split ("-" )
86
+ namespace = "." .join (namespace_folders )
120
87
121
- def generate_doc (config_path : str , output_directory : str = "./ref/" , package_root : str = None ) -> None :
122
- multiapi_found_apiversion = {}
123
- # we are handed a directory that looks like <path-to-repo>/sdk/containerservice/azure-mgmt-containerservice/
124
- project_pattern = os .path .basename (package_root ).replace ("-" , "." )
125
- rst_path_template = os .path .join (output_directory , "{}.rst" )
126
- rst_namespace_template = os .path .join (output_directory , "{}.{}.rst" )
88
+ # add top namespace
89
+ namespaces = {namespace : []}
127
90
128
- config = get_updated_config (config_path , package_root )
91
+ api_directory = os .path .join (package_root , * namespace_folders )
92
+ valid_versions = get_valid_versions (api_directory )
129
93
130
- package_list_path = []
94
+ # check for subnamespaces like azure.mgmt.resource.locks
95
+ if not valid_versions :
96
+ subnamespaces = glob .glob (f"{ api_directory } /*/" )
97
+ for snp_path in subnamespaces :
98
+ versions = get_valid_versions (snp_path )
99
+ valid_versions .extend (versions )
131
100
132
- namespaces = [n for pack in config .values () for n in pack .get ("namespaces" , {})]
101
+ for version_path in valid_versions :
102
+ version = os .path .relpath (version_path , start = api_directory )
103
+ if is_subnamespace (version ):
104
+ subnamespace_name , api_version = version .split ("/" )
105
+ full_namespace = "." .join ([namespace , subnamespace_name , api_version ])
106
+ subnamespace = "." .join ([namespace , subnamespace_name ])
107
+ if subnamespace not in namespaces [namespace ]:
108
+ namespaces [namespace ].append (subnamespace )
109
+ namespaces .setdefault (subnamespace , []).append (full_namespace )
110
+ else :
111
+ full_namespace = "." .join ([namespace , version ])
112
+ namespaces [namespace ].append (full_namespace )
133
113
134
- for namespace in namespaces :
135
- if project_pattern and not namespace .startswith (project_pattern ):
136
- continue
114
+ return namespaces
137
115
138
- _LOGGER .info ("Working on %s" , namespace )
139
116
140
- rst_path = rst_path_template .format (namespace )
141
- with Path (rst_path ).open ("w" ) as rst_file :
142
- rst_file .write (PACKAGE_TEMPLATE .format (title = make_title (namespace + " package" ), namespace = namespace ))
117
+ def write_rst (version : str , rst_path_template : str , rst_namespace_template : str , package_list_path : List [str ]) -> None :
118
+ rst_path = rst_path_template .format (version )
119
+ with Path (rst_path ).open ("w" ) as rst_file :
120
+ rst_file .write (PACKAGE_TEMPLATE .format (title = make_title (version + " package" ), namespace = version ))
143
121
144
- for module in ["operations" , "models" ]:
145
- with Path (rst_namespace_template .format (namespace , module )).open ("w" ) as rst_file :
146
- rst_file .write (
147
- SUBMODULE_TEMPLATE .format (
148
- title = make_title (namespace + "." + module + " module" ), namespace = namespace , submodule = module
149
- )
122
+ for module in ["operations" , "models" ]:
123
+ with Path (rst_namespace_template .format (version , module )).open ("w" ) as rst_file :
124
+ rst_file .write (
125
+ SUBMODULE_TEMPLATE .format (
126
+ title = make_title (version + "." + module + " module" ), namespace = version , submodule = module
150
127
)
128
+ )
129
+ package_list_path .append (rst_path )
151
130
152
- for multiapi_namespace in MULTIAPI_VERSION_NAMESPACE :
153
- length = len (multiapi_namespace .split ("." ))
154
- if namespace .split ("." )[0 :length ] == multiapi_namespace .split ("." )[0 :length ]:
155
- _LOGGER .info ("MultiAPI namespace on %s" , multiapi_namespace )
156
- api_package = namespace .split (multiapi_namespace + "." )[1 ]
157
- multiapi_found_apiversion .setdefault (multiapi_namespace , []).append (api_package )
158
- break
159
- else :
160
- package_list_path .append (rst_path )
161
131
162
- for multiapi_namespace , apilist in multiapi_found_apiversion .items ():
163
- apilist .sort ()
164
- apilist .reverse ()
165
- rst_path = rst_path_template .format (multiapi_namespace )
166
- with Path (rst_path ).open ("w" ) as rst_file :
167
- rst_file .write (
168
- MULTIAPI_VERSION_PACKAGE_TEMPLATE .format (
169
- title = make_title (multiapi_namespace + " package" ), namespace = multiapi_namespace
170
- )
132
+ def write_multiapi_rst (namespace : str , versions : List [str ], rst_path_template : str , package_list_path : List [str ]) -> None :
133
+ rst_path = rst_path_template .format (namespace )
134
+ with Path (rst_path ).open ("w" ) as rst_file :
135
+ rst_file .write (
136
+ MULTIAPI_VERSION_PACKAGE_TEMPLATE .format (
137
+ title = make_title (namespace + " package" ), namespace = namespace
171
138
)
172
- for version in apilist :
173
- rst_file .write (" {namespace}.{version}\n " .format (namespace = multiapi_namespace , version = version ))
174
- package_list_path .append (rst_path )
139
+ )
140
+ for version in versions :
141
+ rst_file .write (" {version}\n " .format (version = version ))
142
+ package_list_path .append (rst_path )
175
143
176
- # now handle the packages from data plane that we want to be present properly sorted in the list of packages
177
- for package in config .keys ():
178
- if "manually_generated" in config [package ] and config [package ]["manually_generated" ] == True :
179
- package_list_path .append (rst_path_template .format (package .replace ("-" , "." )))
180
144
145
+ def write_toc_tree (package_list_path : List [str ]) -> None :
181
146
package_list_path .sort ()
182
147
with Path (GENERATED_PACKAGES_LIST_FILE ).open ("w" ) as generate_file_list_fd :
183
148
lines_to_write = "\n " .join ([" " + package for package in package_list_path ])
184
149
generate_file_list_fd .write (RST_AUTODOC_TOCTREE .format (generated_packages = lines_to_write ))
185
150
186
151
152
+ def generate_doc (output_directory : str = "./ref/" , package_root : str = None ) -> None :
153
+ # we are handed a directory that looks like <path-to-repo>/sdk/containerservice/azure-mgmt-containerservice/
154
+ rst_path_template = os .path .join (output_directory , "{}.rst" )
155
+ rst_namespace_template = os .path .join (output_directory , "{}.{}.rst" )
156
+
157
+ namespaces = get_package_namespaces (package_root )
158
+
159
+ package_list_path = []
160
+
161
+ for namespace , multi_api_versions in namespaces .items ():
162
+ _LOGGER .info ("Working on %s" , namespace )
163
+ if not multi_api_versions :
164
+ write_rst (namespace , rst_path_template , rst_namespace_template , package_list_path )
165
+ continue
166
+
167
+ multi_api_versions .sort (reverse = True )
168
+ write_multiapi_rst (namespace , multi_api_versions , rst_path_template , package_list_path )
169
+
170
+ for version in multi_api_versions :
171
+ if is_subnamespace (version .split ("." )[- 1 ]):
172
+ # subnamespace already handled in write_multiapi_rst
173
+ continue
174
+ _LOGGER .info ("Working on %s" , version )
175
+ write_rst (version , rst_path_template , rst_namespace_template , package_list_path )
176
+
177
+ write_toc_tree (package_list_path )
178
+
179
+
187
180
def main ():
188
181
parser = argparse .ArgumentParser (description = "Generate sphinx api stubs for one or multiple management packages." )
189
182
parser .add_argument (
@@ -192,13 +185,6 @@ def main():
192
185
dest = "project" ,
193
186
help = "Want to target a specific management package? Pass the targeted package root to this argument." ,
194
187
)
195
- parser .add_argument (
196
- "--config" ,
197
- "-c" ,
198
- dest = "config_path" ,
199
- default = CONFIG_FILE ,
200
- help = "The JSON configuration format path [default: %(default)s]" ,
201
- )
202
188
parser .add_argument ("-v" , "--verbose" , dest = "verbose" , action = "store_true" , help = "Verbosity in INFO mode" )
203
189
parser .add_argument ("--debug" , dest = "debug" , action = "store_true" , help = "Verbosity in DEBUG mode" )
204
190
parser .add_argument (
@@ -212,7 +198,7 @@ def main():
212
198
logging .basicConfig ()
213
199
main_logger .setLevel (logging .DEBUG if args .debug else logging .INFO )
214
200
215
- generate_doc (args .config_path , args . output_directory , args .project )
201
+ generate_doc (args .output_directory , args .project )
216
202
217
203
218
204
if __name__ == "__main__" :
0 commit comments