-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add caching support for codebase and binary download (#15)
- Loading branch information
1 parent
2c0ec2f
commit 44b6d9c
Showing
7 changed files
with
273 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package cache | ||
|
||
import ( | ||
"crypto/sha1" | ||
"encoding/hex" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/rogpeppe/go-internal/lockedfile" | ||
"golang.org/x/exp/slog" | ||
) | ||
|
||
const ( | ||
completionMarkerFile = ".done" | ||
) | ||
|
||
func Add(key string, addItem func() error) error { | ||
if err := os.MkdirAll(key, 0700); err != nil { | ||
return errors.Wrap(err, fmt.Sprintf("failed to create directory %s", key)) | ||
} | ||
|
||
lockFilepath := filepath.Join(key, ".started") | ||
slog.Debug("taking lock", "key", lockFilepath) | ||
lock, err := lockedfile.Create(lockFilepath) | ||
slog.Debug("took lock", "key", lockFilepath) | ||
|
||
if err != nil { | ||
return errors.Wrap(err, "failed to take file lock") | ||
} | ||
defer func() { | ||
if err := lock.Close(); err != nil { | ||
slog.Error("failed to release lock", "key", lockFilepath, "error", err) | ||
} | ||
slog.Debug("released lock", "key", lockFilepath) | ||
}() | ||
// If data is already present, return | ||
if _, err := os.Stat(filepath.Join(key, completionMarkerFile)); err == nil { | ||
return nil | ||
} | ||
|
||
if err := addItem(); err != nil { | ||
return errors.Wrap(err, fmt.Sprintf("failed to add item: %s to cache", key)) | ||
} | ||
|
||
integrityFpath := filepath.Join(key, completionMarkerFile) | ||
f, err := os.Create(integrityFpath) | ||
if err != nil { | ||
return errors.Wrap(err, fmt.Sprintf("failed to create integrity file: %s", integrityFpath)) | ||
} | ||
f.Close() | ||
|
||
return nil | ||
} | ||
|
||
// GetKeyName generate unique file path inside cache directory | ||
// based on name provided | ||
func GetKeyName(name string) string { | ||
return filepath.Join(getCacheDir(), sha(name)) | ||
} | ||
|
||
func getCacheDir() string { | ||
dir, _ := os.UserHomeDir() | ||
return filepath.Join(dir, ".cache") | ||
} | ||
|
||
func sha(s string) string { | ||
h := sha1.New() | ||
h.Write([]byte(s)) | ||
return hex.EncodeToString(h.Sum(nil)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package cloner | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/drone/plugin/cache" | ||
"golang.org/x/exp/slog" | ||
) | ||
|
||
func NewCache(cloner Cloner) *cacheCloner { | ||
return &cacheCloner{cloner: cloner} | ||
} | ||
|
||
type cacheCloner struct { | ||
cloner Cloner | ||
} | ||
|
||
// Clone method clones the repository & caches it if not present in cache already. | ||
func (c *cacheCloner) Clone(ctx context.Context, repo, ref, sha string) (string, error) { | ||
key := cache.GetKeyName(fmt.Sprintf("%s%s%s", repo, ref, sha)) | ||
codedir := filepath.Join(key, "data") | ||
|
||
cloneFn := func() error { | ||
// Remove stale data | ||
if err := os.RemoveAll(codedir); err != nil { | ||
slog.Error("cannot remove code directory", codedir, err) | ||
} | ||
|
||
if err := os.MkdirAll(codedir, 0700); err != nil { | ||
slog.Error("failed to create code directory", codedir, err) | ||
return err | ||
} | ||
return c.cloner.Clone(ctx, | ||
Params{Repo: repo, Ref: ref, Sha: sha, Dir: codedir}) | ||
} | ||
|
||
if err := cache.Add(key, cloneFn); err != nil { | ||
return "", err | ||
} | ||
return codedir, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.