Skip to content

Add shared parallel spector scenario compiler (@azure-tools/spector-runner) - #5063

Draft
Timothee Guerin (timotheeguerin) wants to merge 1 commit into
Azure:mainfrom
timotheeguerin:spector-scenario-compiler
Draft

Add shared parallel spector scenario compiler (@azure-tools/spector-runner)#5063
Timothee Guerin (timotheeguerin) wants to merge 1 commit into
Azure:mainfrom
timotheeguerin:spector-scenario-compiler

Conversation

@timotheeguerin

Copy link
Copy Markdown
Member

Fixes #5022

Summary

Adds a shared, parallel spector scenario compiler in the new @azure-tools/spector-runner package, and moves the Go, TypeScript and Python regenerators onto it. compileScenarios spawns one tsp compile subprocess per scenario (up to N at a time, N = CPU count by default) and reports progress through a TaskRunner / runWithConcurrency / === Summary === engine shared in spirit with @typespec/tsp-integration, so the two can be merged later.

Two driving modes

  • Bare CLI + declarative spector.config.yaml — the config can declare the output layout (specsRoot, outputDir, compileConfig) and per-instance lifecycle hooks (hooks.postCompile, hooks.postCompileDeclarations) as shell commands, selectable with --phase all|compile|declarations. Hook commands receive SPECTOR_OUTPUT_DIR / SPECTOR_SPEC_PATH / SPECTOR_SPEC_NAME / SPECTOR_PHASE. This lets the TypeScript regenerator drop its bespoke driver/config JS entirely — pnpm generate-tsp-only is now just spector-runner --config spector.config.yaml, with two short hook scripts (client post-processing + api-extractor declarations).
  • defineConfig module (--config-file) — for emitters needing extra spec roots, local specs, or cross-cutting preRun/postScenario/postRun steps (Python keeps its upstream-synced option tables + flavor/baseline setup here).

Emitters migrated

  • Go and TypeScript now run entirely through the bare CLI.
  • Python runs through a --config-file module.
  • Output is byte-identical to the previous per-emitter drivers (validated on the TS tracked-baseline tree).

Notes

  • New @azure-tools/spector-runner package (54 unit tests).
  • pnpm-lock.yaml change is the new picocolors dep for the package.

…unner)

Add a shared, parallel spector scenario compiler in the new
@azure-tools/spector-runner package, plus a wrapper-free CLI with a
declarative spector.config.yaml (specsRoot/outputDir/compileConfig +
postCompile/postCompileDeclarations hooks, selectable via
--phase all|compile|declarations) and a defineConfig module mode for
emitters needing more. Move the Go, TypeScript and Python regenerators
onto this one parallel-compile + reporting + lifecycle engine; output is
byte-identical to the previous per-emitter drivers.

Fixes Azure#5022
@microsoft-github-policy-service microsoft-github-policy-service Bot added eng emitter:python Issues for @azure-tools/typespec-python emitter emitter:go Issues for @azure-tools/typespec-go emitter emitter:typescript Issues for @azure-tools/typespec-ts emitter labels Jul 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

All changed packages have been documented.

  • @azure-tools/typespec-go
  • @azure-tools/typespec-python
  • @azure-tools/typespec-ts
Show changes

@azure-tools/typespec-go - internal ✏️

Add a shared, parallel spector scenario compiler to the @azure-tools/spector-runner package, plus a wrapper-free spector-runner CLI with a declarative config + hook system, and move the Go, TypeScript (@azure-tools/typespec-ts) and Python (@azure-tools/typespec-python) regenerators onto it. compileScenarios spawns one tsp compile subprocess per scenario (up to N at a time, N = CPU count by default) and reports progress through a TaskRunner/runWithConcurrency/=== Summary === engine shared with @typespec/tsp-integration, so the two can be merged later. The spector-runner CLI (and its runSpectorRunner/buildScenarios programmatic API) builds every scenario in one or more spector.config.yaml files and compiles them in parallel for a given emitter — driven entirely by flags (--config, --specs-root, --emit, --output-dir, --option, --cwd, ...). The spector.config.yaml schema can itself declare the output layout (specsRoot, outputDir, compileConfig) and per-instance lifecycle hooks (hooks.postCompile, hooks.postCompileDeclarations) as shell commands, selectable with --phase all|compile|declarations; hook commands receive SPECTOR_OUTPUT_DIR/SPECTOR_SPEC_PATH/SPECTOR_SPEC_NAME/SPECTOR_PHASE. This lets the TypeScript regenerator drop its bespoke driver/config JS entirely: pnpm generate-tsp-only is now just spector-runner --config spector.config.yaml, with two short hook scripts for the client post-processing and the api-extractor declarations phase. For emitters that need more (extra spec roots, local specs, cross-cutting pre/post steps), a spector-runner.config.{js,ts} module (defineConfig) declares the whole run — scenarios plus preRun/postScenario/postRun hooks — and the CLI drives it end-to-end via --config-file (or runConfig/loadConfigFile programmatically). This lets the per-emitter regenerators shrink (Go and TS now run entirely through the bare CLI; Python keeps only its upstream-synced option tables + flavor/baseline setup in a --config-file module). A CompileScenario may also set a per-scenario cwd (used by the TS regenerator, whose committed per-output tspconfig.yaml is resolved relative to each output folder). The Go, TS and Python regenerators now share this one parallel-compile + reporting + lifecycle engine; output is byte-identical to the previous per-emitter drivers.

@azure-tools/typespec-ts - internal ✏️

