Azure / Azure/azure-dev

pkg/extensions: dependency-aware uninstall and extension ownership

Open
#8,258 0 comments 0 reactions 1 assignee Claimed by @JeffreyCA View on GitHub
area/extensions area/ux enhancement
Dominant language
Go
Stars
569
Forks
364
Avg merge
2d 19h
Merged PRs (30d)
136

Description

### Summary

`azd extension install` and `azd extension update` understand extension dependencies: installing a pack such as `microsoft.foundry` pulls in every extension it declares, and updating a pack reconciles the installed dependency versions. `azd extension uninstall` has no dependency awareness at all. It removes exactly the ids it was given and nothing else, and it does not check whether anything else still needs them.

azd also does not record, on the installed extension, why it was installed or what it depends on. The record under `extension.installed` in `config.json` has the id, version, source, and capabilities, but no dependency list and no distinction between "the user asked for this" and "this came along with a pack". So even if uninstall wanted to reason about dependencies, it has nothing to reason with unless the registry is reachable and still lists the extension.

### Repro

Using the main `azd` registry today:

```
azd extension install microsoft.foundry
```

installs the pack (which has no binary of its own) plus seven dependencies: `azure.ai.agents`, `azure.ai.connections`, `azure.ai.inspector`, `azure.ai.projects`, `azure.ai.routines`, `azure.ai.skills`, `azure.ai.toolboxes`. `azure.ai.agents` itself depends on `azure.ai.inspector` and `azure.ai.projects`, so those two are both shared and transitive dependencies.

1. `azd extension uninstall microsoft.foundry` removes only the empty pack record. All seven dependencies stay installed with no hint that nothing requires them anymore.
2. `azd extension uninstall azure.ai.projects` succeeds silently, leaving `azure.ai.agents` (and the pack) installed but missing a dependency they declare.
3. `azd extension show azure.ai.projects` cannot tell you that `azure.ai.agents` and `microsoft.foundry` require it, and `azd extension show microsoft.foundry` does not list its dependencies at all. Neither works for an extension that was installed from a bundle or has since been delisted, because `show` requires a registry hit.

### Gaps

- Uninstalling a parent leaves dependencies behind with no indication that they may now be unused.
- Uninstalling a dependency can silently break installed parents that still require it.
- Shared and transitive dependencies (the `azure.ai.inspector` / `azure.ai.projects` shape above) have no safe handling in either direction.
- `azd extension show` cannot explain an installed extension's dependencies or reverse dependencies without current registry metadata, and prints blank rows (`Namespace :`, an empty `Usage` section) for packs.

### Proposed behavior

Follow the model package managers such as Homebrew and apt use: remember whether an extension was installed on request or as a dependency, refuse to remove something other installed extensions require, and clean up dependencies nothing needs anymore.

- Record two new optional fields on the installed extension: a snapshot of the installed version's declared `dependencies`, and `installedAsDependency`. Reverse dependencies are computed from the snapshots, so nothing goes stale. Updates preserve the flag, and `azd extension install ` on a dependency-installed extension flips it to explicit.
- `azd extension uninstall ` removes the target, then any dependency that was installed as a dependency and is no longer required by anything remaining, transitively, listing each removed and each kept dependency with the reason. `--no-dependencies` keeps them all.
- Uninstalling an extension that other installed extensions require fails before anything is removed, names the dependents, and suggests uninstalling them first. `--force` proceeds with a warning.
- Naming several extensions in one command treats them as one removal set, so `azd extension uninstall microsoft.foundry azure.ai.agents` is not blocked by the pack requiring agents.
- `azd extension show` lists dependencies (with installed versions and whether they satisfy the constraint) and a Required By section, works for installed extensions absent from every registry, prefers the installed source when several sources match, and drops the empty rows.
- Records written before this change carry no ownership data and are treated conservatively: never auto-removed, never blocking. `azd extension update` backfills the dependency snapshot, so existing installs gain reverse-dependency protection after one update.

Expected result for the repro:

```
azd extension uninstall azure.ai.projects
# ERROR: extension azure.ai.projects is required by installed extensions: azure.ai.agents, microsoft.foundry
# Suggestion: Uninstall the dependent extensions first with 'azd extension uninstall azure.ai.agents microsoft.foundry', or pass --force to remove it anyway.

azd extension uninstall microsoft.foundry
# (✓) Done: Uninstalling microsoft.foundry (1.0.0-beta.2)
# (✓) Done: Uninstalling azure.ai.agents dependency (1.0.0-beta.13, no longer required)
# (✓) Done: Uninstalling azure.ai.connections dependency (1.0.0-beta.1, no longer required)
# ... (all seven removed)
```

### Out of scope

- Cascading removal of dependents (replaced by the blocking error plus `--force`).
- Removing or hinting about dependencies that become unreferenced when a pack update drops them.
- Consulting `azure.yaml` during uninstall; project auto-install reinstalls anything the project still requires.
- Changes to `azd extension list`, a `--dry-run` flag, or JSON output for uninstall.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.