Skip to content

Commit

Permalink
Swap files and github-release command to cobra 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 95c63d2 commit 0c8cf3a
Show file tree
Hide file tree
Showing 13 changed files with 376 additions and 249 deletions.
34 changes: 34 additions & 0 deletions cmd/slsa-provenance/cli/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cli

import (
"github.com/spf13/cobra"

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

const (
cliName = "slsa-provenance"
)

var (
ro = &options.RootOptions{}
)

// New creates a new instance of the slsa-provenance commandline interface
func New() *cobra.Command {
cmd := &cobra.Command{
Use: cliName,
DisableAutoGenTag: true,
SilenceUsage: true,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}

ro.AddFlags(cmd)

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

return cmd
}
21 changes: 21 additions & 0 deletions cmd/slsa-provenance/cli/common_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package cli_test

import (
"bytes"

"github.com/spf13/cobra"
)

const (
githubContext = `{
"token": "***",
Expand Down Expand Up @@ -249,6 +255,21 @@ const (
}`
)

func executeCommand(cmd *cobra.Command, args ...string) (output string, err error) {
_, output, err = executeCommandC(cmd, args...)
return output, err
}

func executeCommandC(cmd *cobra.Command, args ...string) (c *cobra.Command, output string, err error) {
buf := new(bytes.Buffer)
cmd.SetOutput(buf)
cmd.SetArgs(args)

c, err = cmd.ExecuteC()

return c, buf.String(), err
}

func stringPointer(s string) *string {
return &s
}
Expand Down
99 changes: 36 additions & 63 deletions cmd/slsa-provenance/cli/files.go
Original file line number Diff line number Diff line change
@@ -1,103 +1,76 @@
package cli

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

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

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

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

var (
flagset = flag.NewFlagSet("slsa-provenance generate files", flag.ExitOnError)
artifactPath = flagset.String("artifact_path", "", "The file or dir path of the artifacts for which provenance should be generated.")
outputPath = flagset.String("output_path", "build.provenance", "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{}
)
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: "files",
ShortUsage: "slsa-provenance generate files",
ShortHelp: "Generates slsa provenance for file(s)",
FlagSet: flagset,
Exec: func(ctx context.Context, args []string) error {
if *artifactPath == "" {
flagset.Usage()
return RequiredFlagError("-artifact_path")
}
if *outputPath == "" {
flagset.Usage()
return RequiredFlagError("-output_path")
cmd := &cobra.Command{
Use: "files",
Short: fmt.Sprintf("%s generate files", cliName),
Long: "Generates slsa provenance for file(s)",
RunE: func(cmd *cobra.Command, args []string) error {
artifactPath, err := o.GetArtifactPath()
if err != nil {
return err
}
if *githubContext == "" {
flagset.Usage()
return RequiredFlagError("-github_context")
outputPath, err := o.GetOutputPath()
if err != nil {
return err
}
if *runnerContext == "" {
flagset.Usage()
return RequiredFlagError("-runner_context")

gh, err := o.GetGitHubContext()
if err != nil {
return err
}

var gh github.Context
if err := json.Unmarshal([]byte(*githubContext), &gh); err != nil {
return fmt.Errorf("failed to unmarshal github context json: %w", err)
runner, err := o.GetRunnerContext()
if err != nil {
return 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)
materials, err := o.GetExtraMaterials()
if err != nil {
return err
}

env := &github.Environment{
Context: &gh,
Runner: &runner,
Context: gh,
Runner: runner,
}

stmt, err := env.GenerateProvenanceStatement(ctx, *artifactPath)
stmt, err := env.GenerateProvenanceStatement(cmd.Context(), artifactPath)
if err != nil {
return fmt.Errorf("failed to generate provenance: %w", err)
}

for _, extra := range extraMaterials {
content, err := ioutil.ReadFile(extra)
if err != nil {
return fmt.Errorf("could not load extra materials from %s: %w", extra, err)
}
var materials []intoto.Item
if err = json.Unmarshal(content, &materials); err != nil {
return fmt.Errorf("invalid JSON in extra materials file %s: %w", extra, err)
}
for _, material := range materials {
if material.URI == "" {
return fmt.Errorf("empty or missing \"uri\" field in %s", extra)
}
if len(material.Digest) == 0 {
return fmt.Errorf("empty or missing \"digest\" in %s", extra)
}
}
stmt.Predicate.Materials = append(stmt.Predicate.Materials, materials...)
}
stmt.Predicate.Materials = append(stmt.Predicate.Materials, materials...)

fmt.Fprintf(w, "Saving provenance to %s\n", *outputPath)
fmt.Fprintf(cmd.OutOrStdout(), "Saving provenance to %s\n", outputPath)

return env.PersistProvenanceStatement(ctx, stmt, *outputPath)
return env.PersistProvenanceStatement(cmd.Context(), stmt, outputPath)
},
}

o.AddFlags(cmd)

return cmd
}
Loading

0 comments on commit 0c8cf3a

Please sign in to comment.