From d90d8d0d3f5b97c0eff5f523d466650aeb8aab37 Mon Sep 17 00:00:00 2001 From: Jernej Kos Date: Wed, 8 Jan 2025 14:43:57 +0100 Subject: [PATCH] feat(cmd/rofl): Use cached artifacts when available --- cmd/rofl/build/artifacts.go | 59 +++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/cmd/rofl/build/artifacts.go b/cmd/rofl/build/artifacts.go index e2c2f4f..7e44418 100644 --- a/cmd/rofl/build/artifacts.go +++ b/cmd/rofl/build/artifacts.go @@ -58,33 +58,48 @@ func maybeDownloadArtifact(kind, uri string) string { cobra.CheckErr(fmt.Errorf("failed to create cache directory for %s artifact: %w", kind, err)) } - f, err := os.Create(cacheFn) - if err != nil { - cobra.CheckErr(fmt.Errorf("failed to create file for %s artifact: %w", kind, err)) - } - defer f.Close() + // First attempt to use the cached artifact. + f, err := os.Open(cacheFn) + switch { + case err == nil: + // Already exists in cache. + // TODO: Verify checksum and discard if invalid. + f.Close() + + fmt.Printf(" (using cached artifact)\n") + case errors.Is(err, os.ErrNotExist): + // Does not exist in cache, download. + f, err = os.Create(cacheFn) + if err != nil { + cobra.CheckErr(fmt.Errorf("failed to create file for %s artifact: %w", kind, err)) + } + defer f.Close() - // Download the remote artifact. - res, err := http.Get(uri) //nolint:gosec,noctx - if err != nil { - cobra.CheckErr(fmt.Errorf("failed to download %s artifact: %w", kind, err)) - } - defer res.Body.Close() + // Download the remote artifact. + var res *http.Response + res, err = http.Get(uri) //nolint:gosec,noctx + if err != nil { + cobra.CheckErr(fmt.Errorf("failed to download %s artifact: %w", kind, err)) + } + defer res.Body.Close() - // Compute the SHA256 hash while downloading the artifact. - h := sha256.New() - rd := io.TeeReader(res.Body, h) + // Compute the SHA256 hash while downloading the artifact. + h := sha256.New() + rd := io.TeeReader(res.Body, h) - if _, err = io.Copy(f, rd); err != nil { - cobra.CheckErr(fmt.Errorf("failed to download %s artifact: %w", kind, err)) - } + if _, err = io.Copy(f, rd); err != nil { + cobra.CheckErr(fmt.Errorf("failed to download %s artifact: %w", kind, err)) + } - // Verify integrity if available. - if knownHash != "" { - artifactHash := fmt.Sprintf("%x", h.Sum(nil)) - if artifactHash != knownHash { - cobra.CheckErr(fmt.Errorf("hash mismatch for %s artifact (expected: %s got: %s)", kind, knownHash, artifactHash)) + // Verify integrity if available. + if knownHash != "" { + artifactHash := fmt.Sprintf("%x", h.Sum(nil)) + if artifactHash != knownHash { + cobra.CheckErr(fmt.Errorf("hash mismatch for %s artifact (expected: %s got: %s)", kind, knownHash, artifactHash)) + } } + default: + cobra.CheckErr(fmt.Errorf("failed to open cached %s artifact: %w", kind, err)) } return cacheFn