esp-docs 2.3.0__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. {esp_docs-2.3.0 → esp_docs-2.5.0}/PKG-INFO +1 -1
  2. {esp_docs-2.3.0 → esp_docs-2.5.0}/pyproject.toml +1 -1
  3. {esp_docs-2.3.0 → esp_docs-2.5.0}/setup.cfg +1 -1
  4. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/build_docs.py +7 -0
  5. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/conf_docs.py +1 -0
  6. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/run_doxygen.py +23 -12
  7. esp_docs-2.5.0/src/esp_docs/modified_files.py +53 -0
  8. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/upload_docs_s3.py +74 -9
  9. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/PKG-INFO +1 -1
  10. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/SOURCES.txt +1 -0
  11. {esp_docs-2.3.0 → esp_docs-2.5.0}/README.md +0 -0
  12. {esp_docs-2.3.0 → esp_docs-2.5.0}/setup.py +0 -0
  13. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/__init__.py +0 -0
  14. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/DejaVuSans.ttf +0 -0
  15. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/NotoSansSC-Regular.otf +0 -0
  16. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/espressif-logo.svg +0 -0
  17. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/espressif2.pdf +0 -0
  18. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/hover_api.css +0 -0
  19. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/hover_api.js +0 -0
  20. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/_static/theme_overrides.css +0 -0
  21. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/check_docs.py +0 -0
  22. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/check_lang_switch.py +0 -0
  23. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/constants.py +0 -0
  24. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/deploy_docs.py +0 -0
  25. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/deploy_docs_s3.py +0 -0
  26. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/__init__.py +0 -0
  27. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/add_html_zip.py +0 -0
  28. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/dummy_build_system/__init__.py +0 -0
  29. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/exclude_docs.py +0 -0
  30. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/format_esp_target.py +0 -0
  31. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/include_build_file.py +0 -0
  32. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/latex_builder.py +0 -0
  33. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/esp_extensions/link_roles.py +0 -0
  34. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/fonts/DejaVuSans.ttf +0 -0
  35. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/fonts/NotoSansSC-Regular.otf +0 -0
  36. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/__init__.py +0 -0
  37. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/add_warnings.py +0 -0
  38. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/google_analytics.py +0 -0
  39. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/hover_api.py +0 -0
  40. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/html_redirects.py +0 -0
  41. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/list_filter.py +0 -0
  42. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/generic_extensions/toctree_filter.py +0 -0
  43. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/get_github_rev.py +0 -0
  44. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/__init__.py +0 -0
  45. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/build_system/CMakeLists.txt +0 -0
  46. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/build_system/__init__.py +0 -0
  47. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/esp_err_definitions.py +0 -0
  48. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/gen_defines.py +0 -0
  49. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/gen_idf_tools_links.py +0 -0
  50. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/gen_toolchain_links.py +0 -0
  51. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/gen_version_specific_includes.py +0 -0
  52. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/idf_extensions/kconfig_reference.py +0 -0
  53. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/latex_templates/espidf.sty +0 -0
  54. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/latex_templates/preamble.tex +0 -0
  55. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/latex_templates/titlepage.tex +0 -0
  56. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/sanitize_version.py +0 -0
  57. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/util/__init__.py +0 -0
  58. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/util/util.py +0 -0
  59. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/__init__.py +0 -0
  60. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/builder.py +0 -0
  61. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/command.py +0 -0
  62. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/drawer.py +0 -0
  63. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/elements.py +0 -0
  64. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/__init__.py +0 -0
  65. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/base.py +0 -0
  66. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/filters/__init__.py +0 -0
  67. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/filters/linejump.py +0 -0
  68. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/pdf.py +0 -0
  69. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/png.py +0 -0
  70. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/simplesvg.py +0 -0
  71. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/svg.py +0 -0
  72. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/textfolder.py +0 -0
  73. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/utils/__init__.py +0 -0
  74. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/imagedraw/utils/ellipse.py +0 -0
  75. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/metrics.py +0 -0
  76. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/__init__.py +0 -0
  77. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/actor.py +0 -0
  78. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/base.py +0 -0
  79. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/beginpoint.py +0 -0
  80. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/box.py +0 -0
  81. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/circle.py +0 -0
  82. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/cloud.py +0 -0
  83. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/diamond.py +0 -0
  84. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/dots.py +0 -0
  85. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/ellipse.py +0 -0
  86. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/endpoint.py +0 -0
  87. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/__init__.py +0 -0
  88. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/database.py +0 -0
  89. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/input.py +0 -0
  90. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/loopin.py +0 -0
  91. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/loopout.py +0 -0
  92. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/flowchart/terminator.py +0 -0
  93. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/mail.py +0 -0
  94. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/minidiamond.py +0 -0
  95. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/none.py +0 -0
  96. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/note.py +0 -0
  97. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/roundedbox.py +0 -0
  98. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/square.py +0 -0
  99. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/noderenderer/textbox.py +0 -0
  100. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/parser.py +0 -0
  101. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/plugins/__init__.py +0 -0
  102. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/plugins/attributes.py +0 -0
  103. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/plugins/autoclass.py +0 -0
  104. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/__init__.py +0 -0
  105. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/bootstrap.py +0 -0
  106. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/compat.py +0 -0
  107. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/config.py +0 -0
  108. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/fontmap.py +0 -0
  109. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/images.py +0 -0
  110. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/logging.py +0 -0
  111. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/myitertools.py +0 -0
  112. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/rst/__init__.py +0 -0
  113. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/rst/directives.py +0 -0
  114. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/rst/nodes.py +0 -0
  115. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/urlutil.py +0 -0
  116. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs/vendor/blockdiag/utils/uuid.py +0 -0
  117. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/dependency_links.txt +0 -0
  118. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/entry_points.txt +0 -0
  119. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/requires.txt +0 -0
  120. {esp_docs-2.3.0 → esp_docs-2.5.0}/src/esp_docs.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: esp-docs
