fix: unstaged changes handling

See toolshed/organising#651
This commit is contained in:
2024-12-31 11:19:03 +01:00
parent bfed51a69c
commit 5975be6870
26 changed files with 622 additions and 56 deletions

View File

@ -137,8 +137,7 @@ func (r Recipe) EnsureIsClean() error {
}
if !isClean {
msg := "%s (%s) has locally unstaged changes? please commit/remove your changes before proceeding"
return fmt.Errorf(msg, r.Name, r.Dir)
return fmt.Errorf("%s (%s) has locally unstaged changes?", r.Name, r.Dir)
}
return nil
@ -230,8 +229,23 @@ func (r Recipe) EnsureUpToDate() error {
return nil
}
// IsDirty checks whether a recipe is dirty or not. N.B., if you call IsDirty
// from another Recipe method, you should propagate the pointer reference (*).
func (r *Recipe) IsDirty() error {
isClean, err := gitPkg.IsClean(r.Dir)
if err != nil {
return err
}
if !isClean {
r.Dirty = true
}
return nil
}
// ChaosVersion constructs a chaos mode recipe version.
func (r Recipe) ChaosVersion() (string, error) {
func (r *Recipe) ChaosVersion() (string, error) {
var version string
head, err := r.Head()
@ -241,15 +255,10 @@ func (r Recipe) ChaosVersion() (string, error) {
version = formatter.SmallSHA(head.String())
isClean, err := gitPkg.IsClean(r.Dir)
if err != nil {
if err := r.IsDirty(); err != nil {
return version, err
}
if !isClean {
version = fmt.Sprintf("%s+U", version)
}
return version, nil
}

39
pkg/recipe/git_test.go Normal file
View File

@ -0,0 +1,39 @@
package recipe
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func TestIsDirty(t *testing.T) {
r := Get("abra-test-recipe")
if err := r.EnsureExists(); err != nil {
t.Fatal(err)
}
if err := r.IsDirty(); err != nil {
t.Fatal(err)
}
assert.False(t, r.Dirty)
fpath := filepath.Join(r.Dir, "foo.txt")
f, err := os.Create(fpath)
if err != nil {
t.Fatal(err)
}
defer f.Close()
defer t.Cleanup(func() {
os.Remove(fpath)
})
if err := r.IsDirty(); err != nil {
t.Fatal(err)
}
assert.True(t, r.Dirty)
}

View File

@ -2,6 +2,7 @@ package recipe
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/url"
@ -20,6 +21,7 @@ import (
"coopcloud.tech/abra/pkg/log"
"coopcloud.tech/abra/pkg/web"
"coopcloud.tech/tagcmp"
"github.com/go-git/go-git/v5"
)
// RecipeCatalogueURL is the only current recipe catalogue available.
@ -131,7 +133,12 @@ func Get(name string) Recipe {
log.Fatalf("version seems invalid: %s", name)
}
name = split[0]
version = split[1]
if strings.HasSuffix(version, config.DIRTY_DEFAULT) {
version = strings.Replace(split[1], config.DIRTY_DEFAULT, "", 1)
log.Debugf("removed dirty suffix from .env version: %s -> %s", split[1], version)
}
}
gitURL := fmt.Sprintf("%s/%s.git", config.REPOS_BASE_URL, name)
@ -151,7 +158,7 @@ func Get(name string) Recipe {
dir := path.Join(config.RECIPES_DIR, escapeRecipeName(name))
return Recipe{
r := Recipe{
Name: name,
Version: version,
Dir: dir,
@ -163,11 +170,18 @@ func Get(name string) Recipe {
SampleEnvPath: path.Join(dir, ".env.sample"),
AbraShPath: path.Join(dir, "abra.sh"),
}
if err := r.IsDirty(); err != nil && !errors.Is(err, git.ErrRepositoryNotExists) {
log.Fatalf("failed to check git status of %s: %s", r.Name, err)
}
return r
}
type Recipe struct {
Name string
Version string
Dirty bool // NOTE(d1): git terminology for unstaged changes
Dir string
GitURL string
SSHURL string
@ -178,6 +192,21 @@ type Recipe struct {
AbraShPath string
}
// String outputs a human-friendly string representation.
func (r Recipe) String() string {
out := fmt.Sprintf("{name: %s, ", r.Name)
out += fmt.Sprintf("version : %s, ", r.Version)
out += fmt.Sprintf("dirty: %v, ", r.Dirty)
out += fmt.Sprintf("dir: %s, ", r.Dir)
out += fmt.Sprintf("git url: %s, ", r.GitURL)
out += fmt.Sprintf("ssh url: %s, ", r.SSHURL)
out += fmt.Sprintf("compose: %s, ", r.ComposePath)
out += fmt.Sprintf("readme: %s, ", r.ReadmePath)
out += fmt.Sprintf("sample env: %s, ", r.SampleEnvPath)
out += fmt.Sprintf("abra.sh: %s}", r.AbraShPath)
return out
}
func escapeRecipeName(recipeName string) string {
recipeName = strings.ReplaceAll(recipeName, "/", "_")
recipeName = strings.ReplaceAll(recipeName, ".", "_")

View File

@ -105,3 +105,8 @@ func TestGetVersionLabelLocalDoesNotUseTimeoutLabel(t *testing.T) {
assert.NotEqual(t, label, defaultTimeoutLabel)
}
}
func TestDirtyMarkerRemoved(t *testing.T) {
r := Get("abra-test-recipe:1e83340e+U")
assert.Equal(t, "1e83340e", r.Version)
}