tool

package
v1.25.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 9, 2026 License: MIT Imports: 31 Imported by: 0

Documentation

Overview

Package tool provides the type system and built-in registry for azd tool definitions.

Tools are external programs, VS Code extensions, servers, or libraries that complement the Azure Developer CLI. Each tool carries detection, versioning, and per-platform installation metadata so that azd can check, install, and upgrade the developer toolchain automatically.

Index

Constants

This section is empty.

Variables

View Source
var FeatureAlphaTool = alpha.MustFeatureKey("tool")

FeatureAlphaTool is the alpha feature key for the azd tool command group.

Functions

func SelectVersionProviders

func SelectVersionProviders(
	tools []*ToolDefinition,
	commandRunner exec.CommandRunner,
	registryCacheManager *extensions.RegistryCacheManager,
	httpClient httpDoer,
) map[string]LatestVersionProvider

SelectVersionProviders builds a map of tool ID to provider for a set of tools. Tools that have no applicable provider are omitted.

Types

type CachedToolVersion

type CachedToolVersion struct {
	// LatestVersion is the most recent version string returned by the
	// remote version API (or left empty when no remote data is available).
	LatestVersion string `json:"latestVersion"`
}

CachedToolVersion stores the latest known version of a single tool.

type Checksum

type Checksum struct {
	// Algorithm is the hash algorithm (e.g. "sha256", "sha512").
	Algorithm string
	// Value is the hex-encoded checksum to compare against.
	Value string
}

Checksum describes the expected hash of a downloaded artifact.

type Detector

type Detector interface {
	// DetectTool probes a single tool and returns its status.
	DetectTool(
		ctx context.Context,
		tool *ToolDefinition,
	) (*ToolStatus, error)

	// DetectAll probes every tool concurrently and returns a status
	// entry for each one. Individual detection failures are captured
	// in [ToolStatus.Error]; the returned error is non-nil only for
	// programming mistakes such as a nil tool pointer.
	DetectAll(
		ctx context.Context,
		tools []*ToolDefinition,
	) ([]*ToolStatus, error)
}

Detector checks whether tools are installed and extracts their versions.

func NewDetector

func NewDetector(commandRunner exec.CommandRunner) Detector

NewDetector creates a Detector backed by the given exec.CommandRunner.

type ExtensionRegistryVersionProvider

type ExtensionRegistryVersionProvider struct {
	// contains filtered or unexported fields
}

ExtensionRegistryVersionProvider queries the azd extension registry for the latest version of a library-category tool.

func NewExtensionRegistryVersionProvider

func NewExtensionRegistryVersionProvider(
	cacheManager *extensions.RegistryCacheManager,
) *ExtensionRegistryVersionProvider

NewExtensionRegistryVersionProvider creates a provider backed by the given registry cache manager.

func (*ExtensionRegistryVersionProvider) GetLatestVersion

func (p *ExtensionRegistryVersionProvider) GetLatestVersion(
	ctx context.Context,
	tool *ToolDefinition,
) (string, error)

GetLatestVersion returns the latest version of the azd extension identified by the tool's Id.

type InstallResult

type InstallResult struct {
	// Tool is the definition that was installed or upgraded.
	Tool *ToolDefinition
	// Success indicates whether the operation completed successfully
	// and the tool is now available on the local machine.
	Success bool
	// InstalledVersion is the version detected after installation.
	InstalledVersion string
	// Strategy describes what was used to install the tool
	// (e.g. "winget", "brew", "manual").
	Strategy string
	// Duration is the wall-clock time the operation took.
	Duration time.Duration
	// Error holds any error encountered during the operation.
	Error error
}

InstallResult captures the outcome of an install or upgrade operation.

type InstallStrategy

type InstallStrategy struct {
	// PackageManager is the package manager name (e.g. "winget", "brew", "apt", "npm", "code").
	PackageManager string
	// PackageId is the identifier within the package manager (e.g. "Microsoft.AzureCLI").
	PackageId string
	// InstallCommand is the full shell command when a simple package-manager install
	// does not apply (e.g. "curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash").
	InstallCommand string
	// DirectDownloadUrl is a URL to a binary or archive that azd downloads
	// directly. When set, azd downloads the artifact, verifies its checksum
	// (if provided), and makes it available locally. This path is used
	// instead of PackageManager or InstallCommand.
	DirectDownloadUrl string
	// Checksum is the expected hash of the artifact referenced by
	// DirectDownloadUrl. When empty, checksum verification is skipped.
	Checksum Checksum
	// FallbackUrl points to manual installation instructions.
	FallbackUrl string
}

