py2docfx 0.1.9.dev1917798__py3-none-any.whl → 0.1.9.dev1927042__py3-none-any.whl
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.
- py2docfx/__main__.py +72 -23
- py2docfx/convert_prepare/conf_templates/conf.py_t +1 -1
- py2docfx/convert_prepare/constants.py +2 -1
- py2docfx/convert_prepare/environment.py +34 -13
- py2docfx/convert_prepare/generate_document.py +12 -5
- py2docfx/convert_prepare/get_source.py +5 -1
- py2docfx/convert_prepare/git.py +24 -20
- py2docfx/convert_prepare/package_info.py +15 -9
- py2docfx/convert_prepare/pip_utils.py +33 -8
- py2docfx/convert_prepare/post_process/merge_toc.py +5 -1
- py2docfx/convert_prepare/sphinx_caller.py +31 -14
- py2docfx/docfx_yaml/build_finished.py +11 -3
- py2docfx/docfx_yaml/convert_class.py +4 -2
- py2docfx/docfx_yaml/convert_enum.py +4 -2
- py2docfx/docfx_yaml/convert_module.py +4 -2
- py2docfx/docfx_yaml/convert_package.py +4 -2
- py2docfx/docfx_yaml/logger.py +141 -0
- py2docfx/docfx_yaml/process_doctree.py +6 -4
- py2docfx/docfx_yaml/translator.py +5 -7
- py2docfx/docfx_yaml/writer.py +10 -4
- py2docfx/docfx_yaml/yaml_builder.py +0 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/build_meta.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_ext.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/build_py.py +9 -14
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/easy_install.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/egg_info.py +3 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/saveopts.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/sdist.py +2 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/command/setopt.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/dist.py +3 -2
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/monkey.py +3 -3
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/msvc.py +11 -11
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
- py2docfx/venv/basevenv/Lib/site-packages/setuptools/unicode_utils.py +3 -3
- py2docfx/venv/basevenv/Lib/site-packages/wheel/__init__.py +1 -1
- py2docfx/venv/basevenv/Lib/site-packages/wheel/cli/convert.py +1 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/__init__.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/algorithms.py +31 -16
- py2docfx/venv/venv1/Lib/site-packages/jwt/api_jws.py +19 -8
- py2docfx/venv/venv1/Lib/site-packages/jwt/api_jwt.py +75 -19
- py2docfx/venv/venv1/Lib/site-packages/jwt/exceptions.py +8 -0
- py2docfx/venv/venv1/Lib/site-packages/jwt/help.py +4 -1
- py2docfx/venv/venv1/Lib/site-packages/jwt/jwks_client.py +4 -2
- py2docfx/venv/venv1/Lib/site-packages/jwt/utils.py +7 -10
- py2docfx/venv/venv1/Lib/site-packages/msal/application.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/msal/managed_identity.py +5 -3
- py2docfx/venv/venv1/Lib/site-packages/setuptools/build_meta.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_egg.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/bdist_wheel.py +25 -39
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_ext.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/build_py.py +9 -14
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/easy_install.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/editable_wheel.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/egg_info.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/install_egg_info.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/saveopts.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/sdist.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/command/setopt.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/setuptools/config/pyprojecttoml.py +0 -13
- py2docfx/venv/venv1/Lib/site-packages/setuptools/dist.py +3 -2
- py2docfx/venv/venv1/Lib/site-packages/setuptools/monkey.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/setuptools/msvc.py +11 -11
- py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/config/test_pyprojecttoml.py +0 -7
- py2docfx/venv/venv1/Lib/site-packages/setuptools/tests/test_core_metadata.py +168 -72
- py2docfx/venv/venv1/Lib/site-packages/setuptools/unicode_utils.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/wheel/__init__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/wheel/cli/convert.py +1 -2
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/METADATA +1 -1
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/RECORD +78 -77
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/WHEEL +1 -1
- /py2docfx/convert_prepare/conf_templates/{master_doc.rst_t → root_doc.rst_t} +0 -0
- {py2docfx-0.1.9.dev1917798.dist-info → py2docfx-0.1.9.dev1927042.dist-info}/top_level.txt +0 -0
py2docfx/__main__.py
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
from __future__ import annotations # Avoid A | B annotation break under <= py3.9
|
2
2
|
import asyncio
|
3
3
|
import argparse
|
4
|
+
import logging
|
4
5
|
import os
|
5
6
|
import sys
|
6
7
|
import shutil
|
7
8
|
|
8
9
|
from py2docfx import PACKAGE_ROOT
|
9
|
-
from py2docfx.
|
10
|
+
from py2docfx.docfx_yaml.logger import get_logger, get_package_logger, get_warning_error_count, output_log_by_log_level
|
11
|
+
from py2docfx.convert_prepare.constants import SOURCE_REPO, TARGET_REPO, DIST_TEMP, LOG_FOLDER
|
10
12
|
from py2docfx.convert_prepare.generate_document import generate_document
|
11
13
|
from py2docfx.convert_prepare.get_source import YAML_OUTPUT_ROOT
|
12
14
|
from py2docfx.convert_prepare.post_process.merge_toc import merge_toc, move_root_toc_to_target
|
@@ -14,11 +16,6 @@ from py2docfx.convert_prepare.params import load_file_params, load_command_param
|
|
14
16
|
from py2docfx.convert_prepare.package_info import PackageInfo
|
15
17
|
import py2docfx.convert_prepare.environment as py2docfxEnvironment
|
16
18
|
|
17
|
-
|
18
|
-
print("Adding yaml extension to path")
|
19
|
-
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),'docfx_yaml'))
|
20
|
-
os.chdir(PACKAGE_ROOT)
|
21
|
-
|
22
19
|
def get_parser() -> argparse.ArgumentParser:
|
23
20
|
parser = argparse.ArgumentParser(
|
24
21
|
description=(
|
@@ -144,26 +141,40 @@ def get_parser() -> argparse.ArgumentParser:
|
|
144
141
|
help="""A list containing relative paths to the root of the package of files/directories
|
145
142
|
excluded when generating documents, should follow fnmatch-style.""",
|
146
143
|
)
|
144
|
+
|
145
|
+
parser.add_argument(
|
146
|
+
"--verbose",
|
147
|
+
action="store_true",
|
148
|
+
help="""Increase output verbosity. Cannot be used together with --show-warning""",
|
149
|
+
)
|
150
|
+
|
151
|
+
parser.add_argument(
|
152
|
+
"--show-warning",
|
153
|
+
action="store_true",
|
154
|
+
help="""Show warning message. Cannot be used together with --verbose""",
|
155
|
+
)
|
147
156
|
return parser
|
148
157
|
|
149
158
|
|
150
159
|
def parse_command_line_args(argv) -> (
|
151
|
-
list[PackageInfo], list[PackageInfo], str, str, str | os.PathLike, bool):
|
160
|
+
list[PackageInfo], list[PackageInfo], str, str, str | os.PathLike, bool, bool):
|
152
161
|
parser = get_parser()
|
153
162
|
args = parser.parse_args(argv)
|
154
163
|
|
155
164
|
github_token = args.github_token
|
156
165
|
ado_token = args.ado_token
|
157
166
|
output_root = args.output_root
|
167
|
+
verbose = args.verbose
|
168
|
+
show_warning = args.show_warning
|
158
169
|
|
159
170
|
if args.param_file_path:
|
160
171
|
(package_info_list, required_packages) = load_file_params(args.param_file_path)
|
161
172
|
return (list(package_info_list), list(required_packages), github_token,
|
162
|
-
ado_token, output_root)
|
173
|
+
ado_token, output_root, verbose, show_warning)
|
163
174
|
elif args.param_json:
|
164
175
|
(package_info_list, required_packages) = load_command_params(args.param_json)
|
165
176
|
return (package_info_list, required_packages, github_token,
|
166
|
-
ado_token, output_root)
|
177
|
+
ado_token, output_root, verbose, show_warning)
|
167
178
|
else:
|
168
179
|
package_info = PackageInfo()
|
169
180
|
if not args.install_type:
|
@@ -194,11 +205,11 @@ def parse_command_line_args(argv) -> (
|
|
194
205
|
package_info.folder = args.folder
|
195
206
|
if not package_info.url:
|
196
207
|
if not package_info.folder:
|
197
|
-
|
198
|
-
|
199
|
-
)
|
208
|
+
msg = "When install_type is source_code, folder or url should be provided"
|
209
|
+
raise ValueError(msg)
|
200
210
|
else:
|
201
|
-
|
211
|
+
msg = f"Read source code from local folder: {package_info.folder}"
|
212
|
+
logging.info(msg)
|
202
213
|
|
203
214
|
if package_info.install_type == PackageInfo.InstallType.DIST_FILE:
|
204
215
|
package_info.location = args.location
|
@@ -208,7 +219,7 @@ def parse_command_line_args(argv) -> (
|
|
208
219
|
"None",
|
209
220
|
condition="When install_type is dist_file",
|
210
221
|
)
|
211
|
-
return ([package_info], [], github_token, ado_token, output_root)
|
222
|
+
return ([package_info], [], github_token, ado_token, output_root, verbose, show_warning)
|
212
223
|
|
213
224
|
async def donwload_package_generate_documents(
|
214
225
|
package_info_list: list[PackageInfo],
|
@@ -229,12 +240,17 @@ async def donwload_package_generate_documents(
|
|
229
240
|
py2docfxEnvironment.prepare_base_venv(required_package_list, github_token, ado_token))
|
230
241
|
|
231
242
|
for idx, package in enumerate(package_info_list):
|
243
|
+
os.environ['PROCESSING_PACKAGE_NAME'] = package.name
|
232
244
|
package_number = start_num + idx
|
233
|
-
|
245
|
+
py2docfx_logger = get_package_logger(__name__)
|
246
|
+
msg = f"Processing package {package.name}, env_prepare_tasks: {len(env_prepare_tasks)}"
|
247
|
+
py2docfx_logger.info(msg)
|
248
|
+
|
234
249
|
try:
|
235
250
|
await env_prepare_tasks[idx]
|
236
251
|
except Exception as e:
|
237
|
-
|
252
|
+
msg = f"Failed to setup venv for package {package.name}: {e}"
|
253
|
+
py2docfx_logger.error(msg)
|
238
254
|
raise
|
239
255
|
|
240
256
|
generate_document(package, output_root,
|
@@ -249,7 +265,10 @@ async def donwload_package_generate_documents(
|
|
249
265
|
|
250
266
|
if idx + py2docfxEnvironment.VENV_BUFFER < len(package_info_list):
|
251
267
|
buffer_package_idx = idx + py2docfxEnvironment.VENV_BUFFER
|
252
|
-
|
268
|
+
|
269
|
+
msg = f"Creating venv {buffer_package_idx}"
|
270
|
+
py2docfx_logger.info(msg)
|
271
|
+
|
253
272
|
env_prepare_tasks.append(
|
254
273
|
asyncio.create_task(py2docfxEnvironment.prepare_venv(buffer_package_idx,
|
255
274
|
package_info_list[buffer_package_idx],
|
@@ -262,7 +281,8 @@ async def donwload_package_generate_documents(
|
|
262
281
|
py2docfxEnvironment.remove_environment(idx-1)))
|
263
282
|
|
264
283
|
if idx > py2docfxEnvironment.VENV_BUFFER and env_remove_tasks[idx-py2docfxEnvironment.VENV_BUFFER] != None:
|
265
|
-
|
284
|
+
msg = f"Removing venv {idx-py2docfxEnvironment.VENV_BUFFER}"
|
285
|
+
py2docfx_logger.info(msg)
|
266
286
|
await env_remove_tasks[idx-py2docfxEnvironment.VENV_BUFFER]
|
267
287
|
|
268
288
|
if output_doc_folder:
|
@@ -295,16 +315,39 @@ def temp_folder_clean_up(folder_list: list[str | os.PathLike]) -> None:
|
|
295
315
|
if os.path.exists(folder):
|
296
316
|
shutil.rmtree(folder)
|
297
317
|
|
298
|
-
def
|
299
|
-
|
300
|
-
|
318
|
+
def decide_global_log_level(verbose: bool, show_warning: bool) -> None:
|
319
|
+
if verbose and show_warning:
|
320
|
+
raise ValueError("Cannot use --verbose and --show-warning at the same time")
|
321
|
+
if verbose:
|
322
|
+
os.environ['LOG_LEVEL'] = 'INFO'
|
323
|
+
return
|
324
|
+
if show_warning:
|
325
|
+
os.environ['LOG_LEVEL'] = 'WARNING'
|
326
|
+
return
|
327
|
+
|
328
|
+
# Default log level
|
329
|
+
os.environ['LOG_LEVEL'] = 'ERROR'
|
301
330
|
|
331
|
+
def main(argv) -> int:
|
302
332
|
# TODO: may need to purge pip cache
|
303
333
|
(package_info_list,
|
304
334
|
required_package_list,
|
305
335
|
github_token, ado_token,
|
306
|
-
output_root
|
336
|
+
output_root, verbose,
|
337
|
+
show_warning) = parse_command_line_args(argv)
|
338
|
+
|
339
|
+
clean_up_folder_list = [py2docfxEnvironment.VENV_DIR, DIST_TEMP, SOURCE_REPO, TARGET_REPO, LOG_FOLDER]
|
340
|
+
temp_folder_clean_up(clean_up_folder_list)
|
307
341
|
|
342
|
+
decide_global_log_level(verbose, show_warning)
|
343
|
+
|
344
|
+
py2docfx_logger = get_logger(__name__)
|
345
|
+
|
346
|
+
msg = "Adding yaml extension to path"
|
347
|
+
py2docfx_logger.info(msg)
|
348
|
+
|
349
|
+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)),'docfx_yaml'))
|
350
|
+
os.chdir(PACKAGE_ROOT)
|
308
351
|
output_doc_folder = prepare_out_dir(output_root)
|
309
352
|
|
310
353
|
try:
|
@@ -312,8 +355,14 @@ def main(argv) -> int:
|
|
312
355
|
package_info_list, output_root, output_doc_folder,
|
313
356
|
github_token, ado_token, required_package_list))
|
314
357
|
except Exception as e:
|
315
|
-
|
358
|
+
msg = f"An error occurred: {e}"
|
359
|
+
py2docfx_logger.error(msg)
|
316
360
|
raise
|
361
|
+
|
362
|
+
warning_count, error_count = get_warning_error_count()
|
363
|
+
output_log_by_log_level()
|
364
|
+
print(f"Warning count: {warning_count}, Error count: {error_count}")
|
365
|
+
|
317
366
|
return 0
|
318
367
|
|
319
368
|
if __name__ == "__main__":
|
@@ -62,7 +62,7 @@ release = '{{PROJECT_RELEASE}}'
|
|
62
62
|
#
|
63
63
|
# This is also used if you do content translation via gettext catalogs.
|
64
64
|
# Usually you set "language" from the command line for these cases.
|
65
|
-
language =
|
65
|
+
language = 'en'
|
66
66
|
|
67
67
|
# List of patterns, relative to source directory, that match files and
|
68
68
|
# directories to ignore when looking for source files.
|
@@ -6,6 +6,7 @@ from py2docfx import PACKAGE_ROOT
|
|
6
6
|
from py2docfx.convert_prepare.package_info import PackageInfo
|
7
7
|
from py2docfx.convert_prepare.get_source import get_source
|
8
8
|
from py2docfx.convert_prepare import pip_utils
|
9
|
+
from py2docfx.docfx_yaml.logger import get_logger
|
9
10
|
|
10
11
|
REQUIREMENT_MODULES = ["setuptools", "sphinx==6.1.3", "pyyaml", "jinja2==3.0.3", "wheel"]
|
11
12
|
VENV_REQUIREMENT_MODULES = ["setuptools", "wheel"] # to support running setup.py in venv
|
@@ -27,7 +28,7 @@ def install_converter_requirements(executable: str):
|
|
27
28
|
https://apidrop.visualstudio.com/Content%20CI/_git/ReferenceAutomation?path=/Python/InstallPackage.ps1&line=15&lineEnd=35&lineStartColumn=1&lineEndColumn=87&lineStyle=plain&_a=contents
|
28
29
|
"""
|
29
30
|
pip_install_cmd = [executable, "-m", "pip", "install", "--upgrade"]
|
30
|
-
|
31
|
+
py2docfx_logger = get_logger(__name__)
|
31
32
|
pip_install_common_options = [
|
32
33
|
"--no-cache-dir",
|
33
34
|
"--quiet",
|
@@ -37,7 +38,8 @@ def install_converter_requirements(executable: str):
|
|
37
38
|
]
|
38
39
|
|
39
40
|
for module in REQUIREMENT_MODULES:
|
40
|
-
|
41
|
+
msg = f"<CI INFO>: Upgrading {module}..."
|
42
|
+
py2docfx_logger.info(msg)
|
41
43
|
subprocess.run(
|
42
44
|
pip_install_cmd + [module] + pip_install_common_options, check=True
|
43
45
|
)
|
@@ -45,7 +47,8 @@ def install_converter_requirements(executable: str):
|
|
45
47
|
async def install_venv_requirements(venv_num: int):
|
46
48
|
venv_exe = get_venv_exe(venv_num)
|
47
49
|
pip_cmd = ["-m", "pip", "install", "--upgrade"]+ VENV_REQUIREMENT_MODULES
|
48
|
-
await(await asyncio.create_subprocess_exec(venv_exe, *pip_cmd)).wait()
|
50
|
+
# await(await asyncio.create_subprocess_exec(venv_exe, *pip_cmd)).wait()
|
51
|
+
await pip_utils.run_async_subprocess(venv_exe, pip_cmd)
|
49
52
|
|
50
53
|
def get_venv_path(venv_num: int) -> str:
|
51
54
|
return os.path.join(PACKAGE_ROOT, VENV_DIR, "venv"+str(venv_num))
|
@@ -82,7 +85,8 @@ def get_base_venv_sphinx_build_path() -> str:
|
|
82
85
|
|
83
86
|
async def install_converter_requirement_async(executable: str):
|
84
87
|
pip_cmd = PIP_INSTALL_COMMAND + PIP_INSTALL_VENV_COMMON_OPTIONS + REQUIREMENT_MODULES
|
85
|
-
await(await asyncio.create_subprocess_exec(executable, *pip_cmd)).wait()
|
88
|
+
# await(await asyncio.create_subprocess_exec(executable, *pip_cmd)).wait()
|
89
|
+
await pip_utils.run_async_subprocess(executable, pip_cmd)
|
86
90
|
|
87
91
|
async def install_required_packages(
|
88
92
|
executable: str, required_package_list: list[PackageInfo], github_token: str, ado_token: str):
|
@@ -92,7 +96,8 @@ async def install_required_packages(
|
|
92
96
|
# get_source(package, idx, vststoken=ado_token, githubtoken=github_token)
|
93
97
|
package_name, options = package.get_install_command()
|
94
98
|
pip_cmd = PIP_INSTALL_COMMAND + PIP_INSTALL_VENV_COMMON_OPTIONS + options + [package_name]
|
95
|
-
await(await asyncio.create_subprocess_exec(executable, *pip_cmd)).wait()
|
99
|
+
# await(await asyncio.create_subprocess_exec(executable, *pip_cmd)).wait()
|
100
|
+
await pip_utils.run_async_subprocess(executable, pip_cmd)
|
96
101
|
|
97
102
|
async def create_environment(venv_path: int):
|
98
103
|
if os.name == 'nt':
|
@@ -101,26 +106,39 @@ async def create_environment(venv_path: int):
|
|
101
106
|
await (await asyncio.create_subprocess_exec("python3", "-m", "venv", venv_path)).wait()
|
102
107
|
|
103
108
|
async def prepare_base_venv(required_package_list: list[PackageInfo], github_token: str, ado_token: str):
|
104
|
-
|
109
|
+
py2docfx_logger = get_logger(__name__)
|
110
|
+
|
111
|
+
msg = f"<CI INFO>: Creating basevenv..."
|
112
|
+
py2docfx_logger.info(msg)
|
105
113
|
await create_environment(get_base_venv_path())
|
106
|
-
|
114
|
+
|
115
|
+
msg = f"<CI INFO>: Installing converter requirements in ..."
|
116
|
+
py2docfx_logger.info(msg)
|
107
117
|
await install_converter_requirement_async(get_base_venv_exe())
|
108
|
-
|
118
|
+
|
119
|
+
msg = f"<CI INFO>: Installing required packages in basevenv..."
|
120
|
+
py2docfx_logger.info(msg)
|
109
121
|
await install_required_packages(get_base_venv_exe(), required_package_list, github_token, ado_token)
|
110
|
-
|
122
|
+
|
123
|
+
msg = f"<CI INFO>: basevenv setup complete."
|
124
|
+
py2docfx_logger.info(msg)
|
111
125
|
|
112
126
|
async def prepare_venv(venv_num: int, package_info: PackageInfo, package_number: int, github_token: str, ado_token: str):
|
127
|
+
py2docfx_logger = get_logger(__name__)
|
113
128
|
await create_environment(get_venv_path(venv_num))
|
114
129
|
await install_venv_requirements(venv_num)
|
115
130
|
get_source(get_venv_exe(venv_num), package_info, package_number, vststoken=ado_token, githubtoken=github_token)
|
116
131
|
package_name, options = package_info.get_install_command()
|
117
132
|
await pip_utils.install_in_exe_async(get_venv_exe(venv_num), package_name, options)
|
118
|
-
|
133
|
+
msg = f"<CI INFO>: venv{venv_num} setup complete."
|
134
|
+
py2docfx_logger.info(msg)
|
119
135
|
|
120
136
|
async def remove_environment(venv_num: int):
|
137
|
+
py2docfx_logger = get_logger(__name__)
|
121
138
|
venv_path = get_venv_path(venv_num)
|
122
139
|
if os.path.exists(venv_path):
|
123
|
-
|
140
|
+
msg = f"<CI INFO>: Removing venv{venv_num}..."
|
141
|
+
py2docfx_logger.info(msg)
|
124
142
|
# Create a subprocess to run the shell command for removing the directory
|
125
143
|
process = await asyncio.create_subprocess_shell(
|
126
144
|
f'rm -rf {venv_path}' if os.name != 'nt' else f'rmdir /S /Q {venv_path}',
|
@@ -129,6 +147,9 @@ async def remove_environment(venv_num: int):
|
|
129
147
|
)
|
130
148
|
stdout, stderr = await process.communicate()
|
131
149
|
if process.returncode == 0:
|
132
|
-
|
150
|
+
msg = f"<CI INFO>: venv{venv_num} removed."
|
151
|
+
py2docfx_logger.info(msg)
|
133
152
|
else:
|
134
|
-
|
153
|
+
msg = f"<CI ERROR>: Failed to remove venv{venv_num}. Error: {stderr.decode()}"
|
154
|
+
py2docfx_logger.error(msg)
|
155
|
+
raise RuntimeError()
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations # Avoid A | B annotation break under <= py3.9
|
2
2
|
import os
|
3
3
|
import sys
|
4
|
-
|
4
|
+
from py2docfx.docfx_yaml.logger import get_package_logger
|
5
5
|
from py2docfx.convert_prepare.generate_conf import generate_conf
|
6
6
|
from py2docfx.convert_prepare.git import checkout
|
7
7
|
from py2docfx.convert_prepare.package_info import PackageInfo
|
@@ -11,6 +11,7 @@ from py2docfx.convert_prepare.subpackage import merge_subpackage_files
|
|
11
11
|
CONF_TEMPLATE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "conf_templates")
|
12
12
|
|
13
13
|
def generate_document(pkg: PackageInfo, output_root: str | os.PathLike, sphinx_build_path: str, extra_package_path: str, executable=sys.executable):
|
14
|
+
py2docfx_logger = get_package_logger(__name__)
|
14
15
|
# Copy manual written RST from target doc repo
|
15
16
|
package_paths = pkg.path
|
16
17
|
if output_root:
|
@@ -29,14 +30,20 @@ def generate_document(pkg: PackageInfo, output_root: str | os.PathLike, sphinx_b
|
|
29
30
|
if pkg.install_type == pkg.InstallType.SOURCE_CODE and getattr(pkg, "branch", None):
|
30
31
|
checkout(package_paths.source_folder, pkg.branch)
|
31
32
|
|
32
|
-
|
33
|
+
msg = f"<CI INFO>: Generating RST files for {pkg.name}."
|
34
|
+
py2docfx_logger.info(msg)
|
35
|
+
|
33
36
|
subpackages_rst_record = run_apidoc(package_paths.doc_folder, package_paths.source_folder,
|
34
37
|
exclude_paths, pkg)
|
35
38
|
|
36
|
-
|
39
|
+
msg = f"<CI INFO>: Listing RST files:"
|
40
|
+
py2docfx_logger.info(msg)
|
37
41
|
for rst_file in os.listdir(package_paths.doc_folder):
|
38
|
-
|
39
|
-
|
42
|
+
py2docfx_logger.info(rst_file)
|
43
|
+
|
44
|
+
msg = "<CI INFO>: Running Sphinx build..."
|
45
|
+
py2docfx_logger.info(msg)
|
46
|
+
|
40
47
|
generate_conf(pkg, package_paths.doc_folder, CONF_TEMPLATE_DIR)
|
41
48
|
run_converter(package_paths.doc_folder, package_paths.yaml_output_folder, sphinx_build_path, extra_package_path, executable=executable)
|
42
49
|
|
@@ -6,6 +6,7 @@ import sys
|
|
6
6
|
import py2docfx.convert_prepare.git as git
|
7
7
|
import py2docfx.convert_prepare.pip_utils as pip_utils
|
8
8
|
import py2docfx.convert_prepare.pack as pack
|
9
|
+
from py2docfx.docfx_yaml.logger import get_logger
|
9
10
|
from py2docfx.convert_prepare.constants import TARGET_REPO, SOURCE_REPO, DIST_TEMP
|
10
11
|
from py2docfx.convert_prepare.package_info import PackageInfo
|
11
12
|
from py2docfx.convert_prepare.source import Source
|
@@ -72,6 +73,7 @@ def update_package_info(executable: str, pkg: PackageInfo, source_folder: str):
|
|
72
73
|
)
|
73
74
|
|
74
75
|
def get_source(executable: str, pkg: PackageInfo, cnt: int, vststoken=None, githubtoken=None):
|
76
|
+
py2docfx_logger = get_logger(__name__)
|
75
77
|
path_cnt = str(cnt)
|
76
78
|
dist_dir = path.join(DIST_TEMP, path_cnt)
|
77
79
|
|
@@ -120,6 +122,8 @@ def get_source(executable: str, pkg: PackageInfo, cnt: int, vststoken=None, gith
|
|
120
122
|
os.listdir(dist_dir)[0]
|
121
123
|
)
|
122
124
|
else:
|
123
|
-
|
125
|
+
msg = f"Unknown install type: {pkg.install_type}"
|
126
|
+
py2docfx_logger.error(msg)
|
127
|
+
raise ValueError()
|
124
128
|
|
125
129
|
update_package_info(executable, pkg, source_folder)
|
py2docfx/convert_prepare/git.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
import re
|
2
2
|
import subprocess
|
3
3
|
|
4
|
-
|
4
|
+
from py2docfx.docfx_yaml.logger import get_logger
|
5
5
|
|
6
|
+
repoMap = {}
|
6
7
|
|
7
8
|
def clone(repo_location, branch, folder, extra_token=None):
|
8
9
|
"""
|
@@ -12,15 +13,16 @@ def clone(repo_location, branch, folder, extra_token=None):
|
|
12
13
|
replacing
|
13
14
|
https://apidrop.visualstudio.com/Content%20CI/_git/ReferenceAutomation?path=/Python/GetPackageCode.ps1&line=50&lineEnd=90&lineStartColumn=1&lineEndColumn=2&lineStyle=plain&_a=contents
|
14
15
|
"""
|
15
|
-
|
16
|
-
|
16
|
+
py2docfx_logger = get_logger(__name__)
|
17
|
+
msg = "<CI INFO>: Cloning repo: {}...".format(repo_location)
|
18
|
+
py2docfx_logger.info(msg)
|
17
19
|
|
18
20
|
global repoMap
|
19
21
|
|
20
22
|
if not test_url(repo_location, extra_token):
|
21
|
-
|
22
|
-
|
23
|
-
)
|
23
|
+
msg = "Git repo address {} is not a valid URL.".format(repo_location)
|
24
|
+
py2docfx_logger.error(msg)
|
25
|
+
raise ValueError()
|
24
26
|
else:
|
25
27
|
# Remove http(s):// from url to record. Further avoid dup-clone.
|
26
28
|
pureURL = re.sub("^\s*https?://", "", repo_location)
|
@@ -57,17 +59,17 @@ def clone(repo_location, branch, folder, extra_token=None):
|
|
57
59
|
]
|
58
60
|
subprocess.run(clone_params, check=True)
|
59
61
|
repoMap[pureURL] = folder
|
60
|
-
|
61
|
-
"<CI INFO>: Repo {} successfully cloned in {}...".format(
|
62
|
+
msg = "<CI INFO>: Repo {} successfully cloned in {}...".format(
|
62
63
|
repo_location, repoMap[pureURL]
|
63
64
|
)
|
64
|
-
)
|
65
|
+
py2docfx_logger.info(msg)
|
65
66
|
else:
|
66
67
|
raise ValueError(
|
67
68
|
"Branch {} doesn't exist in repo {}.".format(branch, repo_location)
|
68
69
|
)
|
69
70
|
else:
|
70
|
-
|
71
|
+
msg = "<CI INFO>: Repo already cloned in {}...".format(repoMap[pureURL])
|
72
|
+
py2docfx_logger.info(msg)
|
71
73
|
|
72
74
|
return repoMap[pureURL]
|
73
75
|
|
@@ -76,9 +78,12 @@ def test_url(url, extraHeader):
|
|
76
78
|
"""
|
77
79
|
Test if the url is a valid git repo url
|
78
80
|
"""
|
81
|
+
py2docfx_logger = get_logger(__name__)
|
79
82
|
params = ["git", "ls-remote", url]
|
80
83
|
if extraHeader:
|
81
|
-
|
84
|
+
msg = "Using extra header to test git repo url."
|
85
|
+
py2docfx_logger.info(msg)
|
86
|
+
|
82
87
|
params[1:1] = [
|
83
88
|
"-c",
|
84
89
|
"http.extraHeader=Authorization: Basic {}".format(extraHeader),
|
@@ -91,13 +96,13 @@ def test_url(url, extraHeader):
|
|
91
96
|
|
92
97
|
|
93
98
|
def convertBranch(repo_url, branch, extraHeader):
|
99
|
+
py2docfx_logger = get_logger(__name__)
|
94
100
|
result = branch
|
95
101
|
if not branch:
|
96
|
-
|
97
|
-
"Using empty branch of {}, going to use master branch instead.".format(
|
102
|
+
msg = "Using empty branch of {}, going to use master branch instead.".format(
|
98
103
|
repo_url
|
99
104
|
)
|
100
|
-
)
|
105
|
+
py2docfx_logger.info(msg)
|
101
106
|
result = "master"
|
102
107
|
if result == "master":
|
103
108
|
check_params = ["git", "ls-remote", "--heads", repo_url, "refs/heads/main"]
|
@@ -109,11 +114,10 @@ def convertBranch(repo_url, branch, extraHeader):
|
|
109
114
|
|
110
115
|
checkBr = subprocess.check_output(check_params)
|
111
116
|
if checkBr:
|
112
|
-
|
113
|
-
"Using master branch of {}, going to use main branch instead.".format(
|
117
|
+
msg = "Using master branch of {}, going to use main branch instead.".format(
|
114
118
|
repo_url
|
115
119
|
)
|
116
|
-
)
|
120
|
+
py2docfx_logger.info(msg)
|
117
121
|
result = "main"
|
118
122
|
return result
|
119
123
|
|
@@ -125,7 +129,7 @@ def checkout(folder, branch):
|
|
125
129
|
Replacing
|
126
130
|
https://apidrop.visualstudio.com/Content%20CI/_git/ReferenceAutomation?path=/Python/PyCommon.ps1&line=707&lineEnd=763&lineStartColumn=1&lineEndColumn=2&lineStyle=plain&_a=contents
|
127
131
|
"""
|
128
|
-
|
132
|
+
py2docfx_logger = get_logger(__name__)
|
129
133
|
remote = "origin"
|
130
134
|
|
131
135
|
if ":" in branch:
|
@@ -153,8 +157,8 @@ def checkout(folder, branch):
|
|
153
157
|
)
|
154
158
|
|
155
159
|
subprocess.run(["git", "-C", folder, "checkout", "--quiet", branch])
|
156
|
-
|
157
|
-
|
160
|
+
msg = "<CI INFO>: Switched to branch {}.".format(branch)
|
161
|
+
py2docfx_logger.info(msg)
|
158
162
|
|
159
163
|
|
160
164
|
def commit_and_push(repo_location, folder, extra_token=None):
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
import os
|
3
3
|
import re
|
4
|
+
from py2docfx.docfx_yaml.logger import get_logger
|
4
5
|
from py2docfx.convert_prepare.source import Source
|
5
6
|
from py2docfx.convert_prepare.package_info_extra_settings import extra_exclude_path_by_package
|
6
7
|
|
@@ -9,14 +10,13 @@ class PackageInfo:
|
|
9
10
|
PYPI = 1
|
10
11
|
SOURCE_CODE = 2
|
11
12
|
DIST_FILE = 3
|
12
|
-
|
13
13
|
path: Source
|
14
|
-
|
15
14
|
def __init__(self) -> None:
|
16
15
|
pass
|
17
|
-
|
16
|
+
|
18
17
|
@classmethod
|
19
18
|
def report_error(cls, name, value, condition=None):
|
19
|
+
py2docfx_logger = get_logger(__name__)
|
20
20
|
if condition:
|
21
21
|
message = "When {0}, found unexpected property of {1}, loaded value is: {2}".format(
|
22
22
|
condition, name, value
|
@@ -25,7 +25,8 @@ class PackageInfo:
|
|
25
25
|
message = "Found unexpected property of {0}, loaded value is: {1}".format(
|
26
26
|
name, value
|
27
27
|
)
|
28
|
-
|
28
|
+
py2docfx_logger.error(message)
|
29
|
+
raise ValueError()
|
29
30
|
|
30
31
|
@classmethod
|
31
32
|
def parse_from(cls, dict, reading_required_packages=False):
|
@@ -59,12 +60,14 @@ class PackageInfo:
|
|
59
60
|
package_info.folder = package_info_dict.get("folder", None)
|
60
61
|
|
61
62
|
if not package_info.url:
|
63
|
+
py2docfx_logger = get_logger(__name__)
|
62
64
|
if not package_info.folder:
|
63
|
-
|
64
|
-
|
65
|
-
)
|
65
|
+
msg = "When install_type is source_code, url or folder should be provided"
|
66
|
+
py2docfx_logger.error(msg)
|
67
|
+
raise ValueError()
|
66
68
|
else:
|
67
|
-
|
69
|
+
msg = f'Read source code from local folder: {package_info.folder}'
|
70
|
+
py2docfx_logger.info(msg)
|
68
71
|
|
69
72
|
prefer_source_distribution = package_info_dict.get(
|
70
73
|
"prefer_source_distribution", False
|
@@ -140,10 +143,13 @@ class PackageInfo:
|
|
140
143
|
return (packageInstallName, pipInstallExtraOptions)
|
141
144
|
|
142
145
|
def get_exluded_command(self) -> []:
|
146
|
+
py2docfx_logger = get_logger(__name__)
|
143
147
|
if hasattr(self, "path"):
|
144
148
|
code_location = self.path.source_folder
|
145
149
|
else:
|
146
|
-
|
150
|
+
msg = "Should set source code location before build documents"
|
151
|
+
py2docfx_logger.error(msg)
|
152
|
+
raise ValueError()
|
147
153
|
exclude_path = []
|
148
154
|
if code_location:
|
149
155
|
exclude_path.append(os.path.join(code_location, "build/*"))
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import subprocess
|
2
2
|
import asyncio
|
3
|
+
import os
|
3
4
|
from py2docfx import PACKAGE_ROOT
|
5
|
+
from py2docfx.docfx_yaml.logger import get_logger, log_subprocess_ouput
|
4
6
|
|
5
7
|
PYPI = "pypi"
|
6
8
|
|
@@ -10,10 +12,9 @@ pip_install_common_options = [
|
|
10
12
|
"--no-compile",
|
11
13
|
"--no-warn-conflicts",
|
12
14
|
"--disable-pip-version-check",
|
13
|
-
"--verbose"
|
15
|
+
"--verbose"
|
14
16
|
]
|
15
17
|
|
16
|
-
|
17
18
|
def download(package_name, path, extra_index_url=None, prefer_source_distribution=True):
|
18
19
|
# Downloads a package from PyPI to the specified path using pip.
|
19
20
|
download_param = ["pip", "download", "--dest", path, "--no-deps", package_name]
|
@@ -24,7 +25,9 @@ def download(package_name, path, extra_index_url=None, prefer_source_distributio
|
|
24
25
|
download_param.append("--no-binary=:all:")
|
25
26
|
else:
|
26
27
|
download_param.append("--prefer-binary")
|
27
|
-
subprocess.run(download_param, check=True, cwd=PACKAGE_ROOT)
|
28
|
+
output = subprocess.run(download_param, check=True, cwd=PACKAGE_ROOT, capture_output=True, text=True)
|
29
|
+
py2docfx_logger = get_logger(__name__)
|
30
|
+
log_subprocess_ouput(output, py2docfx_logger)
|
28
31
|
|
29
32
|
|
30
33
|
def install(package_name, options):
|
@@ -32,16 +35,38 @@ def install(package_name, options):
|
|
32
35
|
install_param = "pip install {} {}".format(
|
33
36
|
" ".join(pip_install_common_options + options), package_name
|
34
37
|
).split(" ")
|
35
|
-
subprocess.run(install_param, check=True, cwd=PACKAGE_ROOT)
|
36
|
-
|
38
|
+
output = subprocess.run(install_param, check=True, cwd=PACKAGE_ROOT, capture_output=True, text=True)
|
39
|
+
py2docfx_logger = get_logger(__name__)
|
40
|
+
log_subprocess_ouput(output, py2docfx_logger)
|
37
41
|
|
38
42
|
def install_in_exe(exe_path, package_name, options):
|
39
43
|
# Installs a package from PyPI using pip.
|
40
44
|
install_param = [exe_path] + "-m pip install {} {}".format(
|
41
45
|
" ".join(pip_install_common_options + options), package_name
|
42
46
|
).split(" ")
|
43
|
-
subprocess.run(install_param, check=True, cwd=PACKAGE_ROOT)
|
44
|
-
|
47
|
+
output = subprocess.run(install_param, check=True, cwd=PACKAGE_ROOT, capture_output=True, text=True)
|
48
|
+
py2docfx_logger = get_logger(__name__)
|
49
|
+
log_subprocess_ouput(output, py2docfx_logger)
|
50
|
+
|
45
51
|
async def install_in_exe_async(exe_path, package_name, options):
|
46
52
|
pip_cmd = ["-m", "pip", "install"]+ pip_install_common_options + options + [package_name]
|
47
|
-
await
|
53
|
+
await run_async_subprocess(exe_path, pip_cmd)
|
54
|
+
# await(await asyncio.create_subprocess_exec(exe_path, *pip_cmd)).wait()
|
55
|
+
|
56
|
+
async def run_async_subprocess(exe_path, cmd):
|
57
|
+
process = await asyncio.create_subprocess_exec(
|
58
|
+
exe_path, *cmd,
|
59
|
+
stdout=asyncio.subprocess.PIPE,
|
60
|
+
stderr=asyncio.subprocess.PIPE
|
61
|
+
)
|
62
|
+
stdout, stderr = await process.communicate()
|
63
|
+
py2docfx_logger = get_logger(__name__)
|
64
|
+
if process.returncode != 0:
|
65
|
+
msg = stderr.decode('utf-8')
|
66
|
+
if msg != None and msg != "":
|
67
|
+
py2docfx_logger.error(msg)
|
68
|
+
raise RuntimeError()
|
69
|
+
else:
|
70
|
+
msg = stdout.decode('utf-8')
|
71
|
+
if msg != None and msg != "":
|
72
|
+
py2docfx_logger.info(msg)
|