Created
October 6, 2023 15:23
-
-
Save wagoodman/5d654cec6ac23063cb7551d5e8ac973e to your computer and use it in GitHub Desktop.
Using syft source and file resolver objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"github.com/anchore/syft/syft/artifact" | |
"github.com/anchore/syft/syft/file" | |
"github.com/anchore/syft/syft/pkg" | |
"github.com/anchore/syft/syft/pkg/cataloger/generic" | |
"github.com/anchore/syft/syft/source" | |
"io" | |
) | |
func main() { | |
// I've got the following layout: | |
// . | |
// ├── main.go | |
// └── where | |
// └── lib | |
// └── is | |
// └── thing <--- has "contents!" in the file | |
fmt.Println("via directory source...") | |
dirExample() | |
fmt.Println("via file source...") | |
fileExample() | |
fmt.Println("with cataloger pattern...") | |
catalogerExample() | |
} | |
func dirExample() { | |
// we want to make a single source object to access all of the files of interest. | |
src, err := source.NewFromDirectory(source.DirectoryConfig{ | |
Path: "./where", | |
}) | |
handleErr(err) | |
// in the context of a directory the scope doesn't matter, but if this was a container image this would be relevant. | |
resolver, err := src.FileResolver(source.SquashedScope) | |
handleErr(err) | |
// let's look for all files that match the glob pattern "**/thing" | |
locations, err := resolver.FilesByGlob("**/thing") | |
handleErr(err) | |
//// alternatively, we could have referenced the exact path we're interested in. | |
//// Note that this is the path within the analysis path ("./where/" is the analysis path, so "./lib/is/thing" | |
//// is the path to the file we're interested in). | |
//locations, err := resolver.FilesByPath("./lib/is/thing") | |
//handleErr(err) | |
for _, location := range locations { | |
printContents(resolver, location) | |
} | |
} | |
func fileExample() { | |
// let's look at a single file (not ideal, but possible). This can be treated like a directory that contains | |
// the single file of interest (in this case "thing"). | |
src, err := source.NewFromFile(source.FileConfig{ | |
Path: "./where/lib/is/thing", | |
}) | |
handleErr(err) | |
resolver, err := src.FileResolver(source.SquashedScope) | |
handleErr(err) | |
// reference the exact path we're interested in. | |
locations, err := resolver.FilesByPath("thing") | |
handleErr(err) | |
//// alternatively, let's look for all files that match the glob pattern "**/thing" | |
//locations, err := resolver.FilesByGlob("**/thing") | |
//handleErr(err) | |
for _, location := range locations { | |
printContents(resolver, location) | |
} | |
} | |
func catalogerExample() { | |
// we have a generic cataloger that allows for handler functions to be registered for specific file patterns. | |
cat := generic.NewCataloger("my-cataloger"). | |
WithParserByGlobs(thingParser, "**/thing") | |
// we want to make a single source object to access all of the files of interest. | |
src, err := source.NewFromDirectory(source.DirectoryConfig{ | |
Path: "./where", | |
}) | |
handleErr(err) | |
// in the context of a directory the scope doesn't matter, but if this was a container image this would be relevant. | |
resolver, err := src.FileResolver(source.SquashedScope) | |
handleErr(err) | |
_, _, err = cat.Catalog(resolver) | |
handleErr(err) | |
} | |
func thingParser(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { | |
// we're given a reader to the contents of the file we're interested in | |
contents, err := io.ReadAll(reader) | |
handleErr(err) | |
fmt.Println(string(contents)) | |
// assuming that the "thing" we parsed has packages we can return those here | |
return nil, nil, nil | |
} | |
func printContents(resolver file.Resolver, location file.Location) { | |
// now that we have a location we can get the file contents | |
reader, err := resolver.FileContentsByLocation(location) | |
handleErr(err) | |
contents, err := io.ReadAll(reader) | |
handleErr(err) | |
fmt.Println(string(contents)) | |
} | |
func handleErr(err error) { | |
if err != nil { | |
panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment