Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meta-copy-symlinks-new-actions-cache #2337

Merged
merged 7 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion pkg/filecollector/file_collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (cc *CopyCollector) WriteFile(fpath string, fi fs.FileInfo, linkName string
if err := os.MkdirAll(filepath.Dir(fdestpath), 0o777); err != nil {
return err
}
if f == nil {
if linkName != "" {
return os.Symlink(linkName, fdestpath)
}
df, err := os.OpenFile(fdestpath, os.O_CREATE|os.O_WRONLY, fi.Mode())
Expand Down
138 changes: 100 additions & 38 deletions pkg/runner/action_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"io/fs"
"path"
"strings"
"time"

git "github.com/go-git/go-git/v5"
config "github.com/go-git/go-git/v5/config"
Expand Down Expand Up @@ -78,6 +80,44 @@
return hash.String(), nil
}

type GitFileInfo struct {
name string
size int64
modTime time.Time
isDir bool
mode fs.FileMode
}

// IsDir implements fs.FileInfo.
func (g *GitFileInfo) IsDir() bool {
return g.isDir

Check warning on line 93 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L92-L93

Added lines #L92 - L93 were not covered by tests
}

// ModTime implements fs.FileInfo.
func (g *GitFileInfo) ModTime() time.Time {
return g.modTime
}

// Mode implements fs.FileInfo.
func (g *GitFileInfo) Mode() fs.FileMode {
return g.mode
}

// Name implements fs.FileInfo.
func (g *GitFileInfo) Name() string {
return g.name
}

// Size implements fs.FileInfo.
func (g *GitFileInfo) Size() int64 {
return g.size
}

// Sys implements fs.FileInfo.
func (g *GitFileInfo) Sys() any {
return nil
}

func (c GoGitActionCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) {
gitPath := path.Join(c.Path, safeFilename(cacheDir)+".git")
gogitrepo, err := git.PlainOpen(gitPath)
Expand All @@ -88,6 +128,10 @@
if err != nil {
return nil, err
}
t, err := commit.Tree()
if err != nil {
return nil, err

Check warning on line 133 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L133

Added line #L133 was not covered by tests
}
files, err := commit.Files()
if err != nil {
return nil, err
Expand All @@ -108,45 +152,63 @@
tw := tar.NewWriter(wpipe)
cleanIncludePrefix := path.Clean(includePrefix)
wpipe.CloseWithError(files.ForEach(func(f *object.File) error {
if err := ctx.Err(); err != nil {
return err
}
name := f.Name
if strings.HasPrefix(name, cleanIncludePrefix+"/") {
name = name[len(cleanIncludePrefix)+1:]
} else if cleanIncludePrefix != "." && name != cleanIncludePrefix {
return nil
}
fmode, err := f.Mode.ToOSFileMode()
if err != nil {
return err
}
if fmode&fs.ModeSymlink == fs.ModeSymlink {
content, err := f.Contents()
if err != nil {
return err
}
return tw.WriteHeader(&tar.Header{
Name: name,
Mode: int64(fmode),
Linkname: content,
})
}
err = tw.WriteHeader(&tar.Header{
Name: name,
Mode: int64(fmode),
Size: f.Size,
})
if err != nil {
return err
}
reader, err := f.Reader()
if err != nil {
return err
}
_, err = io.Copy(tw, reader)
return err
return actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, f.Name, f)
}))
}()
return rpipe, err
}

func actionCacheCopyFileOrDir(ctx context.Context, cleanIncludePrefix string, t *object.Tree, tw *tar.Writer, origin string, f *object.File) error {
if err := ctx.Err(); err != nil {
return err

Check warning on line 163 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L163

Added line #L163 was not covered by tests
}
name := origin
if strings.HasPrefix(name, cleanIncludePrefix+"/") {
name = name[len(cleanIncludePrefix)+1:]
} else if cleanIncludePrefix != "." && name != cleanIncludePrefix {
return nil
}
fmode, err := f.Mode.ToOSFileMode()
if err != nil {
return err

Check warning on line 173 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L173

Added line #L173 was not covered by tests
}
if fmode&fs.ModeSymlink == fs.ModeSymlink {
content, err := f.Contents()
if err != nil {
return err

Check warning on line 178 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L176-L178

Added lines #L176 - L178 were not covered by tests
}

destPath := path.Join(path.Dir(f.Name), content)

Check warning on line 181 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L181

Added line #L181 was not covered by tests

subtree, err := t.Tree(destPath)
if err == nil {
return subtree.Files().ForEach(func(ft *object.File) error {
return actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, origin+strings.TrimPrefix(ft.Name, f.Name), f)
})

Check warning on line 187 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L183-L187

Added lines #L183 - L187 were not covered by tests
}

f, err := t.File(destPath)
if err != nil {
return fmt.Errorf("%s (%s): %w", destPath, origin, err)

Check warning on line 192 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L190-L192

Added lines #L190 - L192 were not covered by tests
}
return actionCacheCopyFileOrDir(ctx, cleanIncludePrefix, t, tw, origin, f)

Check warning on line 194 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L194

Added line #L194 was not covered by tests
}
header, err := tar.FileInfoHeader(&GitFileInfo{
name: name,
mode: fmode,
size: f.Size,
}, "")
if err != nil {
return err

Check warning on line 202 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L202

Added line #L202 was not covered by tests
}
err = tw.WriteHeader(header)
if err != nil {
return err

Check warning on line 206 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L206

Added line #L206 was not covered by tests
}
reader, err := f.Reader()
if err != nil {
return err

Check warning on line 210 in pkg/runner/action_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/runner/action_cache.go#L210

Added line #L210 was not covered by tests
}
_, err = io.Copy(tw, reader)
return err
}
Loading