3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from os import walk, listdir
18 from os.path import isfile, isdir, join, getsize
20 # Temporary working directory. It is created and deleted by run_doc.sh
23 # Directory with resources to be documented.
24 RESOURCES_DIR = "resources"
26 # Directory with libraries (python, robot) to be documented.
29 # Directory with tests (func, perf) to be documented.
35 PATH_PY_LIBS = join(WORKING_DIR, RESOURCES_DIR, LIB_DIR, "python")
36 PATH_RF_LIBS = join(WORKING_DIR, RESOURCES_DIR, LIB_DIR, "robot")
37 PATH_TESTS = join(WORKING_DIR, TESTS_DIR)
39 # Sections in rst files
62 def get_files(path, extension):
63 """Generates the list of files to process.
65 :param path: Path to files.
66 :param extension: Extension of files to process. If it is the empty string,
67 all files will be processed.
70 :returns: List of files to process.
75 for root, dirs, files in walk(path):
76 for filename in files:
78 if filename.endswith(extension):
79 file_list.append(join(root, filename))
81 file_list.append(join(root, filename))
86 def create_file_name(path, start):
87 """Create the name of rst file.
90 resources.libraries.python.honeycomb.rst
93 :param path: Path to a module to be documented.
94 :param start: The first directory in path which is used in the file name.
100 dir_list = path.split('/')
101 start_index = dir_list.index(start)
102 return ".".join(dir_list[start_index:-1]) + ".rst"
105 def create_rst_file_names_set(files, start):
106 """Generate a set of unique rst file names.
108 :param files: List of all files to be documented with path beginning in the
110 :param start: The first directory in path which is used in the file name.
113 :returns: Set of unique rst file names.
118 file_names.add(create_file_name(file, start))
123 """Create a list of files and directories in the given directory.
125 :param path: Path to the directory.
127 :returns: List of directories and list of files sorted in alphabetical
129 :rtype: tuple of two lists
133 items = listdir(path)
135 if isfile(join(path, item)) and "__init__" not in item:
137 elif isdir(join(path, item)):
139 return sorted(dirs), sorted(files)
142 def write_toc(fh, path, dirs):
143 """Write a table of contents to given rst file.
145 :param fh: File handler of the rst file.
146 :param path: Path to package.
147 :param dirs: List of directories to be included in ToC.
154 fh.write(" {}.{}\n".format('.'.join(path), dir))
157 def write_module_title(fh, module_name):
158 """Write the module title to the given rst file. The title will be on the
161 :param fh: File handler of the rst file.
162 :param module_name: The name of module used for title.
164 :type module_name: str
166 title = "{} suite".format(module_name)
167 fh.write("\n{}\n{}\n".format(title, '-' * len(title)))
170 def generate_py_rst_files():
171 """Generate all rst files for all python modules."""
173 dirs_ignore_list = ["__pycache__", ]
175 py_libs = get_files(PATH_PY_LIBS, PY_EXT)
176 file_names = create_rst_file_names_set(py_libs, RESOURCES_DIR)
178 for file_name in file_names:
179 path = join(WORKING_DIR, *file_name.split('.')[:-1])
180 dirs, files = scan_dir(path)
182 for item in dirs_ignore_list:
189 full_path = join(WORKING_DIR, file_name)
190 with open(full_path, mode='a') as fh:
191 if getsize(full_path) == 0:
192 package = file_name.split('.')[-2]
193 fh.write("{}\n".format(package))
194 fh.write('=' * len("{}".format(package)))
195 module_path = file_name.split('.')[:-1]
197 write_toc(fh, module_path, dirs)
199 module_name = file.split('.')[0]
200 write_module_title(fh, module_name)
201 fh.write(rst_py_module.format('.'.join(module_path),
205 def generate_rf_rst_files(file_names, incl_tests=True, incl_keywords=True):
206 """Generate rst files for the given robot modules.
208 :param file_names: List of file names to be included in the documentation
210 :param incl_tests: If true, tests will be included in the documentation.
211 :param incl_keywords: If true, keywords will be included in the
213 :type file_names: set
214 :type incl_tests: bool
215 :type incl_keywords: bool
218 for file_name in file_names:
219 path = join(WORKING_DIR, *file_name.split('.')[:-1])
220 dirs, files = scan_dir(path)
222 full_path = join(WORKING_DIR, file_name)
223 with open(full_path, mode='a') as fh:
224 if getsize(full_path) == 0:
225 package = file_name.split('.')[-2]
226 fh.write("{}\n".format(package))
227 fh.write('=' * len("{}".format(package)) + '\n')
228 module_path = file_name.split('.')[:-1]
230 write_toc(fh, module_path, dirs)
232 module_name = file.split('.')[0]
233 write_module_title(fh, module_name)
234 path = join(join(*module_path), module_name + RF_EXT)
236 fh.write(rst_rf_tests.format(path))
238 fh.write(rst_rf_keywords.format(path))
241 def generate_kw_rst_files():
242 """Generate all rst files for all robot modules with keywords in libraries
243 directory (no tests)."""
245 rf_libs = get_files(PATH_RF_LIBS, RF_EXT)
246 file_names = create_rst_file_names_set(rf_libs, RESOURCES_DIR)
248 generate_rf_rst_files(file_names, incl_tests=False)
251 def generate_tests_rst_files():
252 """Generate all rst files for all robot modules with tests in tests
253 directory. Include also keywords defined in these modules."""
255 tests = get_files(PATH_TESTS, RF_EXT)
256 file_names = create_rst_file_names_set(tests, TESTS_DIR)
258 generate_rf_rst_files(file_names)
261 if __name__ == '__main__':
263 # Generate all rst files:
264 generate_py_rst_files()
265 generate_kw_rst_files()
266 generate_tests_rst_files()