in cli/azd/extensions/microsoft.azd.extensions/internal/cmd/init.go [390:552]
func collectExtensionMetadata(ctx context.Context, azdClient *azdext.AzdClient) (*models.ExtensionSchema, error) {
fmt.Println()
fmt.Println("Please provide the following information to create your extension.")
fmt.Printf("Values can be changed later in the %s file.\n", output.WithHighLightFormat("extension.yaml"))
fmt.Println()
idPrompt, err := azdClient.Prompt().Prompt(ctx, &azdext.PromptRequest{
Options: &azdext.PromptOptions{
Message: "Enter a unique identifier for your extension",
Placeholder: "company.extension",
RequiredMessage: "Extension ID is required",
Required: true,
Hint: "Extension ID is used to identify your extension in the AZD ecosystem. " +
"It should be unique and follow the format 'company.extension'.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for extension ID: %w", err)
}
displayNamePrompt, err := azdClient.Prompt().Prompt(ctx, &azdext.PromptRequest{
Options: &azdext.PromptOptions{
Message: "Enter a display name for your extension",
Placeholder: "My Extension",
RequiredMessage: "Display name is required",
Required: true,
HelpMessage: "Display name is used to show the extension name in the AZD CLI. " +
"It should be user-friendly and descriptive.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for display name: %w", err)
}
descriptionPrompt, err := azdClient.Prompt().Prompt(ctx, &azdext.PromptRequest{
Options: &azdext.PromptOptions{
Message: "Enter a description for your extension",
Placeholder: "A brief description of your extension",
RequiredMessage: "Description is required",
Required: true,
HelpMessage: "Description is used to provide more information about your extension. " +
"It should be concise and informative.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for description: %w", err)
}
tagsPrompt, err := azdClient.Prompt().Prompt(ctx, &azdext.PromptRequest{
Options: &azdext.PromptOptions{
Message: "Enter tags for your extension (comma-separated)",
Placeholder: "tag1, tag2",
RequiredMessage: "Tags are required",
Required: true,
HelpMessage: "Tags are used to categorize your extension. " +
"You can enter multiple tags separated by commas.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for tags: %w", err)
}
namespacePrompt, err := azdClient.Prompt().Prompt(ctx, &azdext.PromptRequest{
Options: &azdext.PromptOptions{
Message: "Enter a namespace for your extension",
RequiredMessage: "Namespace is required",
Required: true,
HelpMessage: "Namespace is used to group custom commands into a single command " +
"group used for executing the extension.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for namespace: %w", err)
}
capabilitiesPrompt, err := azdClient.Prompt().MultiSelect(ctx, &azdext.MultiSelectRequest{
Options: &azdext.MultiSelectOptions{
Message: "Select capabilities for your extension",
Choices: []*azdext.MultiSelectChoice{
{
Label: "Custom Commands",
Value: "custom-commands",
},
{
Label: "Lifecycle Events",
Value: "lifecycle-events",
},
},
EnableFiltering: internal.ToPtr(false),
DisplayNumbers: internal.ToPtr(false),
HelpMessage: "Capabilities define the features and functionalities of your extension. " +
"You can select multiple capabilities.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for capabilities: %w", err)
}
languageChoices := []*azdext.SelectChoice{
{
Label: "Go",
Value: "go",
},
{
Label: "C#",
Value: "dotnet",
},
{
Label: "JavaScript",
Value: "javascript",
},
{
Label: "Python",
Value: "python",
},
}
programmingLanguagePrompt, err := azdClient.Prompt().Select(ctx, &azdext.SelectRequest{
Options: &azdext.SelectOptions{
Message: "Select a programming language for your extension",
Choices: languageChoices,
EnableFiltering: internal.ToPtr(false),
DisplayNumbers: internal.ToPtr(false),
HelpMessage: "Programming language is used to define the language in which your extension is written. " +
"You can select one programming language.",
},
})
if err != nil {
return nil, fmt.Errorf("failed to prompt for programming language: %w", err)
}
capabilities := make([]extensions.CapabilityType, len(capabilitiesPrompt.Values))
for i, capability := range capabilitiesPrompt.Values {
capabilities[i] = extensions.CapabilityType(capability.Value)
}
tags := []string{}
strings.Split(tagsPrompt.Value, ",")
for _, tag := range tags {
tag = strings.TrimSpace(tag)
if tag != "" {
tags = append(tags, tag)
}
}
absExtensionPath, err := filepath.Abs(idPrompt.Value)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path for extension directory: %w", err)
}
return &models.ExtensionSchema{
Id: idPrompt.Value,
DisplayName: displayNamePrompt.Value,
Description: descriptionPrompt.Value,
Namespace: namespacePrompt.Value,
Capabilities: capabilities,
Language: languageChoices[*programmingLanguagePrompt.Value].Value,
Tags: tags,
Usage: fmt.Sprintf("azd %s <command> [options]", namespacePrompt.Value),
Version: "0.0.1",
Path: absExtensionPath,
}, nil
}