Add a shared, parallel spector scenario compiler to the @azure-tools/spector-runner package, plus a wrapper-free spector-runner CLI with a declarative config + hook system, and move the Go, TypeScript (@azure-tools/typespec-ts) and Python (@azure-tools/typespec-python) regenerators onto it. compileScenarios spawns one tsp compile subprocess per scenario (up to N at a time, N = CPU count by default) and reports progress through a TaskRunner/runWithConcurrency/=== Summary === engine shared with @typespec/tsp-integration, so the two can be merged later. The spector-runner CLI (and its runSpectorRunner/buildScenarios programmatic API) builds every scenario in one or more spector.config.yaml files and compiles them in parallel for a given emitter — driven entirely by flags (--config, --specs-root, --emit, --output-dir, --option, --cwd, ...). The spector.config.yaml schema can itself declare the output layout (specsRoot, outputDir, compileConfig) and per-instance lifecycle hooks (hooks.postCompile, hooks.postCompileDeclarations) as shell commands, selectable with --phase all|compile|declarations; hook commands receive SPECTOR_OUTPUT_DIR/SPECTOR_SPEC_PATH/SPECTOR_SPEC_NAME/SPECTOR_PHASE. This lets the TypeScript regenerator drop its bespoke driver/config JS entirely: pnpm generate-tsp-only is now just spector-runner --config spector.config.yaml, with two short hook scripts for the client post-processing and the api-extractor declarations phase. For emitters that need more (extra spec roots, local specs, cross-cutting pre/post steps), a spector-runner.config.{js,ts} module (defineConfig) declares the whole run — scenarios plus preRun/postScenario/postRun hooks — and the CLI drives it end-to-end via --config-file (or runConfig/loadConfigFile programmatically). This lets the per-emitter regenerators shrink (Go and TS now run entirely through the bare CLI; Python keeps only its upstream-synced option tables + flavor/baseline setup in a --config-file module). A CompileScenario may also set a per-scenario cwd (used by the TS regenerator, whose committed per-output tspconfig.yaml is resolved relative to each output folder). The Go, TS and Python regenerators now share this one parallel-compile + reporting + lifecycle engine; output is byte-identical to the previous per-emitter drivers.

@azure-tools/typespec-python - internal ✏️

Add a shared, parallel spector scenario compiler to the @azure-tools/spector-runner package, plus a wrapper-free spector-runner CLI with a declarative config + hook system, and move the Go, TypeScript (@azure-tools/typespec-ts) and Python (@azure-tools/typespec-python) regenerators onto it. compileScenarios spawns one tsp compile subprocess per scenario (up to N at a time, N = CPU count by default) and reports progress through a TaskRunner/runWithConcurrency/=== Summary === engine shared with @typespec/tsp-integration, so the two can be merged later. The spector-runner CLI (and its runSpectorRunner/buildScenarios programmatic API) builds every scenario in one or more spector.config.yaml files and compiles them in parallel for a given emitter — driven entirely by flags (--config, --specs-root, --emit, --output-dir, --option, --cwd, ...). The spector.config.yaml schema can itself declare the output layout (specsRoot, outputDir, compileConfig) and per-instance lifecycle hooks (hooks.postCompile, hooks.postCompileDeclarations) as shell commands, selectable with --phase all|compile|declarations; hook commands receive SPECTOR_OUTPUT_DIR/SPECTOR_SPEC_PATH/SPECTOR_SPEC_NAME/SPECTOR_PHASE. This lets the TypeScript regenerator drop its bespoke driver/config JS entirely: pnpm generate-tsp-only is now just spector-runner --config spector.config.yaml, with two short hook scripts for the client post-processing and the api-extractor declarations phase. For emitters that need more (extra spec roots, local specs, cross-cutting pre/post steps), a spector-runner.config.{js,ts} module (defineConfig) declares the whole run — scenarios plus preRun/postScenario/postRun hooks — and the CLI drives it end-to-end via --config-file (or runConfig/loadConfigFile programmatically). This lets the per-emitter regenerators shrink (Go and TS now run entirely through the bare CLI; Python keeps only its upstream-synced option tables + flavor/baseline setup in a --config-file module). A CompileScenario may also set a per-scenario cwd (used by the TS regenerator, whose committed per-output tspconfig.yaml is resolved relative to each output folder). The Go, TS and Python regenerators now share this one parallel-compile + reporting + lifecycle engine; output is byte-identical to the previous per-emitter drivers.

@pkg-pr-new

pkg-pr-new Bot commented Jul 27, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-go@5063
npm i https://pkg.pr.new/@azure-tools/typespec-python@5063
npm i https://pkg.pr.new/@azure-tools/typespec-ts@5063

commit: a5b88ad

@azure-sdk-automation

Copy link
Copy Markdown
Contributor

You can try these changes here

🛝 Playground 🌐 Website

@microsoft-github-policy-service microsoft-github-policy-service Bot added the stale Mark a PR that hasn't been recently updated and will be closed. label Aug 11, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown

Hi @Timothee Guerin (@timotheeguerin). Your PR has had no update for 14 days and it is marked as a stale PR. If it is not updated within 14 days, the PR will automatically be closed. If you want to refresh the PR, please remove the stale label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:go Issues for @azure-tools/typespec-go emitter emitter:python Issues for @azure-tools/typespec-python emitter emitter:typescript Issues for @azure-tools/typespec-ts emitter eng stale Mark a PR that hasn't been recently updated and will be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standarized spector scenario generator

1 participant