1 # Copyright (c) 2018 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
15 from os import walk, listdir
16 from os.path import isfile, isdir, join, getsize
18 # Temporary working directory. It is created and deleted by run_doc.sh
21 # Directory with resources to be documented.
22 RESOURCES_DIR = u"resources"
24 # Directory with libraries (python, robot) to be documented.
25 LIB_DIR = u"libraries"
27 # Directory with tests (func, perf) to be documented.
33 PATH_PY_LIBS = join(WORKING_DIR, RESOURCES_DIR, LIB_DIR, u"python")
34 PATH_RF_LIBS = join(WORKING_DIR, RESOURCES_DIR, LIB_DIR, u"robot")
35 PATH_TESTS = join(WORKING_DIR, TESTS_DIR)
37 # Sections in rst files
49 rst_rf_suite_setup = u"""
54 rst_rf_variables = u"""
59 rst_rf_keywords = u"""
70 def get_files(path, extension):
71 """Generates the list of files to process.
73 :param path: Path to files.
74 :param extension: Extension of files to process. If it is the empty string,
75 all files will be processed.
78 :returns: List of files to process.
83 for root, dirs, files in walk(path):
84 for filename in files:
86 if filename.endswith(extension):
87 file_list.append(join(root, filename))
89 file_list.append(join(root, filename))
94 def create_file_name(path, start):
95 """Create the name of rst file.
100 :param path: Path to a module to be documented.
101 :param start: The first directory in path which is used in the file name.
107 dir_list = path.split(u"/")
108 start_index = dir_list.index(start)
109 return u".".join(dir_list[start_index:-1]) + u".rst"
112 def create_rst_file_names_set(files, start):
113 """Generate a set of unique rst file names.
115 :param files: List of all files to be documented with path beginning in the
117 :param start: The first directory in path which is used in the file name.
120 :returns: Set of unique rst file names.
125 file_names.add(create_file_name(file, start))
130 """Create a list of files and directories in the given directory.
132 :param path: Path to the directory.
134 :returns: List of directories and list of files sorted in alphabetical
136 :rtype: tuple of two lists
140 items = listdir(path)
142 if isfile(join(path, item)) and u"__init__" not in item:
144 elif isdir(join(path, item)):
146 return sorted(dirs), sorted(files)
149 def write_toc(fh, path, dirs):
150 """Write a table of contents to given rst file.
152 :param fh: File handler of the rst file.
153 :param path: Path to package.
154 :param dirs: List of directories to be included in ToC.
161 fh.write(f" {u'.'.join(path)}.{dir}\n")
164 def write_module_title(fh, module_name):
165 """Write the module title to the given rst file. The title will be on the
168 :param fh: File handler of the rst file.
169 :param module_name: The name of module used for title.
171 :type module_name: str
173 title = f"{module_name} suite"
174 fh.write(f"\n{title}\n{u'-' * len(title)}")
177 def generate_py_rst_files():
178 """Generate all rst files for all python modules."""
180 dirs_ignore_list = [u"__pycache__", ]
182 py_libs = get_files(PATH_PY_LIBS, PY_EXT)
183 file_names = create_rst_file_names_set(py_libs, RESOURCES_DIR)
185 for file_name in file_names:
186 path = join(WORKING_DIR, *file_name.split(u".")[:-1])
187 dirs, files = scan_dir(path)
189 for item in dirs_ignore_list:
196 full_path = join(WORKING_DIR, file_name)
197 with open(full_path, mode="a") as fh:
198 if getsize(full_path) == 0:
199 package = file_name.split(u".")[-2]
200 fh.write(f"{package}\n")
201 fh.write(u"=" * len(f"{package}"))
202 module_path = file_name.split(u".")[:-1]
204 write_toc(fh, module_path, dirs)
206 module_name = file.split(u".")[0]
207 write_module_title(fh, module_name)
208 fh.write(rst_py_module.format(
209 u".".join(module_path), module_name)
213 def generate_rf_rst_files(
214 file_names, incl_tests=True, incl_keywords=True, incl_suite_setup=False,
215 incl_variables=False):
216 """Generate rst files for the given robot modules.
218 :param file_names: List of file names to be included in the documentation
220 :param incl_tests: If True, tests will be included in the documentation.
221 :param incl_keywords: If True, keywords will be included in the
223 :param incl_suite_setup: If True, the suite setup will be included in the
225 :param incl_variables: If True, the variables will be included in the
227 :type file_names: set
228 :type incl_tests: bool
229 :type incl_keywords: bool
230 :type incl_suite_setup: bool
231 :type incl_variables: bool
234 for file_name in file_names:
235 path = join(WORKING_DIR, *file_name.split(u".")[:-1])
236 dirs, files = scan_dir(path)
238 full_path = join(WORKING_DIR, file_name)
239 with open(full_path, mode="a") as fh:
240 if getsize(full_path) == 0:
241 package = file_name.split(u".")[-2]
242 fh.write(f"{package}\n")
243 fh.write(u"=" * len(f"{package}") + u"\n")
244 module_path = file_name.split(u".")[:-1]
246 write_toc(fh, module_path, dirs)
248 module_name = file.split(u".")[0]
249 write_module_title(fh, module_name)
250 path = join(join(*module_path), module_name + RF_EXT)
252 fh.write(rst_rf_suite_setup.format(path))
254 fh.write(rst_rf_variables.format(path))
256 fh.write(rst_rf_keywords.format(path))
258 fh.write(rst_rf_tests.format(path))
261 def generate_kw_rst_files():
262 """Generate all rst files for all robot modules with keywords in libraries
263 directory (no tests)."""
265 rf_libs = get_files(PATH_RF_LIBS, RF_EXT)
266 file_names = create_rst_file_names_set(rf_libs, RESOURCES_DIR)
268 generate_rf_rst_files(file_names, incl_tests=False)
271 def generate_tests_rst_files():
272 """Generate all rst files for all robot modules with tests in tests
273 directory. Include also keywords defined in these modules."""
275 tests = get_files(PATH_TESTS, RF_EXT)
276 file_names = create_rst_file_names_set(tests, TESTS_DIR)
278 generate_rf_rst_files(
279 file_names, incl_suite_setup=True, incl_variables=True
283 if __name__ == u"__main__":
285 # Generate all rst files:
286 generate_py_rst_files()
287 generate_kw_rst_files()
288 generate_tests_rst_files()