InstallStrategy describes how to install a tool on a specific platform.

type Installer

type Installer interface {
	// Install attempts to install the given tool using the best
	// strategy available for the current platform.
	Install(
		ctx context.Context,
		tool *ToolDefinition,
	) (*InstallResult, error)

	// Upgrade attempts to upgrade the given tool to its latest
	// version. When no upgrade-specific command exists the
	// operation falls back to a regular install.
	Upgrade(
		ctx context.Context,
		tool *ToolDefinition,
	) (*InstallResult, error)
}

Installer defines the contract for installing and upgrading tools on the current platform.

func NewInstaller

func NewInstaller(
	commandRunner exec.CommandRunner,
	platformDetector *PlatformDetector,
	detector Detector,
) Installer

NewInstaller creates an Installer backed by the provided dependencies. Platform detection is deferred until the first Install or Upgrade call.

func NewInstallerWithHTTPClient

func NewInstallerWithHTTPClient(
	commandRunner exec.CommandRunner,
	platformDetector *PlatformDetector,
	detector Detector,
	httpClient httpDoer,
) Installer

NewInstallerWithHTTPClient creates an Installer with a custom HTTP client, primarily for testing.

type LatestVersionProvider

type LatestVersionProvider interface {
	// GetLatestVersion returns the latest version string for the given
	// tool, or an error if the version cannot be determined.
	GetLatestVersion(
		ctx context.Context,
		tool *ToolDefinition,
	) (string, error)
}

LatestVersionProvider retrieves the latest available version of a tool from a remote source (package registry, marketplace, etc.).

func SelectVersionProvider

func SelectVersionProvider(
	tool *ToolDefinition,
	commandRunner exec.CommandRunner,
	registryCacheManager *extensions.RegistryCacheManager,
	httpClient httpDoer,
) LatestVersionProvider

SelectVersionProvider returns the appropriate LatestVersionProvider for the given tool based on its category and configuration. Returns nil when no provider applies.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the top-level orchestrator for tool management. It wires together the built-in tool manifest, a Detector for probing the local machine, an Installer for installing and upgrading tools, and an UpdateChecker for periodic update notifications.

func NewManager

func NewManager(
	detector Detector,
	installer Installer,
	updateChecker *UpdateChecker,
) *Manager

NewManager creates a Manager that operates on the built-in tool registry. The detector, installer, and updateChecker are injected so that callers can supply test doubles when needed.

func (*Manager) CheckForUpdates

func (m *Manager) CheckForUpdates(
	ctx context.Context,
) ([]*UpdateCheckResult, error)

CheckForUpdates delegates to the UpdateChecker to check all tools in the manifest for available updates.

func (*Manager) DetectAll

func (m *Manager) DetectAll(
	ctx context.Context,
) ([]*ToolStatus, error)

DetectAll probes every tool in the manifest and returns a status entry for each one. Individual detection failures are captured in each [ToolStatus.Error]; the returned error is non-nil only for programming mistakes such as a nil manifest entry.

func (*Manager) DetectTool

func (m *Manager) DetectTool(
	ctx context.Context,
	id string,
) (*ToolStatus, error)

DetectTool probes a single tool identified by its unique id and returns its ToolStatus. It returns an error when the id is not found in the manifest.

func (*Manager) FindTool

func (m *Manager) FindTool(id string) (*ToolDefinition, error)

FindTool looks up a tool by its unique identifier in the manifest. It returns an error when no tool with that id exists.

func (*Manager) GetAllTools

func (m *Manager) GetAllTools() []*ToolDefinition

GetAllTools returns a shallow clone of the full tool manifest. Callers may safely modify the returned slice without affecting the manager's internal state.

func (*Manager) GetToolsByCategory

func (m *Manager) GetToolsByCategory(
	category ToolCategory,
) []*ToolDefinition

