mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
add scope feature + lint fixes
This commit is contained in:
parent
1e5c7bb5c7
commit
11b2b1ab45
9 changed files with 194 additions and 19 deletions
|
@ -9,41 +9,41 @@ linters:
|
|||
- dogsled
|
||||
- dupl
|
||||
- errcheck
|
||||
# - funlen
|
||||
- gochecknoinits
|
||||
# - gocognit
|
||||
- funlen
|
||||
- gocognit
|
||||
- goconst
|
||||
# - gocritic
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
# - golint
|
||||
- golint
|
||||
- gomnd
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
# - interfacer
|
||||
# - lll
|
||||
- interfacer
|
||||
- lll
|
||||
- misspell
|
||||
- nakedret
|
||||
- nolintlint
|
||||
- rowserrcheck
|
||||
# - scopelint
|
||||
- scopelint
|
||||
- staticcheck
|
||||
- structcheck
|
||||
# - stylecheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
# - whitespace
|
||||
- whitespace
|
||||
- prealloc
|
||||
- asciicheck
|
||||
|
||||
# do not enable...
|
||||
# - gochecknoinits
|
||||
# - gochecknoglobals
|
||||
# - godot
|
||||
# - godox
|
||||
|
|
|
@ -2,21 +2,22 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const ApplicationName = "imgbom"
|
||||
|
||||
var rootOptions struct {
|
||||
cfgFile string
|
||||
cfgFile string
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: ApplicationName,
|
||||
Short: "A container image BOM tool",
|
||||
Long: `todo.`,
|
||||
Run: doRunCmd,
|
||||
Run: doRunCmd,
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
|
@ -37,4 +38,4 @@ func loadApplicationConfig() {
|
|||
|
||||
func doRunCmd(cmd *cobra.Command, args []string) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
|
@ -30,4 +30,4 @@ func SetVersion(v *Version) {
|
|||
|
||||
func printVersion(cmd *cobra.Command, args []string) {
|
||||
fmt.Printf("%s %s\n", ApplicationName, version.Version)
|
||||
}
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,7 @@ module github.com/anchore/imgbom
|
|||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/anchore/stereoscope v0.0.0-20200512135733-57b1df994b57 // indirect
|
||||
github.com/anchore/stereoscope v0.0.0-20200512135733-57b1df994b57
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/mitchellh/mapstructure v1.3.0 // indirect
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
|
|
23
imgbom/scope/option.go
Normal file
23
imgbom/scope/option.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package scope
|
||||
|
||||
const (
|
||||
UnknownScope Option = iota
|
||||
SquashedScope
|
||||
AllLayersScope
|
||||
)
|
||||
|
||||
type Option int
|
||||
|
||||
var optionStr = []string{
|
||||
"UnknownScope",
|
||||
"Squashed",
|
||||
"AllLayers",
|
||||
}
|
||||
|
||||
func (o Option) String() string {
|
||||
if int(o) >= len(optionStr) || int(o) < 0 {
|
||||
return optionStr[0]
|
||||
}
|
||||
|
||||
return optionStr[o]
|
||||
}
|
17
imgbom/scope/option_test.go
Normal file
17
imgbom/scope/option_test.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestOptionStringerBoundary(t *testing.T) {
|
||||
var _ fmt.Stringer = Option(0)
|
||||
|
||||
for _, c := range []int{-1, 0, 3} {
|
||||
option := Option(c)
|
||||
if option.String() != UnknownScope.String() {
|
||||
t.Errorf("expected Option(%d) to be unknown, found '%+v'", c, option)
|
||||
}
|
||||
}
|
||||
}
|
44
imgbom/scope/scope.go
Normal file
44
imgbom/scope/scope.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
)
|
||||
|
||||
type Scope struct {
|
||||
Option Option
|
||||
Trees []*tree.FileTree
|
||||
}
|
||||
|
||||
func NewScope(img *image.Image, option Option) (Scope, error) {
|
||||
var trees = make([]*tree.FileTree, 0)
|
||||
|
||||
if img == nil {
|
||||
return Scope{}, fmt.Errorf("no image given")
|
||||
}
|
||||
|
||||
switch option {
|
||||
case SquashedScope:
|
||||
if img.SquashedTree == nil {
|
||||
return Scope{}, fmt.Errorf("the image does not have have a squashed tree")
|
||||
}
|
||||
trees = append(trees, img.SquashedTree)
|
||||
|
||||
case AllLayersScope:
|
||||
if len(img.Layers) == 0 {
|
||||
return Scope{}, fmt.Errorf("the image does not contain any layers")
|
||||
}
|
||||
for _, layer := range img.Layers {
|
||||
trees = append(trees, layer.Tree)
|
||||
}
|
||||
default:
|
||||
return Scope{}, fmt.Errorf("bad option provided: %+v", option)
|
||||
}
|
||||
|
||||
return Scope{
|
||||
Option: option,
|
||||
Trees: trees,
|
||||
}, nil
|
||||
}
|
90
imgbom/scope/scope_test.go
Normal file
90
imgbom/scope/scope_test.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/stereoscope/pkg/tree"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testScopeImage(t *testing.T) *image.Image {
|
||||
t.Helper()
|
||||
|
||||
one := image.NewLayer(0, nil)
|
||||
one.Tree = tree.NewFileTree()
|
||||
one.Tree.AddPath("/tree/first/path.txt")
|
||||
|
||||
two := image.NewLayer(1, nil)
|
||||
two.Tree = tree.NewFileTree()
|
||||
two.Tree.AddPath("/tree/second/path.txt")
|
||||
|
||||
i := image.NewImage(nil)
|
||||
i.Layers = []image.Layer{one, two}
|
||||
err := i.Squash()
|
||||
if err != nil {
|
||||
t.Fatal("could not squash test image trees")
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func TestScope(t *testing.T) {
|
||||
refImg := testScopeImage(t)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
img *image.Image
|
||||
option Option
|
||||
expectedTrees []*tree.FileTree
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
name: "AllLayersGoCase",
|
||||
option: AllLayersScope,
|
||||
img: testScopeImage(t),
|
||||
expectedTrees: []*tree.FileTree{refImg.Layers[0].Tree, refImg.Layers[1].Tree},
|
||||
},
|
||||
{
|
||||
name: "SquashedGoCase",
|
||||
option: SquashedScope,
|
||||
img: testScopeImage(t),
|
||||
expectedTrees: []*tree.FileTree{refImg.SquashedTree},
|
||||
},
|
||||
{
|
||||
name: "MissingImage",
|
||||
option: SquashedScope,
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "MissingSquashedTree",
|
||||
option: SquashedScope,
|
||||
img: image.NewImage(nil),
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
name: "NoLayers",
|
||||
option: AllLayersScope,
|
||||
img: image.NewImage(nil),
|
||||
err: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
actual, err := NewScope(c.img, c.option)
|
||||
if err == nil && c.err {
|
||||
t.Fatal("expected an error but did not find one")
|
||||
} else if err != nil && !c.err {
|
||||
t.Fatal("expected no error but found one:", err)
|
||||
}
|
||||
|
||||
if len(actual.Trees) != len(c.expectedTrees) {
|
||||
t.Fatalf("mismatched tree lengths: %d!=%d", len(actual.Trees), len(c.expectedTrees))
|
||||
}
|
||||
|
||||
for idx, at := range actual.Trees {
|
||||
if !at.Equal(c.expectedTrees[idx]) {
|
||||
t.Error("mismatched tree @ idx", idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
2
main.go
2
main.go
|
@ -18,4 +18,4 @@ func main() {
|
|||
})
|
||||
|
||||
cmd.Execute()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue