mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
Bug fix for 1095 - syft conversion option error (#1177)
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
2c882f6239
commit
615f933d98
@ -11,6 +11,9 @@ ignore-packages:
|
|||||||
# packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
|
# packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
|
||||||
- github.com/anchore/packageurl-go
|
- github.com/anchore/packageurl-go
|
||||||
|
|
||||||
|
# crypto/internal/boring is released under the openSSL license as a part of the Golang Standard Libary
|
||||||
|
- crypto/internal/boring
|
||||||
|
|
||||||
# from: https://github.com/spdx/tools-golang/blob/main/LICENSE.code
|
# from: https://github.com/spdx/tools-golang/blob/main/LICENSE.code
|
||||||
# The tools-golang source code is provided and may be used, at your option,
|
# The tools-golang source code is provided and may be used, at your option,
|
||||||
# under either:
|
# under either:
|
||||||
|
|||||||
@ -49,7 +49,7 @@ func New() (*cobra.Command, error) {
|
|||||||
// root options are also passed to the attestCmd so that a user provided config location can be discovered
|
// root options are also passed to the attestCmd so that a user provided config location can be discovered
|
||||||
attestCmd := Attest(v, app, ro)
|
attestCmd := Attest(v, app, ro)
|
||||||
poweruserCmd := PowerUser(v, app, ro)
|
poweruserCmd := PowerUser(v, app, ro)
|
||||||
convertCmd := Convert(v, app, ro)
|
convertCmd := Convert(v, app, ro, po)
|
||||||
|
|
||||||
// rootCmd is currently an alias for the packages command
|
// rootCmd is currently an alias for the packages command
|
||||||
rootCmd := &cobra.Command{
|
rootCmd := &cobra.Command{
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/anchore/syft/cmd/syft/cli/convert"
|
"github.com/anchore/syft/cmd/syft/cli/convert"
|
||||||
"github.com/anchore/syft/cmd/syft/cli/options"
|
"github.com/anchore/syft/cmd/syft/cli/options"
|
||||||
@ -17,7 +18,8 @@ const (
|
|||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
func Convert(v *viper.Viper, app *config.Application, ro *options.RootOptions) *cobra.Command {
|
//nolint:dupl
|
||||||
|
func Convert(v *viper.Viper, app *config.Application, ro *options.RootOptions, po *options.PackagesOptions) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "convert [SOURCE-SBOM] -o [FORMAT]",
|
Use: "convert [SOURCE-SBOM] -o [FORMAT]",
|
||||||
Short: "Convert between SBOM formats",
|
Short: "Convert between SBOM formats",
|
||||||
@ -43,5 +45,11 @@ func Convert(v *viper.Viper, app *config.Application, ro *options.RootOptions) *
|
|||||||
return convert.Run(cmd.Context(), app, args)
|
return convert.Run(cmd.Context(), app, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := po.AddFlags(cmd, v)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/anchore/syft/cmd/syft/cli/options"
|
"github.com/anchore/syft/cmd/syft/cli/options"
|
||||||
|
|
||||||
"github.com/anchore/syft/cmd/syft/cli/packages"
|
"github.com/anchore/syft/cmd/syft/cli/packages"
|
||||||
"github.com/anchore/syft/internal"
|
"github.com/anchore/syft/internal"
|
||||||
"github.com/anchore/syft/internal/config"
|
"github.com/anchore/syft/internal/config"
|
||||||
@ -44,6 +45,7 @@ const (
|
|||||||
packagesHelp = packagesExample + packagesSchemeHelp
|
packagesHelp = packagesExample + packagesSchemeHelp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//nolint:dupl
|
||||||
func Packages(v *viper.Viper, app *config.Application, ro *options.RootOptions, po *options.PackagesOptions) *cobra.Command {
|
func Packages(v *viper.Viper, app *config.Application, ro *options.RootOptions, po *options.PackagesOptions) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "packages [SOURCE]",
|
Use: "packages [SOURCE]",
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package file
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/bmatcuk/doublestar/v4"
|
"github.com/bmatcuk/doublestar/v4"
|
||||||
@ -33,7 +33,7 @@ func ExtractGlobsFromTarToUniqueTempFile(archivePath, dir string, globs ...strin
|
|||||||
|
|
||||||
// we have a file we want to extract....
|
// we have a file we want to extract....
|
||||||
tempfilePrefix := filepath.Base(filepath.Clean(file.Name())) + "-"
|
tempfilePrefix := filepath.Base(filepath.Clean(file.Name())) + "-"
|
||||||
tempFile, err := ioutil.TempFile(dir, tempfilePrefix)
|
tempFile, err := os.CreateTemp(dir, tempfilePrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create temp file: %w", err)
|
return fmt.Errorf("unable to create temp file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -82,7 +81,7 @@ func ExtractFromZipToUniqueTempFile(archivePath, dir string, paths ...string) (m
|
|||||||
visitor := func(file *zip.File) error {
|
visitor := func(file *zip.File) error {
|
||||||
tempfilePrefix := filepath.Base(filepath.Clean(file.Name)) + "-"
|
tempfilePrefix := filepath.Base(filepath.Clean(file.Name)) + "-"
|
||||||
|
|
||||||
tempFile, err := ioutil.TempFile(dir, tempfilePrefix)
|
tempFile, err := os.CreateTemp(dir, tempfilePrefix)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to create temp file: %w", err)
|
return fmt.Errorf("unable to create temp file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -55,7 +54,7 @@ func NewLogrusLogger(cfg LogrusConfig) *LogrusLogger {
|
|||||||
}
|
}
|
||||||
output = logFile
|
output = logFile
|
||||||
default:
|
default:
|
||||||
output = ioutil.Discard
|
output = io.Discard
|
||||||
}
|
}
|
||||||
|
|
||||||
appLogger.SetOutput(output)
|
appLogger.SetOutput(output)
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package version
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ func fetchLatestApplicationVersion() (*hashiVersion.Version, error) {
|
|||||||
return nil, fmt.Errorf("HTTP %d on fetching latest version: %s", resp.StatusCode, resp.Status)
|
return nil, fmt.Errorf("HTTP %d on fetching latest version: %s", resp.StatusCode, resp.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
versionBytes, err := ioutil.ReadAll(resp.Body)
|
versionBytes, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read latest version: %w", err)
|
return nil, fmt.Errorf("failed to read latest version: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -118,7 +118,7 @@ func write(schema []byte) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
existingSchemaBytes, err := ioutil.ReadAll(existingFh)
|
existingSchemaBytes, err := io.ReadAll(existingFh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package linux
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ func IdentifyRelease(resolver source.FileResolver) *Release {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err := ioutil.ReadAll(contentReader)
|
content, err := io.ReadAll(contentReader)
|
||||||
internal.CloseAndLogError(contentReader, location.VirtualPath)
|
internal.CloseAndLogError(contentReader, location.VirtualPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("unable to read %q: %+v", location.RealPath, err)
|
log.Warnf("unable to read %q: %+v", location.RealPath, err)
|
||||||
|
|||||||
@ -3,7 +3,6 @@ package golang
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
@ -15,7 +14,7 @@ import (
|
|||||||
func parseGoMod(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
|
func parseGoMod(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
|
||||||
packages := make(map[string]*pkg.Package)
|
packages := make(map[string]*pkg.Package)
|
||||||
|
|
||||||
contents, err := ioutil.ReadAll(reader)
|
contents, err := io.ReadAll(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to read go module: %w", err)
|
return nil, nil, fmt.Errorf("failed to read go module: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
macho "github.com/anchore/go-macholibre"
|
macho "github.com/anchore/go-macholibre"
|
||||||
"github.com/anchore/syft/internal/log"
|
"github.com/anchore/syft/internal/log"
|
||||||
@ -45,7 +44,7 @@ func GetUnionReader(readerCloser io.ReadCloser) (UnionReader, error) {
|
|||||||
return reader, nil
|
return reader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(readerCloser)
|
b, err := io.ReadAll(readerCloser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to read contents from binary: %w", err)
|
return nil, fmt.Errorf("unable to read contents from binary: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,6 @@ package source
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -345,7 +344,7 @@ func (s *Source) FileResolver(scope Scope) (FileResolver, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func unarchiveToTmp(path string, unarchiver archiver.Unarchiver) (string, func(), error) {
|
func unarchiveToTmp(path string, unarchiver archiver.Unarchiver) (string, func(), error) {
|
||||||
tempDir, err := ioutil.TempDir("", "syft-archive-contents-")
|
tempDir, err := os.MkdirTemp("", "syft-archive-contents-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", func() {}, fmt.Errorf("unable to create tempdir for archive processing: %w", err)
|
return "", func() {}, fmt.Errorf("unable to create tempdir for archive processing: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
78
test/cli/all_formats_convertible_test.go
Normal file
78
test/cli/all_formats_convertible_test.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package cli
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type conversion struct {
|
||||||
|
To string
|
||||||
|
From string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertCmdFlags(t *testing.T) {
|
||||||
|
commonAssertions := []traitAssertion{
|
||||||
|
func(tb testing.TB, stdout, _ string, _ int) {
|
||||||
|
tb.Helper()
|
||||||
|
if len(stdout) < 1000 {
|
||||||
|
tb.Errorf("there may not be any report output (len=%d)", len(stdout))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
assertSuccessfulReturnCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
conversions []conversion
|
||||||
|
env map[string]string
|
||||||
|
assertions []traitAssertion
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "syft-format convertable to spdx-json",
|
||||||
|
conversions: []conversion{
|
||||||
|
{To: "syft-json", From: "spdx-json"},
|
||||||
|
{To: "syft-json", From: "cyclonedx-json"},
|
||||||
|
{To: "spdx-json", From: "syft-json"},
|
||||||
|
{To: "spdx-json", From: "cyclonedx-json"},
|
||||||
|
{To: "cyclonedx-json", From: "syft-json"},
|
||||||
|
{To: "cyclonedx-json", From: "spdx-json"},
|
||||||
|
},
|
||||||
|
assertions: commonAssertions,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
for _, c := range test.conversions {
|
||||||
|
sbomArgs := []string{"dir:./test-fixtures/image-pkg-coverage", "-o", c.From}
|
||||||
|
cmd, stdout, stderr := runSyft(t, test.env, sbomArgs...)
|
||||||
|
if cmd.ProcessState.ExitCode() != 0 {
|
||||||
|
t.Fatalf("failure executing syft creating an sbom")
|
||||||
|
t.Log("STDOUT:\n", stdout)
|
||||||
|
t.Log("STDERR:\n", stderr)
|
||||||
|
t.Log("COMMAND:", strings.Join(cmd.Args, " "))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
sbomFile := filepath.Join(tempDir, "sbom.json")
|
||||||
|
require.NoError(t, os.WriteFile(sbomFile, []byte(stdout), 0666))
|
||||||
|
|
||||||
|
convertArgs := []string{"convert", sbomFile, "-o", c.To}
|
||||||
|
cmd, stdout, stderr = runSyft(t, test.env, convertArgs...)
|
||||||
|
for _, traitFn := range test.assertions {
|
||||||
|
traitFn(t, stdout, stderr, cmd.ProcessState.ExitCode())
|
||||||
|
}
|
||||||
|
if t.Failed() {
|
||||||
|
t.Log("STDOUT:\n", stdout)
|
||||||
|
t.Log("STDERR:\n", stderr)
|
||||||
|
t.Log("COMMAND:", strings.Join(cmd.Args, " "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user