3
- Version: 2.3.0
3
+ Version: 2.5.0
4
4
  Summary: Documentation building package used at Espressif
5
5
  Home-page: https://github.com/espressif/esp-docs
6
6
  Author: Espressif
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [tool.commitizen]
9
9
  name = "cz_conventional_commits"
10
- version = "2.3.0"
10
+ version = "2.5.0"
11
11
  tag_format = "v$version"
12
12
  version_files = [
13
13
  "setup.cfg:version",
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = esp-docs
3
- version = 2.3.0
3
+ version = 2.5.0
4
4
  author = Espressif
5
5
  author_email = marius.vikhammer@espressif.com
6
6
  description = Documentation building package used at Espressif
@@ -26,6 +26,7 @@
26
26
  from __future__ import print_function
27
27
 
28
28
  import argparse
29
+ import json
29
30
  import locale
30
31
  import math
31
32
  import multiprocessing
@@ -36,6 +37,7 @@ import subprocess
36
37
  import sys
37
38
  from pathlib import Path
38
39
  from .check_docs import check_docs, format_path_for_display, style_text
40
+ from .modified_files import parse_modified_files_arg
39
41
  from .check_lang_switch import run_lang_linkcheck
40
42
  from esp_docs.constants import TARGETS
41
43
 
@@ -89,6 +91,8 @@ def main():
89
91
  parser.add_argument('--input-docs', '-i', nargs='+', default=[''],
90
92
  help='List of documents to build relative to the doc base folder, i.e. the language folder. Defaults to all documents')
91
93
  parser.add_argument('--fast-build', '-f', action='store_true', help='Skips including doxygen generated APIs into the Sphinx build')
94
+ parser.add_argument('--modified-files', nargs='+', default=[],
95
+ help='List of modified files relative to the project path, used by smart build logic')
92
96
  parser.add_argument('--skip-reqs-check', action='store_true', help='Skips checking python requirements.txt found in the current directory (deprecated)')
93
97
 
94
98
  action_parsers = parser.add_subparsers(dest='action')
@@ -103,6 +107,7 @@ def main():
103
107
  action_parsers.add_parser('lang-linkcheck', help='Check if link_to_translation directives are present in RST files included in toctrees')
104
108
 
105
109
  args = parser.parse_args()
110
+ args.modified_files = parse_modified_files_arg(args.modified_files)
106
111
 
107
112
  global languages
108
113
  if args.language is None:
@@ -183,6 +188,7 @@ def parallel_call(args, callback):
183
188
  build_info['builders'] = args.builders
184
189
  build_info['input_docs'] = args.input_docs
185
190
  build_info['doxyfile_dir'] = args.doxyfile_dir
191
+ build_info['modified_files'] = args.modified_files
186
192
  build_info['project_path'] = args.project_path
187
193
 
188
194
  entries.append(build_info)
@@ -225,6 +231,7 @@ def sphinx_call(build_info, builder):
225
231
  environ = {}
226
232
  environ.update(os.environ)
227
233
  environ['BUILDDIR'] = build_info['build_dir']
234
+ environ['DOCS_MODIFIED_FILES'] = json.dumps(build_info['modified_files'])
228
235
 
229
236
  args = [sys.executable, '-u', '-m', 'sphinx.cmd.build',
230
237
  '-j', str(build_info['sphinx_parallel_jobs']),
@@ -325,6 +325,7 @@ def setup(app):
325
325
  app.add_config_value('docs_to_build', None, 'env')
326
326
  app.add_config_value('user_setup_callback', None, 'env')
327
327
  app.add_config_value('doc_id', None, 'env')
328
+ app.add_config_value('modified_files', os.environ.get('DOCS_MODIFIED_FILES', '[]'), 'env')
328
329
 
329
330
  # Breathe extension variables (depend on build_dir)
330
331
  # note: we generate into xml_in and then copy_if_modified to xml dir
@@ -9,6 +9,7 @@ from io import open
9
9
  from collections import defaultdict
10
10
  from dataclasses import dataclass
11
11
 
12
+ from ..modified_files import get_modified_files, normalize_modified_file_path
12
13
  from ..util.util import copy_if_modified
13
14
 
14
15
  ALL_KINDS = [
@@ -52,6 +53,16 @@ def find_doxygen_dir(doxyfile_dir):
52
53
  return doxyfile_dir
53
54
 
54
55
 
56
+ def should_keep_api_reference(header_path, modified_files, fast_build):
57
+ if not fast_build:
58
+ return True
59
+
60
+ if not modified_files:
61
+ return False
62
+
63
+ return normalize_modified_file_path(header_path) in modified_files
64
+
65
+
55
66
  def generate_doxygen(app, defines):
56
67
 
57
68
  build_dir = app.config.build_dir
@@ -150,6 +161,7 @@ def convert_api_xml_to_inc(app, doxyfiles):
150
161
  inc_directory_path = '{}/inc'.format(build_dir)
151
162
 
152
163
  fast_build = os.environ.get('DOCS_FAST_BUILD', None)
164
+ modified_files = get_modified_files(app.config)
153
165
 
154
166
  if not os.path.isdir(xml_directory_path):
155
167
  raise RuntimeError('Directory {} does not exist!'.format(xml_directory_path))
@@ -161,28 +173,27 @@ def convert_api_xml_to_inc(app, doxyfiles):
161
173
 
162
174
  print("Generating 'api_name.inc' files with Doxygen directives")
163
175
  for api_path in api_paths:
164
- rst_output = generate_directives(app, api_path.header_path, api_path.xml_file_path)
176
+ final_rst_output = generate_directives(app, api_path.header_path, api_path.xml_file_path)
177
+
178
+ # For fast builds we skip unchanged API reference includes, but still keep
179
+ # the ones generated from modified headers.
180
+ if not should_keep_api_reference(api_path.header_path, modified_files, fast_build):
181
+ final_rst_output = ''
165
182
 
166
183
  # Create subfolders if needed
167
184
  dir_name = os.path.dirname(api_path.inc_file_path)
168
185
  if dir_name:
169
186
  os.makedirs(dir_name, exist_ok=True)
170
187
 
188
+ inc_exists = os.path.isfile(api_path.inc_file_path)
171
189
  previous_rst_output = ''
172
- if os.path.isfile(api_path.inc_file_path):
190
+ if inc_exists:
173
191
  with open(api_path.inc_file_path, 'r', encoding='utf-8') as inc_file_old:
174
192
  previous_rst_output = inc_file_old.read()
175
193
 
176
- if previous_rst_output != rst_output:
177
- with open(api_path.inc_file_path, 'w', encoding='utf-8') as inc_file:
178
- inc_file.write(rst_output)
179
-
180
- # For fast builds we wipe the doxygen api documentation.
181
- # Parsing this output during the sphinx build process is
182
- # what takes 95% of the build time
183
- if fast_build:
194
+ if (not inc_exists) or previous_rst_output != final_rst_output:
184
195
  with open(api_path.inc_file_path, 'w', encoding='utf-8') as inc_file:
185
- inc_file.write('')
196
+ inc_file.write(final_rst_output)
186
197
 
187
198
 
188
199
  def get_doxyfile_input_paths(app, doxyfile_path):
@@ -215,7 +226,7 @@ def get_doxyfile_input_paths(app, doxyfile_path):
215
226
  # process only lines that are not comments
216
227
  if line.find('#') == -1:
217
228
  # extract header file path inside project folder
218
- m = re.search('\(PROJECT_PATH\)/(.*\.hp*)', line) # noqa: W605 - regular expression
229
+ m = re.search(r'\(PROJECT_PATH\)/(.*\.hp*)', line)
219
230
  if m is None:
220
231
  raise ValueError("Doxygen input statements should be specified using $(PROJECT_PATH) env variable, instead got {}".format(line))
221
232
  header_file_path = m.group(1)
@@ -0,0 +1,53 @@
1
+ from __future__ import unicode_literals
2
+
3
+ import json
4
+ import os
5
+
6
+
7
+ def parse_modified_files_arg(modified_files):
8
+ if not modified_files:
9
+ return []
10
+
11
+ normalized_paths = []
12
+ for value in modified_files:
13
+ if not value:
14
+ continue
15
+
16
+ normalized_paths.extend(
17
+ path for path in value.split(';') if path
18
+ )
19
+
20
+ return normalized_paths
21
+
22
+
23
+ def normalize_modified_file_path(file_path, project_path=None):
24
+ normalized_path = file_path
25
+
26
+ if project_path and os.path.isabs(normalized_path):
27
+ normalized_path = os.path.relpath(normalized_path, project_path)
28
+
29
+ normalized_path = os.path.normpath(normalized_path).replace('\\', '/')
30
+
31
+ if normalized_path == '.':
32
+ return ''
33
+
34
+ while normalized_path.startswith('./'):
35
+ normalized_path = normalized_path[2:]
36
+
37
+ return normalized_path
38
+
39
+
40
+ def get_modified_files(config):
41
+ modified_files = config.modified_files
42
+
43
+ if not modified_files:
44
+ return set()
45
+
46
+ if isinstance(modified_files, str):
47
+ modified_files = json.loads(modified_files)
48
+
49
+ return {
50
+ normalize_modified_file_path(path, config.project_path)
51
+ for path in modified_files
52
+ if path
53
+ }
@@ -53,10 +53,14 @@ Optional environment variables
53
53
  """
54
54
 
55
55
  import glob
56
+ import functools
56
57
  import mimetypes
57
58
  import os
58
59
  import os.path
59
60
  import shutil
61
+ import time
62
+ from concurrent.futures import ThreadPoolExecutor, as_completed
63
+ from urllib.parse import quote
60
64
 
61
65
  import boto3
62
66
  from botocore.config import Config
@@ -65,6 +69,23 @@ from .util.util import is_stable_version, env
65
69
  from .sanitize_version import sanitize_version # noqa
66
70
 
67
71
 
72
+ def print_timing(label, started_at):
73
+ elapsed = time.perf_counter() - started_at
74
+ print(f'[timing] {label} took {elapsed:.3f}s', flush=True)
75
+
76
+
77
+ def timed(func):
78
+ @functools.wraps(func)
79
+ def wrapper(*args, **kwargs):
80
+ started_at = time.perf_counter()
81
+ try:
82
+ return func(*args, **kwargs)
83
+ finally:
84
+ print_timing(func.__name__, started_at)
85
+
86
+ return wrapper
87
+
88
+
68
89
  class S3Config:
69
90
  alias = 'deploy-docs-s3'
70
91
  access_key: str = env('DOCS_S3_ACCESS_KEY_ID')
@@ -82,6 +103,7 @@ class S3Config:
82
103
  )
83
104
 
84
105
 
106
+ @timed
85
107
  def main():
86
108
  # if you get KeyErrors on the following lines, it's probably because you're not running in Gitlab CI
87
109
  git_ver = env('GIT_VER') # output of git describe --always
@@ -102,7 +124,9 @@ def main():
102
124
  docs_path = f'{commit_sha}/{S3Config.docs_path}'
103
125
 
104
126
  tmp_path = copy_docs_to_tmp_folder(version, build_dir)
105
- upload(tmp_path, docs_path)
127
+ uploaded_url = upload(tmp_path, docs_path)
128
+ if uploaded_url:
129
+ print(f'Docs uploaded. Example file: {uploaded_url}')
106
130
 
107
131
  # note: it would be neater to use symlinks for stable, but because of the directory order
108
132
  # (language first) it's kind of a pain to do on a remote server, so we just repeat the
@@ -111,34 +135,75 @@ def main():
111
135
  if is_stable_version(version) and do_deploy_stable:
112
136
  print('Deploying again as stable version...')
113
137
  tmp_path = copy_docs_to_tmp_folder('stable', build_dir)
114
- upload(tmp_path, docs_path)
138
+ uploaded_url = upload(tmp_path, docs_path)
139
+ if uploaded_url:
140
+ print(f'Stable docs uploaded. Example file: {uploaded_url}')
115
141
 
116
142
 
117
143
  def _upload_one(local_path, key_name):
144
+ started_at = time.perf_counter()
118
145
  content_type, encoding = mimetypes.guess_type(local_path)
119
146
 
120
147
  extra_args = {}
121
148
  if content_type:
122
149
  extra_args['ContentType'] = content_type
123
150
 
124
- S3Config.s3.upload_file(
125
- local_path,
126
- S3Config.bucket_name,
127
- key_name,
128
- ExtraArgs=extra_args if extra_args else None,
129
- )
151
+ try:
152
+ S3Config.s3.upload_file(
153
+ local_path,
154
+ S3Config.bucket_name,
155
+ key_name,
156
+ ExtraArgs=extra_args if extra_args else None,
157
+ )
158
+ finally:
159
+ print_timing(f'_upload_one: {local_path}', started_at)
130
160
 
131
161
 
162
+ @timed
132
163
  def upload(source_dir, remote_dir):
133
164
  prefix = remote_dir.strip('/')
165
+ example_key_name = None
166
+ upload_jobs = []
167
+
134
168
  for root, _, files in os.walk(source_dir):
135
169
  for filename in files:
136
170
  local_path = str(os.path.join(root, filename))
137
171
  rel_path = os.path.relpath(local_path, source_dir).replace(os.sep, '/')
138
172
  key_name = f'{prefix}/{rel_path}'
139
- _upload_one(local_path, key_name)
173
+ upload_jobs.append((local_path, key_name))
174
+
175
+ if filename == 'index.html' and example_key_name is None:
176
+ example_key_name = key_name
177
+
178
+ if not upload_jobs:
179
+ return build_s3_file_url(example_key_name) if example_key_name else None
180
+
181
+ max_workers = max(1, int(os.getenv('DOCS_S3_UPLOAD_WORKERS', 16)))
182
+ print(f'Uploading {len(upload_jobs)} files with {max_workers} workers...')
183
+
184
+ with ThreadPoolExecutor(max_workers=max_workers) as executor:
185
+ futures = [
186
+ executor.submit(_upload_one, local_path, key_name)
187
+ for local_path, key_name in upload_jobs
188
+ ]
189
+ try:
190
+ for future in as_completed(futures):
191
+ future.result()
192
+ except Exception:
193
+ for future in futures:
194
+ future.cancel()
195
+ raise
196
+
197
+ return build_s3_file_url(example_key_name) if example_key_name else None
198
+
199
+
200
+ def build_s3_file_url(key_name):
201
+ key_path = quote(key_name.lstrip('/'), safe='/')
202
+ endpoint = S3Config.endpoint.removesuffix('/')
203
+ return f'{endpoint.replace("://", f"://{S3Config.bucket_name}.", 1)}/{key_path}'
140
204
 
141
205
 
206
+ @timed
142
207
  def copy_docs_to_tmp_folder(version, build_dir):
143
208
  """Copy all docs to a tmp folder, maintaining the directory structure used to deploy as
144
209
  the given version"""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: esp-docs
3
- Version: 2.3.0
3
+ Version: 2.5.0
4
4
  Summary: Documentation building package used at Espressif
5
5
  Home-page: https://github.com/espressif/esp-docs
6
6
  Author: Espressif
@@ -11,6 +11,7 @@ src/esp_docs/constants.py
11
11
  src/esp_docs/deploy_docs.py
12
12
  src/esp_docs/deploy_docs_s3.py
13
13
  src/esp_docs/get_github_rev.py
14
+ src/esp_docs/modified_files.py
14
15
  src/esp_docs/sanitize_version.py
15
16
  src/esp_docs/upload_docs_s3.py
16
17
  src/esp_docs.egg-info/PKG-INFO
File without changes
File without changes