-
Notifications
You must be signed in to change notification settings - Fork 268
Description
Extensions cannot provide guidance or suggestions when required tool validation fails because lifecycle events fire after EnsureAllTools() completes successfully. This creates a catch-22 where extensions that want to suggest alternatives (like remote build when Docker is unavailable) never get the opportunity to run.
Current Execution Order
1. Initialize
2. EnsureAllTools() ← Fails if Docker daemon not running
3. [COMMAND EXITS WITH ERROR]
4. Lifecycle events (prepackage, preprovision, predeploy) ← Never reached
Example Use Case
The azd-ext-doctor extension aims to suggest enabling remote build when Docker daemon is unavailable:
func onPrePackage(ctx context.Context, args *azdext.ServiceEventArgs) error {
// Check if Docker required but not running
// Suggest: azd doctor configure remote-build
// But this never executes because EnsureAllTools fails first
}Current behavior: User runs azd package with Docker daemon stopped → immediate error
Desired behavior: Extension suggests remote build alternative before failing
Proposed Solution
Add a new lifecycle event that fires before tool validation, allowing extensions to:
- Inspect required tools
- Provide suggestions for missing/unavailable tools
- Offer configuration alternatives
- Guide users through remediation
Suggested Event Names (choose one)
pretoolcheck- Fires before EnsureAllTools()preinit- Fires at the very beginning of command executiontoolcheck- Fires with tool validation context
Example Extension Usage
host.WithProjectEventHandler("pretoolcheck", func(ctx context.Context, args *azdext.ProjectEventArgs) error {
// Extension can inspect required tools
requiredTools := args.RequiredTools
for _, tool := range requiredTools {
if tool.Name == "docker" && !isDockerDaemonRunning() {
fmt.Fprintln(os.Stderr, "💡 Tip: Enable remote build to build without local Docker")
fmt.Fprintln(os.Stderr, "Run: azd doctor configure remote-build")
}
}
return nil
})Modified Execution Order
1. Initialize
2. → NEW: Fire pretoolcheck lifecycle event ← Extensions can provide guidance
3. EnsureAllTools() ← Fails if tools missing/unavailable
4. Lifecycle events (prepackage, preprovision, predeploy)
Benefits
- Better UX: Users get actionable suggestions before seeing cryptic tool errors
- Extension Capabilities: Extensions can provide domain-specific guidance
- Graceful Degradation: Extensions can suggest workarounds (remote build, alternative tools, etc.)
- Proactive Help: Catch tool issues early with helpful context
Related Code Locations
- cmd/package.go#L134 - Package command calls EnsureAllTools
- cmd/provision.go#L197 - Provision command calls EnsureAllTools
- cmd/deploy.go#L217 - Deploy command calls EnsureServiceTargetTools
- pkg/tools/ensure.go#L39-L87 - Tool validation logic
Alternative Considered
Extensions could use standalone commands (like azd doctor check), but this:
- Requires users to know about the extension
- Adds extra manual steps
- Doesn't integrate with normal
azd up/package/deployworkflows - Loses context about which command the user actually wanted to run
Implementation Notes
The event should provide:
- List of required tools for the operation
- Service/project context
- Ability to output to stderr without disrupting normal flow
- Should NOT block tool validation (run even if extension errors)
Real-World Impact
The azd-ext-doctor extension (https://github.com/spboyer/azd-ext-doctor) would immediately benefit from this feature, providing users with actionable suggestions when tools are unavailable, improving the developer experience significantly.