diff --git a/cli/recipe/diff.go b/cli/recipe/diff.go new file mode 100644 index 00000000..7067300d --- /dev/null +++ b/cli/recipe/diff.go @@ -0,0 +1,61 @@ +package recipe + +import ( + "fmt" + "os/exec" + "path" + + "coopcloud.tech/abra/cli/internal" + "coopcloud.tech/abra/pkg/autocomplete" + "coopcloud.tech/abra/pkg/config" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +// getGitDiffArgs builds the `git diff` invocation args +func getGitDiffArgs(repoPath string) []string { + return []string{ + "-C", + repoPath, + "--no-pager", + "-c", + "color.diff=always", + "diff", + } +} + +var recipeDiffCommand = cli.Command{ + Name: "diff", + Usage: "Show unstaged changes in recipe config", + Description: "Due to limitations in our underlying Git dependency, this command requires /usr/bin/git.", + Aliases: []string{"d"}, + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + BashComplete: autocomplete.RecipeNameComplete, + Action: func(c *cli.Context) error { + recipeName := c.Args().First() + + if recipeName != "" { + internal.ValidateRecipe(c) + } + + _, err := exec.LookPath("git") + if err != nil { + logrus.Fatal("unable to locate 'git' command?") + } + + gitDiffArgs := getGitDiffArgs(path.Join(config.RECIPES_DIR, recipeName)) + diff, err := exec.Command("git", gitDiffArgs...).Output() + if err != nil { + logrus.Fatal(err) + } + + fmt.Print(string(diff)) + + return nil + }, +} diff --git a/cli/recipe/recipe.go b/cli/recipe/recipe.go index 8333f0f0..ad3b6365 100644 --- a/cli/recipe/recipe.go +++ b/cli/recipe/recipe.go @@ -30,5 +30,7 @@ manner. Abra supports convenient automation for recipe maintainenace, see the recipeSyncCommand, recipeUpgradeCommand, recipeVersionCommand, + recipeResetCommand, + recipeDiffCommand, }, } diff --git a/cli/recipe/reset.go b/cli/recipe/reset.go new file mode 100644 index 00000000..67208cdc --- /dev/null +++ b/cli/recipe/reset.go @@ -0,0 +1,56 @@ +package recipe + +import ( + "path" + + "coopcloud.tech/abra/cli/internal" + "coopcloud.tech/abra/pkg/autocomplete" + "coopcloud.tech/abra/pkg/config" + "github.com/go-git/go-git/v5" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var recipeResetCommand = cli.Command{ + Name: "reset", + Usage: "Remove all unstaged changes from recipe config", + Description: "WARNING, this will delete your changes. Be Careful.", + Aliases: []string{"rs"}, + ArgsUsage: "", + Flags: []cli.Flag{ + internal.DebugFlag, + internal.NoInputFlag, + }, + Before: internal.SubCommandBefore, + BashComplete: autocomplete.RecipeNameComplete, + Action: func(c *cli.Context) error { + recipeName := c.Args().First() + + if recipeName != "" { + internal.ValidateRecipe(c) + } + + repoPath := path.Join(config.RECIPES_DIR, recipeName) + repo, err := git.PlainOpen(repoPath) + if err != nil { + logrus.Fatal(err) + } + + ref, err := repo.Head() + if err != nil { + logrus.Fatal(err) + } + + worktree, err := repo.Worktree() + if err != nil { + logrus.Fatal(err) + } + + opts := &git.ResetOptions{Commit: ref.Hash(), Mode: git.HardReset} + if err := worktree.Reset(opts); err != nil { + logrus.Fatal(err) + } + + return nil + }, +} diff --git a/tests/integration/recipe_diff.bats b/tests/integration/recipe_diff.bats new file mode 100644 index 00000000..fd384e35 --- /dev/null +++ b/tests/integration/recipe_diff.bats @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +setup() { + load "$PWD/tests/integration/helpers/common" + _common_setup +} + +@test "show unstaged changes" { + run $ABRA recipe diff "$TEST_RECIPE" + assert_success + refute_output --partial 'traefik.enable' + + run sed -i '/traefik.enable=.*/d' "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml" + assert_success + + run $ABRA recipe diff "$TEST_RECIPE" + assert_success + assert_output --partial 'traefik.enable' + + _reset_recipe +} diff --git a/tests/integration/recipe_reset.bats b/tests/integration/recipe_reset.bats new file mode 100644 index 00000000..22b46f61 --- /dev/null +++ b/tests/integration/recipe_reset.bats @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +setup() { + load "$PWD/tests/integration/helpers/common" + _common_setup +} + +@test "reset unstaged changes" { + run $ABRA recipe fetch "$TEST_RECIPE" + assert_success + + run sed -i '/traefik.enable=.*/d' "$ABRA_DIR/recipes/$TEST_RECIPE/compose.yml" + assert_success + + run $ABRA recipe diff "$TEST_RECIPE" + assert_success + assert_output --partial 'traefik.enable' + + run $ABRA recipe reset "$TEST_RECIPE" + assert_success + + run $ABRA recipe diff "$TEST_RECIPE" + assert_success + refute_output --partial 'traefik.enable' +}