GetToolsByCategory returns every tool in the manifest whose [ToolDefinition.Category] matches the given category.

func (*Manager) HasUpdatesAvailable

func (m *Manager) HasUpdatesAvailable(
	ctx context.Context,
) (bool, int, error)

HasUpdatesAvailable reports whether cached update-check results indicate that one or more tools have updates available. It returns a boolean flag, the count of tools with updates, and any error encountered while reading the cache.

func (*Manager) InstallTools

func (m *Manager) InstallTools(
	ctx context.Context,
	ids []string,
) ([]*InstallResult, error)

InstallTools installs the requested tools by id, automatically resolving and prepending any missing dependencies. Tools are installed in dependency order: if a dependency installation fails the dependent tool is skipped and an error is recorded in its InstallResult.

func (*Manager) MarkUpdateNotificationShown

func (m *Manager) MarkUpdateNotificationShown(
	ctx context.Context,
) error

MarkUpdateNotificationShown records that the user has been notified about available updates so that the notification is not repeated too soon.

func (*Manager) ShouldCheckForUpdates

func (m *Manager) ShouldCheckForUpdates(
	ctx context.Context,
) bool

ShouldCheckForUpdates reports whether enough time has elapsed since the last update check to warrant a new one.

func (*Manager) ShouldShowNotification

func (m *Manager) ShouldShowNotification(
	ctx context.Context,
) bool

ShouldShowNotification reports whether an update notification should be displayed for the current check cycle. It returns false when a notification has already been shown since the last update check.

func (*Manager) UpgradeAll

func (m *Manager) UpgradeAll(
	ctx context.Context,
) ([]*InstallResult, error)

UpgradeAll detects every tool in the manifest, filters to those that are already installed, and upgrades each one.

func (*Manager) UpgradeTools

func (m *Manager) UpgradeTools(
	ctx context.Context,
	ids []string,
) ([]*InstallResult, error)

UpgradeTools upgrades the tools identified by the given ids. Each id is resolved against the manifest and then passed to the installer's Upgrade method.

type MarketplaceVersionProvider

type MarketplaceVersionProvider struct {
	// contains filtered or unexported fields
}

MarketplaceVersionProvider queries the VS Code Marketplace for the latest version of a VS Code extension.

func NewMarketplaceVersionProvider

func NewMarketplaceVersionProvider(
	httpClient httpDoer,
) *MarketplaceVersionProvider

NewMarketplaceVersionProvider creates a provider that uses the given HTTP client for marketplace API calls.

func (*MarketplaceVersionProvider) GetLatestVersion

func (p *MarketplaceVersionProvider) GetLatestVersion(
	ctx context.Context,
	tool *ToolDefinition,
) (string, error)

GetLatestVersion queries the VS Code Marketplace for the latest version of the extension identified by the tool's Id.

type PackageManagerVersionProvider

type PackageManagerVersionProvider struct {
	// contains filtered or unexported fields
}

PackageManagerVersionProvider queries a platform package manager (npm, winget, brew) for the latest available version of a tool.

func NewPackageManagerVersionProvider

func NewPackageManagerVersionProvider(
	commandRunner exec.CommandRunner,
) *PackageManagerVersionProvider

NewPackageManagerVersionProvider creates a provider that uses the given command runner to invoke package manager queries.

func (*PackageManagerVersionProvider) GetLatestVersion

func (p *PackageManagerVersionProvider) GetLatestVersion(
	ctx context.Context,
	tool *ToolDefinition,
) (string, error)

GetLatestVersion queries the package manager configured in the tool's install strategy for the current platform.

type Platform

type Platform struct {
	// OS is the operating system identifier returned by runtime.GOOS
	// (e.g. "windows", "darwin", "linux").
	OS string
	// AvailableManagers lists the package managers detected on the system
	// (e.g. ["winget", "npm"]).
	AvailableManagers []string
}

Platform describes the detected operating system and the package managers that were found on the local machine.

func (*Platform) HasManager

func (p *Platform) HasManager(name string) bool

HasManager reports whether the named package manager was detected on this platform.

type PlatformDetector

type PlatformDetector struct {
	// contains filtered or unexported fields
}

PlatformDetector discovers the current operating system and probes for available package managers using a exec.CommandRunner.

