Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions internal/strategy/gomod/private_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import (
"io"
"io/fs"
"log/slog"
"os"
"os/exec"
"path/filepath"
"sort"
"strings"
"time"

"github.com/alecthomas/errors"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
modzip "golang.org/x/mod/zip"

"github.com/block/cachew/internal/gitclone"
)
Expand Down Expand Up @@ -284,21 +288,28 @@ func (p *privateFetcher) generateMod(ctx context.Context, repo *gitclone.Reposit
}

func (p *privateFetcher) generateZip(ctx context.Context, repo *gitclone.Repository, modulePath, version string) (io.ReadSeekCloser, error) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't recall when this is run, is it only if we don't already have a zip in the cache for the given version?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, at least that's what I recall I did. I'll double check.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, this only gets called if it's not in the cache. The gomod proxy lib will add it to the cache.

prefix := fmt.Sprintf("%s@%s/", modulePath, version)
output, err := gitclone.WithReadLockReturn(repo, func() ([]byte, error) {
// #nosec G204 - version and repo.Path() are controlled by this package, not user input
cmd := exec.CommandContext(ctx, "git", "-C", repo.Path(), "archive",
"--format=zip",
fmt.Sprintf("--prefix=%s", prefix),
version)
return cmd.CombinedOutput()
})

tmpDir, err := os.MkdirTemp("", "gomod-zip-*")
if err != nil {
return nil, errors.Wrapf(err, "git archive failed: %s", string(output))
return nil, errors.Wrap(err, "create temp dir")
}
defer os.RemoveAll(tmpDir) //nolint:errcheck

cloneDir := filepath.Join(tmpDir, "repo")

// Local clone from the mirror at the requested version — git hardlinks objects by default.
// #nosec G204 - repo.Path(), version, and cloneDir are controlled by us
cmd := exec.CommandContext(ctx, "git", "clone", "--branch", version, repo.Path(), cloneDir)
if output, err := cmd.CombinedOutput(); err != nil {
return nil, errors.Wrapf(err, "git clone: %s", string(output))
}

var buf bytes.Buffer
m := module.Version{Path: modulePath, Version: version}
if err := modzip.CreateFromDir(&buf, m, cloneDir); err != nil {
return nil, errors.Wrap(err, "create module zip")
}

return newReadSeekCloser(bytes.NewReader(output)), nil
return newReadSeekCloser(bytes.NewReader(buf.Bytes())), nil
}

type readSeekCloser struct {
Expand Down