func runInitAction()

in cli/azd/extensions/microsoft.azd.extensions/internal/cmd/init.go [133:334]


func runInitAction(ctx context.Context, flags *initFlags) error {
	// Create a new context that includes the AZD access token
	ctx = azdext.WithAccessToken(ctx)

	// Create a new AZD client
	azdClient, err := azdext.NewAzdClient()
	if err != nil {
		return fmt.Errorf("failed to create azd client: %w", err)
	}

	defer azdClient.Close()

	var extensionMetadata *models.ExtensionSchema
	if flags.noPrompt {
		// In headless mode, use the provided command-line arguments
		extensionMetadata, err = collectExtensionMetadataFromFlags(flags)
		if err != nil {
			return err
		}
	} else if !flags.createRegistry {
		// Interactive mode - collect metadata through prompts
		extensionMetadata, err = collectExtensionMetadata(ctx, azdClient)
		if err != nil {
			return fmt.Errorf("failed to collect extension metadata: %w", err)
		}

		fmt.Println()
		confirmResponse, err := azdClient.
			Prompt().
			Confirm(ctx, &azdext.ConfirmRequest{
				Options: &azdext.ConfirmOptions{
					Message:      fmt.Sprintf("Continue creating the extension at %s?", extensionMetadata.Id),
					DefaultValue: internal.ToPtr(false),
					Placeholder:  "no",
					HelpMessage:  "Confirm if you want to continue creating the extension.",
				},
			})
		if err != nil {
			return fmt.Errorf("failed to confirm extension, %w", err)
		}

		if !*confirmResponse.Value {
			return errors.New("extension creation cancelled by user")
		}
	}

	localRegistryExists := false

	createLocalExtensionSourceAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		if has, err := hasLocalRegistry(); err == nil && has {
			localRegistryExists = true
			return ux.Skipped, nil
		}

		if err := createLocalRegistry(); err != nil {
			return ux.Error, common.NewDetailedError(
				"Registry creation failed",
				fmt.Errorf("failed to create local registry: %w", err),
			)
		}

		return ux.Success, nil
	}

	createExtensionDirectoryAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		if err := createExtensionDirectory(ctx, azdClient, extensionMetadata); err != nil {
			return ux.Error, common.NewDetailedError(
				"Error creating directory",
				fmt.Errorf("failed to create extension directory: %w", err),
			)
		}

		return ux.Success, nil
	}

	buildExtensionAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		cmd := exec.Command("azd", "x", "build", "--skip-install")
		cmd.Dir = extensionMetadata.Path

		if err := cmd.Run(); err != nil {
			return ux.Error, common.NewDetailedError(
				"Build failed",
				fmt.Errorf("failed to build extension: %w", err),
			)
		}

		return ux.Success, nil
	}

	packageExtensionAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		cmd := exec.Command("azd", "x", "pack")
		cmd.Dir = extensionMetadata.Path

		if err := cmd.Run(); err != nil {
			return ux.Error, common.NewDetailedError(
				"Package failed",
				fmt.Errorf("failed to package extension: %w", err),
			)
		}
		return ux.Success, nil
	}

	publishExtensionAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		cmd := exec.Command("azd", "x", "publish")
		cmd.Dir = extensionMetadata.Path

		if err := cmd.Run(); err != nil {
			return ux.Error, common.NewDetailedError(
				"Publish failed",
				fmt.Errorf("failed to package extension: %w", err),
			)
		}
		return ux.Success, nil
	}

	installExtensionAction := func(spf ux.SetProgressFunc) (ux.TaskState, error) {
		/* #nosec G204 - Subprocess launched with a potential tainted input or cmd arguments */
		cmd := exec.Command("azd", "ext", "install", extensionMetadata.Id, "--source", "local")
		cmd.Dir = extensionMetadata.Path

		if err := cmd.Run(); err != nil {
			return ux.Error, common.NewDetailedError(
				"Install failed",
				fmt.Errorf("failed to install extension: %w", err),
			)
		}
		return ux.Success, nil
	}

	taskList := ux.NewTaskList(nil)

	if flags.createRegistry {
		taskList.AddTask(ux.TaskOptions{
			Title:  "Create local azd extension source",
			Action: createLocalExtensionSourceAction,
		})
	} else {
		taskList.
			AddTask(ux.TaskOptions{
				Title:  "Create local azd extension source",
				Action: createLocalExtensionSourceAction,
			}).
			AddTask(ux.TaskOptions{
				Title:  fmt.Sprintf("Creating extension directory %s", output.WithHighLightFormat(extensionMetadata.Id)),
				Action: createExtensionDirectoryAction,
			}).
			AddTask(ux.TaskOptions{
				Title:  "Build extension",
				Action: buildExtensionAction,
			}).
			AddTask(ux.TaskOptions{
				Title:  "Package extension",
				Action: packageExtensionAction,
			}).
			AddTask(ux.TaskOptions{
				Title:  "Publish extension to local extension source",
				Action: publishExtensionAction,
			}).
			AddTask(ux.TaskOptions{
				Title:  "Install extension",
				Action: installExtensionAction,
			})
	}

	if err := taskList.Run(); err != nil {
		return fmt.Errorf("failed running init tasks: %w", err)
	}

	if localRegistryExists {
		fmt.Println(output.WithWarningFormat("Local extension source already exists."))
		fmt.Println()
	}

	if !flags.createRegistry {
		fmt.Println(output.WithBold("Try out the extension"))
		fmt.Printf(
			"- Run %s to try your extension now.\n",
			output.WithHighLightFormat("azd %s -h", extensionMetadata.Namespace),
		)
		fmt.Println()
		fmt.Println(output.WithBold("Next Steps"))
		fmt.Printf(
			"- Navigate to the %s directory and start building your extension.\n",
			output.WithHighLightFormat(extensionMetadata.Id),
		)
		fmt.Println()
		fmt.Println(output.WithBold("Iterate on the extension"))
		fmt.Printf(
			"- Run %s to watch for code changes and auto re-build the extension\n",
			output.WithHighLightFormat("azd x watch"),
		)
		fmt.Printf("- Run %s to rebuild the extension\n", output.WithHighLightFormat("azd x build"))
		fmt.Println()
		fmt.Println(output.WithBold("Package, release and publish the extension"))
		fmt.Printf("- Run %s to package the extension\n", output.WithHighLightFormat("azd x pack"))
		fmt.Printf("- Run %s to create a GitHub release for your extension\n", output.WithHighLightFormat("azd x release"))
		fmt.Printf("- Run %s to publish the extension\n", output.WithHighLightFormat("azd x publish"))
		fmt.Println()
	}

	return nil
}