mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
support home dir expansion (#188)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
2844b9878f
commit
4b78d9a1c0
@ -9,7 +9,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
|
||||
"github.com/anchore/stereoscope"
|
||||
@ -48,7 +49,10 @@ type Scope struct {
|
||||
// NewScope produces a Scope based on userInput like dir: or image:tag
|
||||
func NewScope(userInput string, o Option) (Scope, func(), error) {
|
||||
fs := afero.NewOsFs()
|
||||
parsedScheme, location := detectScheme(fs, image.DetectSource, userInput)
|
||||
parsedScheme, location, err := detectScheme(fs, image.DetectSource, userInput)
|
||||
if err != nil {
|
||||
return Scope{}, func() {}, fmt.Errorf("unable to parse input=%q: %w", userInput, err)
|
||||
}
|
||||
|
||||
switch parsedScheme {
|
||||
case directoryScheme:
|
||||
@ -134,32 +138,39 @@ func (s Scope) Source() interface{} {
|
||||
|
||||
type sourceDetector func(string) (image.Source, string, error)
|
||||
|
||||
func detectScheme(fs afero.Fs, imageDetector sourceDetector, userInput string) (scheme, string) {
|
||||
func detectScheme(fs afero.Fs, imageDetector sourceDetector, userInput string) (scheme, string, error) {
|
||||
if strings.HasPrefix(userInput, "dir:") {
|
||||
// blindly trust the user's scheme
|
||||
return directoryScheme, strings.TrimPrefix(userInput, "dir:")
|
||||
dirLocation, err := homedir.Expand(strings.TrimPrefix(userInput, "dir:"))
|
||||
if err != nil {
|
||||
return unknownScheme, "", fmt.Errorf("unable to expand directory path: %w", err)
|
||||
}
|
||||
return directoryScheme, dirLocation, nil
|
||||
}
|
||||
|
||||
// we should attempt to let stereoscope determine what the source is first --just because the source is a valid directory
|
||||
// doesn't mean we yet know if it is an OCI layout directory (to be treated as an image) or if it is a generic filesystem directory.
|
||||
source, imageSpec, err := imageDetector(userInput)
|
||||
if err != nil {
|
||||
// this is not necessarily an error we care a
|
||||
log.Debugf("unable to detect the scheme from %q: %w", userInput, err)
|
||||
return unknownScheme, ""
|
||||
return unknownScheme, "", fmt.Errorf("unable to detect the scheme from %q: %w", userInput, err)
|
||||
}
|
||||
|
||||
if source == image.UnknownSource {
|
||||
fileMeta, err := fs.Stat(userInput)
|
||||
dirLocation, err := homedir.Expand(userInput)
|
||||
if err != nil {
|
||||
return unknownScheme, ""
|
||||
return unknownScheme, "", fmt.Errorf("unable to expand potential directory path: %w", err)
|
||||
}
|
||||
|
||||
fileMeta, err := fs.Stat(dirLocation)
|
||||
if err != nil {
|
||||
return unknownScheme, "", nil
|
||||
}
|
||||
|
||||
if fileMeta.IsDir() {
|
||||
return directoryScheme, userInput
|
||||
return directoryScheme, dirLocation, nil
|
||||
}
|
||||
return unknownScheme, ""
|
||||
return unknownScheme, "", nil
|
||||
}
|
||||
|
||||
return imageScheme, imageSpec
|
||||
return imageScheme, imageSpec, nil
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package scope
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/afero"
|
||||
"os"
|
||||
"testing"
|
||||
@ -368,30 +369,94 @@ func TestDetectScheme(t *testing.T) {
|
||||
expectedScheme: directoryScheme,
|
||||
expectedLocation: ".",
|
||||
},
|
||||
// we should support tilde expansion
|
||||
{
|
||||
name: "tilde-expansion-image-implicit",
|
||||
userInput: "~/some-path",
|
||||
detection: detectorResult{
|
||||
src: image.OciDirectorySource,
|
||||
ref: "~/some-path",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-implicit",
|
||||
userInput: "~/some-path",
|
||||
detection: detectorResult{
|
||||
src: image.UnknownSource,
|
||||
ref: "",
|
||||
},
|
||||
dirs: []string{"~/some-path"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-explicit-exists",
|
||||
userInput: "dir:~/some-path",
|
||||
dirs: []string{"~/some-path"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-explicit-dne",
|
||||
userInput: "dir:~/some-path",
|
||||
expectedScheme: directoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-implicit-dne",
|
||||
userInput: "~/some-path",
|
||||
expectedScheme: unknownScheme,
|
||||
expectedLocation: "",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fs := afero.NewMemMapFs()
|
||||
|
||||
for _, p := range test.dirs {
|
||||
err := fs.Mkdir(p, os.ModePerm)
|
||||
expandedExpectedLocation, err := homedir.Expand(p)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to expand path=%q: %+v", p, err)
|
||||
}
|
||||
err = fs.Mkdir(expandedExpectedLocation, os.ModePerm)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create dummy tar: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
imageDetector := func(string) (image.Source, string, error) {
|
||||
return test.detection.src, test.detection.ref, test.detection.err
|
||||
// lean on the users real home directory value
|
||||
switch test.detection.src {
|
||||
case image.OciDirectorySource, image.DockerTarballSource, image.OciTarballSource:
|
||||
expandedExpectedLocation, err := homedir.Expand(test.expectedLocation)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to expand path=%q: %+v", test.expectedLocation, err)
|
||||
}
|
||||
return test.detection.src, expandedExpectedLocation, test.detection.err
|
||||
default:
|
||||
return test.detection.src, test.detection.ref, test.detection.err
|
||||
}
|
||||
}
|
||||
|
||||
actualScheme, actualLocation := detectScheme(fs, imageDetector, test.userInput)
|
||||
actualScheme, actualLocation, err := detectScheme(fs, imageDetector, test.userInput)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err : %+v", err)
|
||||
}
|
||||
|
||||
if actualScheme != test.expectedScheme {
|
||||
t.Errorf("expected scheme %q , got %q", test.expectedScheme, actualScheme)
|
||||
}
|
||||
|
||||
if actualLocation != test.expectedLocation {
|
||||
t.Errorf("expected location %q , got %q", test.expectedLocation, actualLocation)
|
||||
// lean on the users real home directory value
|
||||
expandedExpectedLocation, err := homedir.Expand(test.expectedLocation)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to expand path=%q: %+v", test.expectedLocation, err)
|
||||
}
|
||||
|
||||
if actualLocation != expandedExpectedLocation {
|
||||
t.Errorf("expected location %q , got %q", expandedExpectedLocation, actualLocation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user