doInstall performs the actual package resolution and installation.
(ctx context.Context, command, versionRef string)
| 95 | |
| 96 | // doInstall performs the actual package resolution and installation. |
| 97 | func doInstall(ctx context.Context, command, versionRef string) (string, error) { |
| 98 | // Re-check bin dir under singleflight — another goroutine may have |
| 99 | // just finished installing while we were waiting. |
| 100 | binPath := filepath.Join(BinDir(), command) |
| 101 | if info, err := os.Stat(binPath); err == nil && info.Mode()&0o111 != 0 { |
| 102 | return binPath, nil |
| 103 | } |
| 104 | |
| 105 | registry := SharedRegistry() |
| 106 | |
| 107 | pkg, version, err := lookupPackage(ctx, registry, command, versionRef) |
| 108 | if err != nil { |
| 109 | return "", err |
| 110 | } |
| 111 | |
| 112 | if version == "" { |
| 113 | version, err = resolveVersion(ctx, registry, pkg) |
| 114 | if err != nil { |
| 115 | return "", fmt.Errorf("resolving latest version for %s/%s: %w", pkg.RepoOwner, pkg.RepoName, err) |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | pkgName := pkg.RepoOwner + "/" + pkg.RepoName |
| 120 | slog.InfoContext(ctx, "Auto-installing missing command", |
| 121 | "command", command, "package", pkgName, "version", version) |
| 122 | announceInstall(command, pkgName, version) |
| 123 | |
| 124 | binaryPath, err := registry.Install(ctx, pkg, version) |
| 125 | if err != nil { |
| 126 | return "", fmt.Errorf("installing %s@%s: %w", pkgName, version, err) |
| 127 | } |
| 128 | |
| 129 | slog.InfoContext(ctx, "Successfully installed command", |
| 130 | "command", command, "package", fmt.Sprintf("%s@%s", pkgName, version), "path", binaryPath) |
| 131 | |
| 132 | return binaryPath, nil |
| 133 | } |
| 134 | |
| 135 | // announceInstall prints a single user-visible line to stderr right |
| 136 | // before downloading a tool, so the user understands what the |
nothing calls this directly
no test coverage detected