mirror of
https://github.com/anchore/grype
synced 2024-11-14 00:07:08 +00:00
151 lines
3.3 KiB
Go
151 lines
3.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
"github.com/wagoodman/go-partybus"
|
|
|
|
"github.com/anchore/grype/grype/db"
|
|
"github.com/anchore/grype/grype/differ"
|
|
"github.com/anchore/grype/grype/event"
|
|
"github.com/anchore/grype/internal/bus"
|
|
"github.com/anchore/grype/internal/log"
|
|
"github.com/anchore/grype/internal/ui"
|
|
"github.com/anchore/stereoscope"
|
|
)
|
|
|
|
var dbDiffOutputFormat string
|
|
|
|
const deleteFlag string = "delete"
|
|
|
|
var dbDiffCmd = &cobra.Command{
|
|
Use: "diff [flags] base_db_url target_db_url",
|
|
Short: "diff two DBs and display the result",
|
|
Args: cobra.MaximumNArgs(2),
|
|
RunE: runDBDiffCmd,
|
|
}
|
|
|
|
func init() {
|
|
dbDiffCmd.Flags().StringVarP(&dbDiffOutputFormat, "output", "o", "table", "format to display results (available=[table, json])")
|
|
dbDiffCmd.Flags().BoolP(deleteFlag, "d", false, "delete downloaded databases after diff occurs")
|
|
|
|
dbCmd.AddCommand(dbDiffCmd)
|
|
}
|
|
|
|
func startDBDiffCmd(base string, target string, deleteDatabases bool) <-chan error {
|
|
errs := make(chan error)
|
|
go func() {
|
|
defer close(errs)
|
|
d, err := differ.NewDiffer(appConfig.DB.ToCuratorConfig())
|
|
if err != nil {
|
|
errs <- err
|
|
return
|
|
}
|
|
|
|
if err := d.SetBaseDB(base); err != nil {
|
|
errs <- err
|
|
return
|
|
}
|
|
|
|
if err := d.SetTargetDB(target); err != nil {
|
|
errs <- err
|
|
return
|
|
}
|
|
|
|
diff, err := d.DiffDatabases()
|
|
if err != nil {
|
|
errs <- err
|
|
return
|
|
}
|
|
|
|
if len(*diff) == 0 {
|
|
fmt.Println("Databases are identical!")
|
|
} else {
|
|
err := d.Present(dbDiffOutputFormat, diff, os.Stdout)
|
|
if err != nil {
|
|
errs <- err
|
|
}
|
|
}
|
|
|
|
if deleteDatabases {
|
|
errs <- d.DeleteDatabases()
|
|
}
|
|
|
|
bus.Publish(partybus.Event{
|
|
Type: event.NonRootCommandFinished,
|
|
Value: "",
|
|
})
|
|
}()
|
|
return errs
|
|
}
|
|
|
|
func runDBDiffCmd(cmd *cobra.Command, args []string) error {
|
|
reporter, closer, err := reportWriter()
|
|
defer func() {
|
|
if err := closer(); err != nil {
|
|
log.Warnf("unable to write to report destination: %+v", err)
|
|
}
|
|
}()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
deleteDatabases, err := cmd.Flags().GetBool(deleteFlag)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var base, target string
|
|
|
|
switch len(args) {
|
|
case 0:
|
|
log.Info("base_db_url and target_db_url not provided; fetching most recent")
|
|
base, target, err = getDefaultURLs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
case 1:
|
|
log.Info("target_db_url not provided; fetching most recent")
|
|
base = args[0]
|
|
_, target, err = getDefaultURLs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
default:
|
|
base = args[0]
|
|
target = args[1]
|
|
}
|
|
|
|
return eventLoop(
|
|
startDBDiffCmd(base, target, deleteDatabases),
|
|
setupSignals(),
|
|
eventSubscription,
|
|
stereoscope.Cleanup,
|
|
ui.Select(isVerbose(), appConfig.Quiet, reporter)...,
|
|
)
|
|
}
|
|
|
|
func getDefaultURLs() (baseURL string, targetURL string, err error) {
|
|
dbCurator, err := db.NewCurator(appConfig.DB.ToCuratorConfig())
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
listing, err := dbCurator.ListingFromURL()
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
supportedSchema := dbCurator.SupportedSchema()
|
|
available, exists := listing.Available[supportedSchema]
|
|
if len(available) < 2 || !exists {
|
|
return "", "", stderrPrintLnf("Not enough databases available for the current schema to diff (%d)", supportedSchema)
|
|
}
|
|
|
|
targetURL = available[0].URL.String()
|
|
baseURL = available[1].URL.String()
|
|
|
|
return baseURL, targetURL, nil
|
|
}
|