github.com/nektos/act@v0.2.63/pkg/runner/local_repository_cache.go (about) 1 package runner 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "context" 7 "fmt" 8 "io" 9 "io/fs" 10 goURL "net/url" 11 "os" 12 "path/filepath" 13 "strings" 14 15 "github.com/nektos/act/pkg/filecollector" 16 ) 17 18 type LocalRepositoryCache struct { 19 Parent ActionCache 20 LocalRepositories map[string]string 21 CacheDirCache map[string]string 22 } 23 24 func (l *LocalRepositoryCache) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) { 25 if dest, ok := l.LocalRepositories[fmt.Sprintf("%s@%s", url, ref)]; ok { 26 l.CacheDirCache[fmt.Sprintf("%s@%s", cacheDir, ref)] = dest 27 return ref, nil 28 } 29 if purl, err := goURL.Parse(url); err == nil { 30 if dest, ok := l.LocalRepositories[fmt.Sprintf("%s@%s", strings.TrimPrefix(purl.Path, "/"), ref)]; ok { 31 l.CacheDirCache[fmt.Sprintf("%s@%s", cacheDir, ref)] = dest 32 return ref, nil 33 } 34 } 35 return l.Parent.Fetch(ctx, cacheDir, url, ref, token) 36 } 37 38 func (l *LocalRepositoryCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) { 39 // sha is mapped to ref in fetch if there is a local override 40 if dest, ok := l.CacheDirCache[fmt.Sprintf("%s@%s", cacheDir, sha)]; ok { 41 srcPath := filepath.Join(dest, includePrefix) 42 buf := &bytes.Buffer{} 43 tw := tar.NewWriter(buf) 44 defer tw.Close() 45 srcPath = filepath.Clean(srcPath) 46 fi, err := os.Lstat(srcPath) 47 if err != nil { 48 return nil, err 49 } 50 tc := &filecollector.TarCollector{ 51 TarWriter: tw, 52 } 53 if fi.IsDir() { 54 srcPrefix := srcPath 55 if !strings.HasSuffix(srcPrefix, string(filepath.Separator)) { 56 srcPrefix += string(filepath.Separator) 57 } 58 fc := &filecollector.FileCollector{ 59 Fs: &filecollector.DefaultFs{}, 60 SrcPath: srcPath, 61 SrcPrefix: srcPrefix, 62 Handler: tc, 63 } 64 err = filepath.Walk(srcPath, fc.CollectFiles(ctx, []string{})) 65 if err != nil { 66 return nil, err 67 } 68 } else { 69 var f io.ReadCloser 70 var linkname string 71 if fi.Mode()&fs.ModeSymlink != 0 { 72 linkname, err = os.Readlink(srcPath) 73 if err != nil { 74 return nil, err 75 } 76 } else { 77 f, err = os.Open(srcPath) 78 if err != nil { 79 return nil, err 80 } 81 defer f.Close() 82 } 83 err := tc.WriteFile(fi.Name(), fi, linkname, f) 84 if err != nil { 85 return nil, err 86 } 87 } 88 return io.NopCloser(buf), nil 89 } 90 return l.Parent.GetTarArchive(ctx, cacheDir, sha, includePrefix) 91 }