ScriptExecutor Interface and ScriptLanguage Type
Part of #7435 — Multi-Language Hook Support
User Story
As a template author, I want azd to understand that my hook script is written in a specific programming language so that it can handle execution appropriately instead of treating everything as a shell script.
Solution Approach
Create pkg/tools/language/executor.go (NEW):
- Define
ScriptLanguage type (string) with constants: ScriptLanguageUnknown (""), ScriptLanguagePython ("python"), ScriptLanguageJavaScript ("js"), ScriptLanguageTypeScript ("ts"), ScriptLanguageDotNet ("dotnet").
- Define
ScriptExecutor interface:
Language() ScriptLanguage
Prepare(ctx context.Context, scriptPath string) error — runtime check, dependency install, build
Execute(ctx context.Context, scriptPath string, options tools.ExecOptions) (exec.RunResult, error)
- Implement
GetExecutor(language ScriptLanguage, ...) (ScriptExecutor, error) factory. Accept dependencies via parameters (not global state) — specifically exec.CommandRunner. Phase 1: Python returns real executor; JS/TS/DotNet return ErrUnsupportedLanguage sentinel.
- Implement
InferLanguageFromPath(path string) ScriptLanguage mapping .py → Python, .js → JS, .ts → TS, .cs → DotNet, unknown → ScriptLanguageUnknown.
Create pkg/tools/language/executor_test.go (NEW):
- Table-driven tests for
InferLanguageFromPath covering all extensions + unknown.
- Tests for
GetExecutor returning real executor for Python, ErrUnsupportedLanguage for others.
Files: pkg/tools/language/executor.go (NEW), pkg/tools/language/executor_test.go (NEW)
Acceptance Criteria
References
ScriptExecutor Interface and ScriptLanguage Type
Part of #7435 — Multi-Language Hook Support
User Story
As a template author, I want azd to understand that my hook script is written in a specific programming language so that it can handle execution appropriately instead of treating everything as a shell script.
Solution Approach
Create
pkg/tools/language/executor.go(NEW):ScriptLanguagetype (string) with constants:ScriptLanguageUnknown(""),ScriptLanguagePython("python"),ScriptLanguageJavaScript("js"),ScriptLanguageTypeScript("ts"),ScriptLanguageDotNet("dotnet").ScriptExecutorinterface:Language() ScriptLanguagePrepare(ctx context.Context, scriptPath string) error— runtime check, dependency install, buildExecute(ctx context.Context, scriptPath string, options tools.ExecOptions) (exec.RunResult, error)GetExecutor(language ScriptLanguage, ...) (ScriptExecutor, error)factory. Accept dependencies via parameters (not global state) — specificallyexec.CommandRunner. Phase 1: Python returns real executor; JS/TS/DotNet returnErrUnsupportedLanguagesentinel.InferLanguageFromPath(path string) ScriptLanguagemapping.py→ Python,.js→ JS,.ts→ TS,.cs→ DotNet, unknown →ScriptLanguageUnknown.Create
pkg/tools/language/executor_test.go(NEW):InferLanguageFromPathcovering all extensions + unknown.GetExecutorreturning real executor for Python,ErrUnsupportedLanguagefor others.Files:
pkg/tools/language/executor.go(NEW),pkg/tools/language/executor_test.go(NEW)Acceptance Criteria
go build ./pkg/tools/language/...InferLanguageFromPathcorrectly maps.py,.js,.ts,.cs, and unknown extensionsGetExecutorreturnsErrUnsupportedLanguagefor JS, TS, DotNet in Phase 1ScriptExecutorinterface is compatible withtools.ExecOptionsfrompkg/tools/script.goReferences