-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
moved cache and persistence to internal
- Loading branch information
Daniel Menet
committed
Aug 25, 2023
1 parent
7fb3cc3
commit 7c83323
Showing
5 changed files
with
291 additions
and
0 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,46 @@ | ||
package cache | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
type Cache struct { | ||
timeout time.Duration | ||
store map[string]cacheElement | ||
} | ||
|
||
func New(timeout time.Duration) *Cache { | ||
return &Cache{ | ||
timeout: timeout, | ||
store: map[string]cacheElement{}, | ||
} | ||
} | ||
|
||
func (c *Cache) Add(key string, data []byte) { | ||
c.store[key] = cacheElement{ | ||
cachedAt: time.Now(), | ||
data: data, | ||
} | ||
} | ||
|
||
func (c *Cache) Get(key string) ([]byte, bool) { | ||
elem, ok := c.store[key] | ||
if !ok { | ||
return nil, false | ||
} | ||
age := time.Since(elem.cachedAt) | ||
if age >= c.timeout { | ||
delete(c.store, key) | ||
return nil, false | ||
} | ||
return elem.data, true | ||
} | ||
|
||
func (c *Cache) Purge() { | ||
c.store = make(map[string]cacheElement) | ||
} | ||
|
||
type cacheElement struct { | ||
data []byte | ||
cachedAt time.Time | ||
} |
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,93 @@ | ||
package cache | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestCache_Add(t *testing.T) { | ||
// Create a new cache instance | ||
cache := New(time.Minute) | ||
|
||
// Add a cache element with a key and data | ||
key := "test" | ||
data := []byte("test data") | ||
cache.Add(key, data) | ||
|
||
// Check if the cache element exists in the store | ||
if _, ok := cache.store[key]; !ok { | ||
t.Errorf("Cache element with key '%s' not found", key) | ||
} | ||
|
||
// Check if the data of the cache element is correct | ||
if got := cache.store[key].data; !bytes.Equal(got, data) { | ||
t.Errorf("Cache element data mismatch, got %v, want %v", got, data) | ||
} | ||
} | ||
|
||
func TestCache_Get(t *testing.T) { | ||
// Create a new cache instance | ||
cache := New(time.Minute) | ||
|
||
// Add a cache element with a key and data | ||
key := "test" | ||
data := []byte("test data") | ||
cache.Add(key, data) | ||
|
||
// Retrieve the cache element using the Get method | ||
got, ok := cache.Get(key) | ||
|
||
// Check if the cache element is found | ||
if !ok { | ||
t.Errorf("Cache element with key '%s' not found", key) | ||
} | ||
|
||
// Check if the retrieved data is correct | ||
if string(got) != string(data) { | ||
t.Errorf("Retrieved data mismatch, got %s, want %s", got, data) | ||
} | ||
} | ||
|
||
func TestCache_Get_Expired(t *testing.T) { | ||
// Create a new cache instance with a short timeout duration | ||
cache := New(1 * time.Millisecond) | ||
|
||
// Add a cache element with a key and data | ||
key := "test" | ||
data := []byte("test data") | ||
cache.Add(key, data) | ||
|
||
// Wait for the cache element to expire | ||
time.Sleep(2 * time.Millisecond) | ||
|
||
// Retrieve the cache element using the Get method | ||
got, ok := cache.Get(key) | ||
|
||
// Check if the cache element is not found | ||
if ok { | ||
t.Errorf("Cache element with key '%s' found, expected not found", key) | ||
} | ||
|
||
// Check if the retrieved data is nil | ||
if got != nil { | ||
t.Errorf("Retrieved data mismatch, got %v, want nil", got) | ||
} | ||
} | ||
|
||
func TestCache_Purge(t *testing.T) { | ||
// Create a new cache instance | ||
cache := New(time.Minute) | ||
|
||
// Add multiple cache elements | ||
cache.Add("key1", []byte("data1")) | ||
cache.Add("key2", []byte("data2")) | ||
|
||
// Purge the cache | ||
cache.Purge() | ||
|
||
// Check if the store is empty | ||
if len(cache.store) != 0 { | ||
t.Errorf("Cache store is not empty after purging") | ||
} | ||
} |
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,92 @@ | ||
package persistence | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/go-git/go-billy/v5" | ||
"github.com/go-git/go-billy/v5/memfs" | ||
"github.com/go-git/go-git/v5" | ||
"github.com/go-git/go-git/v5/plumbing" | ||
ssh2 "github.com/go-git/go-git/v5/plumbing/transport/ssh" | ||
"github.com/go-git/go-git/v5/storage/memory" | ||
"golang.org/x/crypto/ssh" | ||
) | ||
|
||
type gitrepo struct { | ||
repo *git.Repository | ||
fs billy.Filesystem | ||
} | ||
|
||
func NewGitRepo(keypath, pass, url string) (Persistence, error) { | ||
gr := &gitrepo{} | ||
pem, err := os.ReadFile(keypath) | ||
if err != nil { | ||
return gr, err | ||
} | ||
signer, err := ssh.ParsePrivateKeyWithPassphrase(pem, []byte(pass)) | ||
if err != nil { | ||
return gr, err | ||
} | ||
auth := &ssh2.PublicKeys{User: "git", Signer: signer} | ||
gr.fs = memfs.New() | ||
gr.repo, err = git.Clone(memory.NewStorage(), gr.fs, &git.CloneOptions{ | ||
URL: url, | ||
Auth: auth, | ||
Progress: os.Stdout, | ||
Mirror: true, | ||
}) | ||
return gr, err | ||
} | ||
|
||
func (gr *gitrepo) Filesystem() billy.Filesystem { | ||
return gr.fs | ||
} | ||
|
||
func (gr *gitrepo) Branches() ([]string, error) { | ||
var branches []string | ||
iter, err := gr.repo.Branches() | ||
if err != nil { | ||
return branches, err | ||
} | ||
_ = iter.ForEach(func(this *plumbing.Reference) error { | ||
branches = append(branches, this.Name().String()) | ||
return nil | ||
}) | ||
return branches, nil | ||
} | ||
|
||
func (gr *gitrepo) branch(name string) *plumbing.Reference { | ||
var ref *plumbing.Reference | ||
iter, err := gr.repo.Branches() | ||
if err != nil { | ||
return ref | ||
} | ||
_ = iter.ForEach(func(this *plumbing.Reference) error { | ||
if this.Name().String() == name { | ||
ref = this | ||
} | ||
return nil | ||
}) | ||
return ref | ||
} | ||
|
||
func (gr *gitrepo) CheckoutBranch(name string) error { | ||
worktree, err := gr.repo.Worktree() | ||
if err != nil { | ||
return err | ||
} | ||
branch := gr.branch(name) | ||
if branch == nil { | ||
return fmt.Errorf("Branch '%s' does not exist", name) | ||
} | ||
err = worktree.Checkout(&git.CheckoutOptions{ | ||
Branch: branch.Name(), | ||
Force: true, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
gr.fs = worktree.Filesystem | ||
return 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,29 @@ | ||
package persistence | ||
|
||
import ( | ||
"github.com/go-git/go-billy/v5" | ||
"github.com/go-git/go-billy/v5/osfs" | ||
) | ||
|
||
type local struct { | ||
fs billy.Filesystem | ||
} | ||
|
||
func NewLocal(path string) (Persistence, error) { | ||
l := &local{ | ||
fs: osfs.New(path), | ||
} | ||
return l, nil | ||
} | ||
|
||
func (l *local) Filesystem() billy.Filesystem { | ||
return l.fs | ||
} | ||
|
||
func (l *local) Branches() ([]string, error) { | ||
return []string{"local"}, nil | ||
} | ||
|
||
func (l *local) CheckoutBranch(name string) error { | ||
return 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,31 @@ | ||
package persistence | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/go-git/go-billy/v5" | ||
) | ||
|
||
type Persistence interface { | ||
Filesystem() billy.Filesystem | ||
Branches() ([]string, error) | ||
CheckoutBranch(string) error | ||
} | ||
|
||
type Config struct { | ||
Filepath string | ||
Git struct { | ||
Keyfile string | ||
Pass string | ||
URL string | ||
} | ||
} | ||
|
||
func New(c Config) (Persistence, error) { | ||
if c.Git.URL != "" { | ||
return NewGitRepo(c.Git.Keyfile, c.Git.Pass, c.Git.URL) | ||
} else if c.Filepath != "" { | ||
return NewLocal(c.Filepath) | ||
} | ||
return nil, fmt.Errorf("Neither a git url nor a local file path was provided") | ||
} |