func NewPlatformDetector

func NewPlatformDetector(commandRunner exec.CommandRunner) *PlatformDetector

NewPlatformDetector creates a PlatformDetector that uses the provided CommandRunner to probe for package manager availability.

func (*PlatformDetector) Detect

func (pd *PlatformDetector) Detect(ctx context.Context) (*Platform, error)

Detect identifies the current platform by reading runtime.GOOS and checking each known package manager for availability. Managers that are not found are silently skipped; the method only returns an error for unexpected failures.

func (*PlatformDetector) IsManagerAvailable

func (pd *PlatformDetector) IsManagerAvailable(
	ctx context.Context,
	manager string,
) bool

IsManagerAvailable reports whether the named package manager can be found on the system PATH and responds to a --version invocation. A manager that cannot be located or executed is considered unavailable.

func (*PlatformDetector) SelectStrategy

func (pd *PlatformDetector) SelectStrategy(
	tool *ToolDefinition,
	platform *Platform,
) *InstallStrategy

SelectStrategy returns the best install strategy for the given tool on the detected platform. It returns nil when no strategy is defined for the platform's OS. When the strategy names a PackageManager that is not present in platform.AvailableManagers the strategy is still returned — the caller (installer) is responsible for handling the fallback.

type ToolCategory

type ToolCategory string

ToolCategory classifies a tool by its runtime shape.

const (
	// ToolCategoryCLI is a standalone command-line binary (e.g. az, copilot).
	ToolCategoryCLI ToolCategory = "cli"
	// ToolCategoryExtension is an IDE extension (e.g. VS Code extensions).
	ToolCategoryExtension ToolCategory = "extension"
	// ToolCategoryServer is a long-running background process or server (e.g. MCP server).
	ToolCategoryServer ToolCategory = "server"
	// ToolCategoryLibrary is an azd extension or plugin library.
	ToolCategoryLibrary ToolCategory = "library"
)

type ToolDefinition

type ToolDefinition struct {
	// Id is the unique, kebab-case identifier for the tool (e.g. "az-cli").
	Id string
	// Name is the human-readable display name.
	Name string
	// Description summarizes what the tool does in one sentence.
	Description string
	// Category classifies the tool (CLI, extension, server, or library).
	Category ToolCategory
	// Priority indicates whether the tool is recommended or optional.
	Priority ToolPriority
	// Website is the canonical documentation URL.
	Website string
	// DetectCommand is the binary name used to verify the tool is installed (e.g. "az").
	DetectCommand string
	// VersionArgs are the CLI arguments that print a version string (e.g. ["--version"]).
	VersionArgs []string
	// VersionRegex is a Go regular expression with a capture group for the semver portion
	// of the version output (e.g. `azure-cli\s+(\d+\.\d+\.\d+)`).
	VersionRegex string
	// InstallStrategies maps a GOOS value ("windows", "darwin", "linux") to the
	// platform-specific installation strategy.
	InstallStrategies map[string]InstallStrategy
	// Dependencies lists the IDs of tools that must be installed before this one.
	Dependencies []string
}

ToolDefinition is the complete metadata for a single tool in the registry.

func BuiltInTools

func BuiltInTools() []*ToolDefinition

BuiltInTools returns the full set of tools that ship with the azd tool registry. The returned slice is a fresh copy; callers may safely append or modify it.

func FindTool

func FindTool(id string) *ToolDefinition

FindTool returns the built-in tool with the given id, or nil if none matches.

func FindToolsByCategory

func FindToolsByCategory(category ToolCategory) []*ToolDefinition

FindToolsByCategory returns every built-in tool whose category matches. The returned slice is a fresh copy.

type ToolPriority

type ToolPriority string

ToolPriority indicates how strongly a tool is recommended.

const (
	// ToolPriorityRecommended marks a tool that most azd users should install.
	ToolPriorityRecommended ToolPriority = "recommended"
	// ToolPriorityOptional marks a tool that is useful but not essential.
	ToolPriorityOptional ToolPriority = "optional"
)

type ToolStatus

