Skip to content

Commit

Permalink
Refactor Generate Command to cobra cli lib
Browse files Browse the repository at this point in the history
Signed-off-by: Marco Franssen <marco.franssen@philips.com>
  • Loading branch information
marcofranssen committed Nov 30, 2021
1 parent 0c8cf3a commit 29db98e
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 93 deletions.
9 changes: 8 additions & 1 deletion cmd/slsa-provenance/cli/commands.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cli

import (
"fmt"

"github.com/spf13/cobra"

"github.com/philips-labs/slsa-provenance-action/cmd/slsa-provenance/cli/options"
Expand All @@ -14,6 +16,11 @@ var (
ro = &options.RootOptions{}
)

// RequiredFlagError creates a required flag error for the given flag name
func RequiredFlagError(flagName string) error {
return fmt.Errorf("no value found for required flag: %s", flagName)
}

// New creates a new instance of the slsa-provenance commandline interface
func New() *cobra.Command {
cmd := &cobra.Command{
Expand All @@ -28,7 +35,7 @@ func New() *cobra.Command {
ro.AddFlags(cmd)

cmd.AddCommand(Version())
cmd.AddCommand(Files())
cmd.AddCommand(Generate())

return cmd
}
16 changes: 2 additions & 14 deletions cmd/slsa-provenance/cli/files.go
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
package cli

import (
"flag"
"fmt"
"strings"

"github.com/philips-labs/slsa-provenance-action/cmd/slsa-provenance/cli/options"
"github.com/philips-labs/slsa-provenance-action/lib/github"
"github.com/spf13/cobra"
)

// Files creates an instance of *ffcli.Command to manage file provenance
// Files creates an instance of *cobra.Command to manage file provenance
func Files() *cobra.Command {
o := &options.FilesOptions{}

var (
flagset = flag.NewFlagSet("slsa-provenance generate files", flag.ExitOnError)
extraMaterials = []string{}
)
flagset.Func("extra_materials", "paths to files containing SLSA v0.1 formatted materials (JSON array) in to include in the provenance", func(s string) error {
extraMaterials = append(extraMaterials, strings.Fields(s)...)
return nil
})

cmd := &cobra.Command{
Use: "files",
Short: fmt.Sprintf("%s generate files", cliName),
Long: "Generates slsa provenance for file(s)",
Short: "Generate provenance on file assets",
RunE: func(cmd *cobra.Command, args []string) error {
artifactPath, err := o.GetArtifactPath()
if err != nil {
Expand Down
75 changes: 11 additions & 64 deletions cmd/slsa-provenance/cli/generate.go
Original file line number Diff line number Diff line change
@@ -1,73 +1,20 @@
package cli

import (
"context"
"encoding/json"
"flag"
"fmt"
"io"
"strings"

"github.com/peterbourgon/ff/v3/ffcli"

"github.com/philips-labs/slsa-provenance-action/lib/github"
"github.com/spf13/cobra"
)

// RequiredFlagError creates a required flag error for the given flag name
func RequiredFlagError(flagName string) error {
return fmt.Errorf("no value found for required flag: %s", flagName)
}
// Generate creates an instance of *cobra.Command to generate provenance
func Generate() *cobra.Command {
cmd := &cobra.Command{
Use: "generate",
Short: "Generate provenance using subcommands",
}

// Generate creates an instance of *ffcli.Command to generate provenance
func Generate(w io.Writer) *ffcli.Command {
var (
flagset = flag.NewFlagSet("slsa-provenance generate", flag.ExitOnError)
tagName = flagset.String("tag_name", "", `The github release to generate provenance on.
(if set the artifacts will be downloaded from the release and the provenance will be added as an additional release asset.)`)
artifactPath = flagset.String("artifact_path", "", "The file or dir path of the artifacts for which provenance should be generated.")
outputPath = flagset.String("output_path", "provenance.json", "The path to which the generated provenance should be written.")
githubContext = flagset.String("github_context", "", "The '${github}' context value.")
runnerContext = flagset.String("runner_context", "", "The '${runner}' context value.")
extraMaterials = []string{}
cmd.AddCommand(
Files(),
GitHubRelease(),
)
flagset.Func("extra_materials", "paths to files containing SLSA v0.1 formatted materials (JSON array) in to include in the provenance", func(s string) error {
extraMaterials = append(extraMaterials, strings.Fields(s)...)
return nil
})

flagset.SetOutput(w)

return &ffcli.Command{
Name: "generate",
ShortUsage: "slsa-provenance generate",
ShortHelp: "Generates the slsa provenance file",
FlagSet: flagset,
Subcommands: []*ffcli.Command{},
Exec: func(ctx context.Context, args []string) error {
if *outputPath == "" {
flagset.Usage()
return RequiredFlagError("-output_path")
}
if *githubContext == "" {
flagset.Usage()
return RequiredFlagError("-github_context")
}
if *runnerContext == "" {
flagset.Usage()
return RequiredFlagError("-runner_context")
}

var gh github.Context
if err := json.Unmarshal([]byte(*githubContext), &gh); err != nil {
return fmt.Errorf("failed to unmarshal github context json: %w", err)
}

var runner github.RunnerContext
if err := json.Unmarshal([]byte(*runnerContext), &runner); err != nil {
return fmt.Errorf("failed to unmarshal runner context json: %w", err)
}

return nil
},
}
return cmd
}
5 changes: 2 additions & 3 deletions cmd/slsa-provenance/cli/github-release.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import (
"github.com/philips-labs/slsa-provenance-action/lib/github"
)

// GitHubRelease creates an instance of *ffcli.Command to manage GitHub release provenance
// GitHubRelease creates an instance of *cobra.Command to manage GitHub release provenance
func GitHubRelease() *cobra.Command {
o := options.GitHubReleaseOptions{}

cmd := &cobra.Command{
Use: "github-release",
Short: "slsa-provenance generate github-release",
Long: "Generates slsa provenance for assets in a GitHub release",
Short: "Generate provenance on GitHub release assets",
RunE: func(cmd *cobra.Command, args []string) error {
artifactPath, err := o.GetArtifactPath()
if err != nil {
Expand Down
9 changes: 0 additions & 9 deletions cmd/slsa-provenance/cli/options/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ func RequiredFlagError(flagName string) error {
type FilesOptions struct {
GenerateOptions
ArtifactPath string
OutputPath string
}

func (o *FilesOptions) GetArtifactPath() (string, error) {
Expand All @@ -24,15 +23,7 @@ func (o *FilesOptions) GetArtifactPath() (string, error) {
return o.ArtifactPath, nil
}

func (o *FilesOptions) GetOutputPath() (string, error) {
if o.ArtifactPath == "" {
return "", RequiredFlagError("output-path")
}
return o.OutputPath, nil
}

func (o *FilesOptions) AddFlags(cmd *cobra.Command) {
o.GenerateOptions.AddFlags(cmd)
cmd.PersistentFlags().StringVar(&o.ArtifactPath, "artifact-path", "", "The file(s) or directory of artifacts to include in provenance.")
cmd.PersistentFlags().StringVar(&o.OutputPath, "output-path", "provenance.json", "The path to which the generated provenance should be written.")
}
9 changes: 9 additions & 0 deletions cmd/slsa-provenance/cli/options/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
type GenerateOptions struct {
GitHubContext string
RunnerContext string
OutputPath string
ExtraMaterials []string
}

Expand All @@ -39,6 +40,13 @@ func (o *GenerateOptions) GetRunnerContext() (*github.RunnerContext, error) {
return &runner, nil
}

func (o *FilesOptions) GetOutputPath() (string, error) {
if o.OutputPath == "" {
return "", RequiredFlagError("output-path")
}
return o.OutputPath, nil
}

func (o *GenerateOptions) GetExtraMaterials() ([]intoto.Item, error) {
var materials []intoto.Item

Expand Down Expand Up @@ -67,5 +75,6 @@ func (o *GenerateOptions) GetExtraMaterials() ([]intoto.Item, error) {
func (o *GenerateOptions) AddFlags(cmd *cobra.Command) {
cmd.PersistentFlags().StringVar(&o.GitHubContext, "github-context", "", "The '${github}' context value.")
cmd.PersistentFlags().StringVar(&o.RunnerContext, "runner-context", "", "The '${runner}' context value.")
cmd.PersistentFlags().StringVar(&o.OutputPath, "output-path", "provenance.json", "The path to which the generated provenance should be written.")
cmd.PersistentFlags().StringSliceVarP(&o.ExtraMaterials, "extra-materials", "m", nil, "The '${runner}' context value.")
}
2 changes: 0 additions & 2 deletions cmd/slsa-provenance/cli/options/github-release.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
type GitHubReleaseOptions struct {
GenerateOptions
ArtifactPath string
OutputPath string
TagName string
}

Expand Down Expand Up @@ -35,7 +34,6 @@ func (o *GitHubReleaseOptions) GetTagName() (string, error) {
func (o *GitHubReleaseOptions) AddFlags(cmd *cobra.Command) {
o.GenerateOptions.AddFlags(cmd)
cmd.PersistentFlags().StringVar(&o.ArtifactPath, "artifact-path", "", "The file(s) or directory of artifacts to include in provenance.")
cmd.PersistentFlags().StringVar(&o.OutputPath, "output-path", "provenance.json", "The path to which the generated provenance should be written.")
cmd.PersistentFlags().StringVar(&o.TagName, "tag-name", "", `The github release to generate provenance on.
(if set the artifacts will be downloaded from the release and the provenance will be added as an additional release asset.)`)
}

0 comments on commit 29db98e

Please sign in to comment.