Skip to content
This repository has been archived by the owner on May 3, 2022. It is now read-only.

Commit

Permalink
feat: add 'duffle claims' subcommand (#339)
Browse files Browse the repository at this point in the history
This adds a 'duffle claims' subcommand, along with 'duffle claims show' to view the content of a claim. In the future, we can add more commands for working with claims.

Closes #286
  • Loading branch information
technosophos authored Nov 2, 2018
1 parent 5880b3b commit 1a2724a
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 0 deletions.
30 changes: 30 additions & 0 deletions cmd/duffle/claims.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"io"

"github.com/spf13/cobra"
)

const claimsDesc = `
Work with claims and existing releases.
A claim is a record of a release. When a bundle is installed, Duffle retains a
claim that tracks that release. Subsequent operations (like upgrades) will
modify the claim record.
The claim tools provide features for working directly with claims.
`

func newClaimsCmd(w io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "claims",
Short: "manage claims",
Long: claimsDesc,
Aliases: []string{"claim"},
}

cmd.AddCommand(newClaimsShowCmd(w))

return cmd
}
57 changes: 57 additions & 0 deletions cmd/duffle/claims_show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package main

import (
"encoding/json"
"io"

"github.com/deis/duffle/pkg/claim"

"github.com/spf13/cobra"
)

const claimsShowDesc = `
Display the content of a claim.
This dumps the entire content of a claim as a JSON object.
`

func newClaimsShowCmd(w io.Writer) *cobra.Command {
var onlyBundle bool
cmd := &cobra.Command{
Use: "show NAME",
Short: "show a claim",
Long: claimsShowDesc,
Aliases: []string{"get"},
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
name := args[0]
storage := claimStorage()
return displayClaim(name, w, storage, onlyBundle)
},
}

cmd.Flags().BoolVarP(&onlyBundle, "bundle", "b", false, "only show the bundle from the claim")

return cmd
}

func displayClaim(name string, out io.Writer, storage claim.Store, onlyBundle bool) error {
c, err := storage.Read(name)
if err != nil {
return err
}

var data []byte
if onlyBundle {
data, err = json.MarshalIndent(c.Bundle, "", " ")
} else {
data, err = json.MarshalIndent(c, "", " ")
}
if err != nil {
return err
}

_, err = out.Write(data)
out.Write([]byte("\n"))
return err
}
60 changes: 60 additions & 0 deletions cmd/duffle/claims_show_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"bytes"
"encoding/json"
"testing"

"github.com/deis/duffle/pkg/bundle"
"github.com/deis/duffle/pkg/claim"

"github.com/stretchr/testify/assert"
)

func TestDisplayClaim(t *testing.T) {
var buf bytes.Buffer
storage := mockClaimStore()

storage.Store(claim.Claim{
Name: "myclaim",
Bundle: &bundle.Bundle{
Name: "mybundle",
Version: "0.1.2",
},
})

displayClaim("myclaim", &buf, storage, false)

var got claim.Claim
if err := json.Unmarshal(buf.Bytes(), &got); err != nil {
t.Fatal(err)
}

is := assert.New(t)
is.Equal("myclaim", got.Name)
is.Equal("mybundle", got.Bundle.Name)
}

func TestDisplayClaim_Bundle(t *testing.T) {
var buf bytes.Buffer
storage := mockClaimStore()

storage.Store(claim.Claim{
Name: "myclaim",
Bundle: &bundle.Bundle{
Name: "mybundle",
Version: "0.1.2",
},
})

displayClaim("myclaim", &buf, storage, true)

var got bundle.Bundle
if err := json.Unmarshal(buf.Bytes(), &got); err != nil {
t.Fatal(err)
}

is := assert.New(t)
is.Equal("mybundle", got.Name)
is.Equal("0.1.2", got.Version)
}
61 changes: 61 additions & 0 deletions cmd/duffle/claims_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"errors"
"testing"

"github.com/deis/duffle/pkg/bundle"
"github.com/deis/duffle/pkg/claim"

"github.com/stretchr/testify/assert"
)

func TestMockClaimStore(t *testing.T) {
is := assert.New(t)
store := mockClaimStore()
c := claim.Claim{
Name: "testclaim",
Bundle: &bundle.Bundle{
Name: "testbundle",
},
}
store.Store(c)
list, err := store.List()
is.NoError(err)
is.Len(list, 1)
got, err := store.Read("testclaim")
is.NoError(err)
is.Equal("testbundle", got.Bundle.Name)
}

func mockClaimStore() claim.Store {
return claim.NewClaimStore(mockClaimBackend{})
}

type mockClaimBackend map[string][]byte

func (m mockClaimBackend) List() ([]string, error) {
list := []string{}
for key := range m {
list = append(list, key)
}
return list, nil
}

func (m mockClaimBackend) Store(name string, data []byte) error {
m[name] = data
return nil
}

func (m mockClaimBackend) Read(name string) ([]byte, error) {
data, ok := m[name]
if !ok {
return data, errors.New("not found")
}
return data, nil
}

func (m mockClaimBackend) Delete(name string) error {
delete(m, name)
return nil
}
1 change: 1 addition & 0 deletions cmd/duffle/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func newRootCmd(outputRedirect io.Writer) *cobra.Command {
cmd.AddCommand(newRunCmd(outLog))
cmd.AddCommand(newCredentialsCmd(outLog))
cmd.AddCommand(newKeyCmd(outLog))
cmd.AddCommand(newClaimsCmd(outLog))

return cmd
}

0 comments on commit 1a2724a

Please sign in to comment.