type ToolStatus struct {
	// Tool is the definition that was probed.
	Tool *ToolDefinition
	// Installed is true when the tool was found on the local machine.
	Installed bool
	// InstalledVersion is the version string extracted from the tool's
	// output. It is empty when the tool is not installed or when
	// version parsing fails.
	InstalledVersion string
	// Error records any unexpected failure during detection (e.g. a
	// timeout). A tool that is simply not installed has Error == nil.
	Error error
}

ToolStatus captures the detection result for a single tool.

type UpdateCheckCache

type UpdateCheckCache struct {
	// CheckedAt is the time the cache was last populated.
	CheckedAt time.Time `json:"checkedAt"`
	// ExpiresAt is the earliest time the cache should be refreshed.
	ExpiresAt time.Time `json:"expiresAt"`
	// Tools maps tool IDs to their cached version information.
	Tools map[string]CachedToolVersion `json:"tools"`
}

UpdateCheckCache is the on-disk representation of a tool update check result set. It is serialized as JSON and written to ~/.azd/tool-check-cache.json.

type UpdateCheckResult

type UpdateCheckResult struct {
	// Tool is the registry definition that was checked.
	Tool *ToolDefinition
	// CurrentVersion is the version currently installed on the local
	// machine (empty when the tool is not installed).
	CurrentVersion string
	// LatestVersion is the newest version known to the update checker.
	LatestVersion string
	// UpdateAvailable is true when LatestVersion is non-empty and
	// differs from CurrentVersion.
	UpdateAvailable bool
}

UpdateCheckResult pairs a tool definition with its current and latest version information so callers can determine whether an upgrade is available.

type UpdateChecker

type UpdateChecker struct {
	// contains filtered or unexported fields
}

UpdateChecker performs periodic update checks for registered tools, caching results to disk so that expensive remote lookups are amortized across CLI invocations.

func NewUpdateChecker

func NewUpdateChecker(
	configManager config.UserConfigManager,
	detector Detector,
	configDirFn func() (string, error),
	versionProviders map[string]LatestVersionProvider,
) *UpdateChecker

NewUpdateChecker creates an UpdateChecker that resolves its cache file location lazily via configDirFn. This avoids blocking I/O (e.g. config.GetUserConfigDir) during IoC container registration.

func (*UpdateChecker) Check

func (uc *UpdateChecker) Check(
	ctx context.Context,
	tools []*ToolDefinition,
) ([]*UpdateCheckResult, error)

Check runs the update check for the supplied tools. It detects the currently installed versions, queries version providers for the latest available versions (using cached data when not expired), persists the results, and updates the last-check timestamp.

func (*UpdateChecker) GetCachedResults

func (uc *UpdateChecker) GetCachedResults() (*UpdateCheckCache, error)

GetCachedResults reads and returns the on-disk update check cache. It returns (nil, nil) when the cache file does not yet exist or cannot be read. Corrupt cache files are removed so they can be regenerated on the next check cycle.

func (*UpdateChecker) HasUpdatesAvailable

func (uc *UpdateChecker) HasUpdatesAvailable(
	ctx context.Context,
	tools []*ToolDefinition,
) (bool, int, error)

HasUpdatesAvailable checks the cache for tools whose latest known version differs from the currently installed version. It returns whether any updates exist, how many, and any error encountered while reading the cache or detecting versions. The caller provides the tool definitions to resolve cached IDs against, avoiding a dependency on the package-level manifest.

func (*UpdateChecker) MarkNotificationShown

func (uc *UpdateChecker) MarkNotificationShown(
	ctx context.Context,
) error

MarkNotificationShown records the current time as the last moment an update notification was displayed, preventing repeated notifications within the same check cycle.

func (*UpdateChecker) SaveCache

func (uc *UpdateChecker) SaveCache(cache *UpdateCheckCache) error

SaveCache serializes the cache to disk, creating any intermediate directories as needed.

func (*UpdateChecker) ShouldCheck

func (uc *UpdateChecker) ShouldCheck(ctx context.Context) bool

ShouldCheck returns true when enough time has elapsed since the last update check and automatic checks have not been disabled by the user.

func (*UpdateChecker) ShouldShowNotification

func (uc *UpdateChecker) ShouldShowNotification(
	ctx context.Context,
) bool

ShouldShowNotification returns true when an update notification has not yet been shown for the most recent check cycle.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL