downloadCopilot downloads and installs the Copilot CLI to installDir. It returns the path to the installed Copilot binary.
(httpClient *http.Client, ios *iostreams.IOStreams, installDir, localPath string)
| 237 | // downloadCopilot downloads and installs the Copilot CLI to installDir. |
| 238 | // It returns the path to the installed Copilot binary. |
| 239 | func downloadCopilot(httpClient *http.Client, ios *iostreams.IOStreams, installDir, localPath string) (string, error) { |
| 240 | platform := runtime.GOOS |
| 241 | if platform == "windows" { |
| 242 | platform = "win32" |
| 243 | } |
| 244 | |
| 245 | arch := runtime.GOARCH |
| 246 | if arch == "amd64" { |
| 247 | arch = "x64" |
| 248 | } |
| 249 | |
| 250 | if arch != "x64" && arch != "arm64" { |
| 251 | return "", fmt.Errorf("unsupported architecture: %s (supported: x64, arm64)", arch) |
| 252 | } |
| 253 | |
| 254 | var archiveName string |
| 255 | var isZip bool |
| 256 | switch platform { |
| 257 | case "win32": |
| 258 | archiveName = fmt.Sprintf("copilot-%s-%s.zip", platform, arch) |
| 259 | isZip = true |
| 260 | case "linux", "darwin": |
| 261 | archiveName = fmt.Sprintf("copilot-%s-%s.tar.gz", platform, arch) |
| 262 | default: |
| 263 | return "", fmt.Errorf("unsupported platform: %s (supported: linux, darwin, windows)", platform) |
| 264 | } |
| 265 | |
| 266 | archiveURL, err := safeurl.JoinPathWithHostPrefix("https://github.com/", "github", "copilot-cli", "releases", "latest", "download", archiveName) |
| 267 | if err != nil { |
| 268 | return "", err |
| 269 | } |
| 270 | |
| 271 | checksumsURL, err := safeurl.JoinPathWithHostPrefix("https://github.com/", "github", "copilot-cli", "releases", "latest", "download", "SHA256SUMS.txt") |
| 272 | if err != nil { |
| 273 | return "", err |
| 274 | } |
| 275 | |
| 276 | expectedChecksum, err := fetchExpectedChecksum(httpClient, checksumsURL, archiveName) |
| 277 | if err != nil { |
| 278 | return "", fmt.Errorf("failed to fetch checksums: %w", err) |
| 279 | } |
| 280 | |
| 281 | ios.StartProgressIndicatorWithLabel(fmt.Sprintf("Downloading Copilot CLI from %s", archiveURL.String())) |
| 282 | defer ios.StopProgressIndicator() |
| 283 | |
| 284 | resp, err := httpClient.Get(archiveURL.String()) |
| 285 | if err != nil { |
| 286 | return "", fmt.Errorf("failed to download: %w", err) |
| 287 | } |
| 288 | defer resp.Body.Close() |
| 289 | |
| 290 | if resp.StatusCode != http.StatusOK { |
| 291 | return "", fmt.Errorf("download failed with status: %s", resp.Status) |
| 292 | } |
| 293 | |
| 294 | // Download to temp file while calculating checksum |
| 295 | tmpFile, err := os.CreateTemp("", "copilot-download-*") |
| 296 | if err != nil { |