Skip to content

Commit ea6bf6a

Browse files
JennyPngCopilotscbedd
authored
Add Generate Check without Tox (#43982)
* migrate generate * minor * address some copilot comments * Update eng/tools/azure-sdk-tools/azpysdk/generate.py Co-authored-by: Copilot <[email protected]> * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * format * stdout * address review comments * properly print stderr * typo * set generate to false for azure-template * Update eng/tools/azure-sdk-tools/azpysdk/generate.py Co-authored-by: Scott Beddall <[email protected]> * Format --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Scott Beddall <[email protected]>
1 parent 5268f45 commit ea6bf6a

File tree

4 files changed

+107
-0
lines changed

4 files changed

+107
-0
lines changed

doc/tool_usage_guide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ This repo is currently migrating all checks from a slower `tox`-based framework,
2727
|`verifysdist`| Verify directories included in sdist and contents in manifest file. Also ensures that py.typed configuration is correct within the setup.py. | `azpysdk verifysdist .` |
2828
|`verify_keywords`| Verify that the keyword 'azure sdk' is present in the targeted package's keywords. | `azpysdk verify_keywords .` |
2929
|`import_all`| Installs the package w/ default dependencies, then attempts to `import *` from the base namespace. Ensures that all imports will resolve after a base install and import. | `azpysdk import_all .` |
30+
|`generate`| Regenerates the code. | `azpysdk generate .` |
3031
|`breaking`| Checks for breaking changes. | `azpysdk breaking .` |
3132

3233
## Common arguments
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import argparse
2+
import sys
3+
from pathlib import Path
4+
5+
from typing import Optional, List
6+
from subprocess import PIPE, CalledProcessError, run
7+
8+
from .Check import Check
9+
from ci_tools.functions import install_into_venv
10+
from ci_tools.variables import set_envvar_defaults
11+
from ci_tools.logging import logger
12+
13+
14+
class generate(Check):
15+
def __init__(self) -> None:
16+
super().__init__()
17+
18+
def register(
19+
self, subparsers: "argparse._SubParsersAction", parent_parsers: Optional[List[argparse.ArgumentParser]] = None
20+
) -> None:
21+
"""Register the generate check. The generate check regenerates the code using autorest or tsp-client based on the package configuration."""
22+
parents = parent_parsers or []
23+
p = subparsers.add_parser("generate", parents=parents, help="Run the generate check to regenerate the code.")
24+
p.set_defaults(func=self.run)
25+
26+
def run(self, args: argparse.Namespace) -> int:
27+
"""Run the generate check command."""
28+
logger.info("Running generate check...")
29+
30+
set_envvar_defaults()
31+
targeted = self.get_targeted_directories(args)
32+
33+
results: List[int] = []
34+
35+
for parsed in targeted:
36+
package_dir = parsed.folder
37+
package_name = parsed.name
38+
executable, staging_directory = self.get_executable(args.isolate, args.command, sys.executable, package_dir)
39+
logger.info(f"Processing {package_name} for generate check")
40+
41+
# install dependencies
42+
self.install_dev_reqs(executable, args, package_dir)
43+
44+
try:
45+
self.generate(Path(package_dir))
46+
except ValueError as e:
47+
logger.error(f"Generation failed for {package_name}: {e}")
48+
results.append(1)
49+
continue
50+
51+
return max(results) if results else 0
52+
53+
def generate(self, folder: Path = Path(".")) -> None:
54+
if (folder / "swagger" / "README.md").exists():
55+
self.generate_autorest(folder)
56+
elif (folder / "tsp-location.yaml").exists():
57+
self.generate_typespec(folder)
58+
else:
59+
raise ValueError("Didn't find swagger/README.md nor tsp-location.yaml")
60+
61+
def generate_autorest(self, folder: Path) -> None:
62+
readme_path = folder / "swagger" / "README.md"
63+
64+
try:
65+
run(
66+
["autorest", str(readme_path), "--python-sdks-folder=../../"],
67+
cwd=folder,
68+
shell=False,
69+
stderr=PIPE,
70+
check=True,
71+
)
72+
except FileNotFoundError:
73+
raise ValueError(
74+
"autorest is not installed. Please install autorest (reference https://github.com/Azure/autorest/blob/main/docs/install/readme.md#-installing-autorest) before running this command."
75+
)
76+
except CalledProcessError as e:
77+
stderr_output = e.stderr.decode() if e.stderr else "No stderr output"
78+
raise ValueError(f"autorest encountered an unexpected error: stderr={stderr_output}")
79+
80+
logger.info("Autorest done")
81+
82+
def generate_typespec(self, folder: Path) -> None:
83+
tsp_location_path = folder / "tsp-location.yaml"
84+
85+
if not tsp_location_path.exists():
86+
raise ValueError(
87+
"Didn't find a tsp-location.yaml in local directory. Please make sure a valid "
88+
"tsp-location.yaml file exists before running this command, for more information "
89+
"on how to create one, see: "
90+
"https://github.com/Azure/azure-sdk-tools/tree/main/tools/tsp-client/README.md"
91+
)
92+
93+
try:
94+
run(["tsp-client", "update"], cwd=folder, check=True, stderr=PIPE, shell=False)
95+
except FileNotFoundError as e:
96+
raise ValueError(
97+
"tsp-client is not installed. Please run: npm install -g @azure-tools/typespec-client-generator-cli"
98+
)
99+
except CalledProcessError as e:
100+
stderr_output = e.stderr.decode() if e.stderr else "No stderr output"
101+
raise ValueError(f"tsp-client encountered an unexpected error: stderr={stderr_output}")
102+
103+
logger.info("TypeSpec generate done")

eng/tools/azure-sdk-tools/azpysdk/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from .verify_whl import verify_whl
2929
from .bandit import bandit
3030
from .verify_keywords import verify_keywords
31+
from .generate import generate
3132
from .breaking import breaking
3233

3334
from ci_tools.logging import configure_logging, logger
@@ -88,6 +89,7 @@ def build_parser() -> argparse.ArgumentParser:
8889
verify_whl().register(subparsers, [common])
8990
bandit().register(subparsers, [common])
9091
verify_keywords().register(subparsers, [common])
92+
generate().register(subparsers, [common])
9193
breaking().register(subparsers, [common])
9294

9395
return parser

sdk/template/azure-template/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ verifytypes = true
4848
pyright = true
4949
pylint = true
5050
black = true
51+
generate = false

0 commit comments

Comments
 (0)