github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/gosbom/source/scheme.go (about) 1 package source 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/mitchellh/go-homedir" 8 "github.com/spf13/afero" 9 10 "github.com/anchore/stereoscope/pkg/image" 11 ) 12 13 // Scheme represents the optional prefixed string at the beginning of a user request (e.g. "docker:"). 14 type Scheme string 15 16 const ( 17 // UnknownScheme is the default scheme 18 UnknownScheme Scheme = "UnknownScheme" 19 // DirectoryScheme indicates the source being cataloged is a directory on the root filesystem 20 DirectoryScheme Scheme = "DirectoryScheme" 21 // ImageScheme indicates the source being cataloged is a container image 22 ImageScheme Scheme = "ImageScheme" 23 // FileScheme indicates the source being cataloged is a single file 24 FileScheme Scheme = "FileScheme" 25 ) 26 27 var AllSchemes = []Scheme{ 28 DirectoryScheme, 29 ImageScheme, 30 FileScheme, 31 } 32 33 func DetectScheme(fs afero.Fs, imageDetector sourceDetector, userInput string) (Scheme, image.Source, string, error) { 34 switch { 35 case strings.HasPrefix(userInput, "dir:"): 36 dirLocation, err := homedir.Expand(strings.TrimPrefix(userInput, "dir:")) 37 if err != nil { 38 return UnknownScheme, image.UnknownSource, "", fmt.Errorf("unable to expand directory path: %w", err) 39 } 40 return DirectoryScheme, image.UnknownSource, dirLocation, nil 41 42 case strings.HasPrefix(userInput, "file:"): 43 fileLocation, err := homedir.Expand(strings.TrimPrefix(userInput, "file:")) 44 if err != nil { 45 return UnknownScheme, image.UnknownSource, "", fmt.Errorf("unable to expand directory path: %w", err) 46 } 47 return FileScheme, image.UnknownSource, fileLocation, nil 48 } 49 50 // try the most specific sources first and move out towards more generic sources. 51 52 // first: let's try the image detector, which has more scheme parsing internal to stereoscope 53 source, imageSpec, err := imageDetector(userInput) 54 if err == nil && source != image.UnknownSource { 55 return ImageScheme, source, imageSpec, nil 56 } 57 58 // next: let's try more generic sources (dir, file, etc.) 59 location, err := homedir.Expand(userInput) 60 if err != nil { 61 return UnknownScheme, image.UnknownSource, "", fmt.Errorf("unable to expand potential directory path: %w", err) 62 } 63 64 fileMeta, err := fs.Stat(location) 65 if err != nil { 66 return UnknownScheme, source, "", nil 67 } 68 69 if fileMeta.IsDir() { 70 return DirectoryScheme, source, location, nil 71 } 72 73 return FileScheme, source, location, nil 74 }