Skip to content

Commit

Permalink
feat(glaze): call deglaze with an -undo flag
Browse files Browse the repository at this point in the history
Co-authored-by: Steve Taylor <sttaylor@vmware.com>
Co-authored-by: Claire Tinati <ctinati@vmware.com
  • Loading branch information
crhntr and staylor14 committed Jun 28, 2023
1 parent a574a21 commit 3d84ec4
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 82 deletions.
54 changes: 24 additions & 30 deletions internal/commands/glaze.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,55 +5,49 @@ import (
"github.com/pivotal-cf/kiln/pkg/cargo"
)

type (
glazeCommandOptions struct {
type Glaze struct {
Options struct {
Kilnfile string `short:"kf" long:"kilnfile" default:"Kilnfile" description:"path to Kilnfile"`
Undo bool ` long:"undo" description:"loosens bosh release constraints post-GA based on 'maintenance_version_bump_policy' and 'float_always'"`
}
Glaze struct {
Options glazeCommandOptions
}
DeGlaze struct {
Options glazeCommandOptions
}
)

func (cmd *Glaze) Execute(args []string) error {
return glazeCommandExecute(cmd.Options, args, (*cargo.Kilnfile).Glaze)
}

func (cmd *Glaze) Usage() jhanda.Usage {
return jhanda.Usage{
Description: "This command locks all the components.",
ShortDescription: "Pin versions in Kilnfile to match lock.",
}
}

func (cmd *DeGlaze) Execute(args []string) error {
return glazeCommandExecute(cmd.Options, args, (*cargo.Kilnfile).DeGlaze)
glaze, deGlaze func(kf *cargo.Kilnfile, kl cargo.KilnfileLock) error
}

func (cmd *DeGlaze) Usage() jhanda.Usage {
return jhanda.Usage{
Description: "This command unlocks all the components.",
ShortDescription: "Unpin version constraints in Kilnfile based on de_glaze_behavior.",
func NewGlaze() *Glaze {
return &Glaze{
glaze: (*cargo.Kilnfile).Glaze,
deGlaze: (*cargo.Kilnfile).DeGlaze,
}
}

func glazeCommandExecute(options glazeCommandOptions, args []string, fn func(kilnfile *cargo.Kilnfile, lock cargo.KilnfileLock) error) error {
_, err := jhanda.Parse(&options, args)
func (cmd *Glaze) Execute(args []string) error {
_, err := jhanda.Parse(&cmd.Options, args)
if err != nil {
return err
}
kfPath, err := cargo.ResolveKilnfilePath(options.Kilnfile)
kfPath, err := cargo.ResolveKilnfilePath(cmd.Options.Kilnfile)
if err != nil {
return err
}
kilnfile, kilnfileLock, err := cargo.ReadKilnfileAndKilnfileLock(kfPath)
if err != nil {
return err
}
if err := fn(&kilnfile, kilnfileLock); err != nil {
if cmd.Options.Undo {
err = cmd.deGlaze(&kilnfile, kilnfileLock)
} else {
err = cmd.glaze(&kilnfile, kilnfileLock)
}
if err != nil {
return err
}
return cargo.WriteKilnfile(kfPath, kilnfile)
}

func (cmd *Glaze) Usage() jhanda.Usage {
return jhanda.Usage{
Description: "This command locks all the components.",
ShortDescription: "Pin versions in Kilnfile to match lock.",
}
}
143 changes: 93 additions & 50 deletions internal/commands/glaze_test.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
package commands

import (
"fmt"
"os"
"path/filepath"
"testing"

. "github.com/onsi/gomega"
"github.com/pivotal-cf/jhanda"
"github.com/pivotal-cf/kiln/pkg/cargo"
"gopkg.in/yaml.v2"
)

const invalidYAML = `}`

func TestGlaze_Execute(t *testing.T) {
testGlazeCommand(t, &Glaze{})
type glazeWithFakeImplementation struct {
Glaze
GlazeFuncCalled, DeGlazeFuncCalled bool
glazeFuncError, deGlazeFuncError error
}

func (fake *glazeWithFakeImplementation) glaze(*cargo.Kilnfile, cargo.KilnfileLock) error {
fake.GlazeFuncCalled = true
return fake.glazeFuncError
}

func (fake *glazeWithFakeImplementation) deGlaze(*cargo.Kilnfile, cargo.KilnfileLock) error {
fake.DeGlazeFuncCalled = true
return fake.deGlazeFuncError
}

func TestDeGlaze_Execute(t *testing.T) {
testGlazeCommand(t, &DeGlaze{})
func newGlazeWithFake(glazeFuncError, deGlazeFuncError error) *glazeWithFakeImplementation {
result := &glazeWithFakeImplementation{
glazeFuncError: glazeFuncError,
deGlazeFuncError: deGlazeFuncError,
}
result.Glaze.glaze = result.glaze
result.Glaze.deGlaze = result.deGlaze
return result
}

func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
func TestGlaze_Execute(t *testing.T) {
t.Run("Kilnfile passed in as argument", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
Expand All @@ -30,15 +48,15 @@ func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

err := cmd.Execute([]string{"--kilnfile", kfp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).ToNot(HaveOccurred())
})

t.Run("Kilnfile is missing", func(t *testing.T) {
tmp := t.TempDir()
err := cmd.Execute([]string{"--kilnfile", tmp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", tmp})

g := NewWithT(t)
g.Expect(err).To(MatchError(ContainSubstring("Kilnfile")))
Expand All @@ -52,7 +70,7 @@ func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

err := cmd.Execute([]string{"--kilnfile", tmp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", tmp})

g := NewWithT(t)
g.Expect(err).NotTo(HaveOccurred())
Expand All @@ -63,51 +81,14 @@ func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{})

err := cmd.Execute([]string{"--kilnfile", kfp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).To(MatchError(ContainSubstring("Kilnfile.lock")))
})

t.Run("Kilnfile has a release not in Kilnfile.lock", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{
Releases: []cargo.ComponentSpec{
{Name: "banana"},
},
})
klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{
Releases: []cargo.ComponentLock{},
})
err := cmd.Execute([]string{"--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).To(MatchError(ContainSubstring(`"banana" not found in Kilnfile.lock`)))
})

t.Run("Kilnfile has a release not in Kilnfile.lock", func(t *testing.T) {
tmp := t.TempDir()

kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{
Releases: []cargo.ComponentSpec{
{Name: "banana"},
},
})
klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{
Releases: []cargo.ComponentLock{},
})
err := cmd.Execute([]string{"--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).To(MatchError(ContainSubstring(`"banana" not found in Kilnfile.lock`)))
})

t.Run("bad flag passed", func(t *testing.T) {
err := cmd.Execute([]string{"--unknown-flag"})
err := newGlazeWithFake(nil, nil).Execute([]string{"--unknown-flag"})

g := NewWithT(t)
g.Expect(err).To(MatchError(ContainSubstring(`flag provided but not defined`)))
Expand All @@ -118,7 +99,7 @@ func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
_ = os.WriteFile(kfp, []byte(invalidYAML), 0o777)
err := cmd.Execute([]string{"--kilnfile", kfp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", kfp})
g := NewWithT(t)
g.Expect(err).To(MatchError(And(
ContainSubstring(`Kilnfile`),
Expand All @@ -131,14 +112,76 @@ func testGlazeCommand(t *testing.T, cmd jhanda.Command) {
_ = os.WriteFile(kfp, []byte(`{}`), 0o777)
klp := filepath.Join(tmp, "Kilnfile.lock")
_ = os.WriteFile(klp, []byte(invalidYAML), 0o777)
err := cmd.Execute([]string{"--kilnfile", kfp})
err := newGlazeWithFake(nil, nil).Execute([]string{"--kilnfile", kfp})
g := NewWithT(t)
g.Expect(err).To(MatchError(And(
ContainSubstring(`Kilnfile.lock`),
ContainSubstring(`yaml:`),
)))
})
})

t.Run("when undo is passed", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{})

klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

cmd := newGlazeWithFake(nil, nil)
err := cmd.Execute([]string{"--undo", "--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(cmd.DeGlazeFuncCalled).To(BeTrue(), "it calls deGlaze")
})

t.Run("when de-glaze fails", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{})

klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

cmd := newGlazeWithFake(nil, fmt.Errorf("banana"))
err := cmd.Execute([]string{"--undo"})

g := NewWithT(t)
g.Expect(err).To(HaveOccurred())
})

t.Run("when undo is not passed", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{})

klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

cmd := newGlazeWithFake(nil, nil)
err := cmd.Execute([]string{"--kilnfile", kfp})

g := NewWithT(t)
g.Expect(err).ToNot(HaveOccurred())
g.Expect(cmd.GlazeFuncCalled).To(BeTrue(), "it calls glaze")
})

t.Run("when glaze fails", func(t *testing.T) {
tmp := t.TempDir()
kfp := filepath.Join(tmp, "Kilnfile")
writeYAML(t, kfp, cargo.Kilnfile{})

klp := filepath.Join(tmp, "Kilnfile.lock")
writeYAML(t, klp, cargo.KilnfileLock{})

cmd := newGlazeWithFake(nil, fmt.Errorf("banana"))
err := cmd.Execute([]string{})

g := NewWithT(t)
g.Expect(err).To(HaveOccurred())
})
}

func writeYAML(t *testing.T, path string, data interface{}) {
Expand Down
3 changes: 1 addition & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ func main() {
}

// commandSet["fetch"] = commands.NewFetch(outLogger, mrsProvider, localReleaseDirectory)
commandSet["glaze"] = new(commands.Glaze)
commandSet["de-glaze"] = new(commands.DeGlaze)
commandSet["glaze"] = commands.NewGlaze()

commandSet["generate-osm-manifest"] = commands.NewOSM(outLogger, nil)

Expand Down

0 comments on commit 3d84ec4

Please sign in to comment.