diff --git a/cmd/query.go b/cmd/query.go index 81423a7cb3..7ba518bd75 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -76,7 +76,7 @@ Examples: AddStringArrayFlag(pconstants.ArgSnapshotTag, nil, "Specify tags to set on the snapshot"). AddStringFlag(pconstants.ArgSnapshotTitle, "", "The title to give a snapshot"). AddIntFlag(pconstants.ArgDatabaseQueryTimeout, 0, "The query timeout"). - AddStringSliceFlag(pconstants.ArgExport, nil, "Export output to file, supported format: sps (snapshot)"). + AddStringSliceFlag(pconstants.ArgExport, nil, "Export output to file, supported formats: csv, json, sps (snapshot)"). AddStringFlag(pconstants.ArgSnapshotLocation, "", "The location to write snapshots - either a local file path or a Turbot Pipes workspace"). AddBoolFlag(pconstants.ArgProgress, true, "Display snapshot upload status") diff --git a/pkg/export/snapshot_exporter.go b/pkg/export/snapshot_exporter.go deleted file mode 100644 index ab01478387..0000000000 --- a/pkg/export/snapshot_exporter.go +++ /dev/null @@ -1,41 +0,0 @@ -package export - -import ( - "context" - "fmt" - "strings" - - "github.com/turbot/pipe-fittings/v2/steampipeconfig" - "github.com/turbot/steampipe/v2/pkg/constants" -) - -type SnapshotExporter struct { - ExporterBase -} - -func (e *SnapshotExporter) Export(_ context.Context, input ExportSourceData, filePath string) error { - snapshot, ok := input.(*steampipeconfig.SteampipeSnapshot) - if !ok { - return fmt.Errorf("SnapshotExporter input must be *dashboardtypes.SteampipeSnapshot") - } - snapshotBytes, err := snapshot.AsStrippedJson(false) - if err != nil { - return err - } - - res := strings.NewReader(fmt.Sprintf("%s\n", string(snapshotBytes))) - - return Write(filePath, res) -} - -func (e *SnapshotExporter) FileExtension() string { - return constants.SnapshotExtension -} - -func (e *SnapshotExporter) Name() string { - return constants.OutputFormatSnapshot -} - -func (*SnapshotExporter) Alias() string { - return "sps" -} diff --git a/pkg/initialisation/init_data.go b/pkg/initialisation/init_data.go index 139b049a34..20fb3f6f45 100644 --- a/pkg/initialisation/init_data.go +++ b/pkg/initialisation/init_data.go @@ -16,7 +16,7 @@ import ( "github.com/turbot/steampipe/v2/pkg/db/db_client" "github.com/turbot/steampipe/v2/pkg/db/db_common" "github.com/turbot/steampipe/v2/pkg/db/db_local" - "github.com/turbot/steampipe/v2/pkg/export" + "github.com/turbot/pipe-fittings/v2/export" "github.com/turbot/steampipe/v2/pkg/statushooks" ) diff --git a/pkg/query/init_data.go b/pkg/query/init_data.go index 8ab025a6e6..78350b93a3 100644 --- a/pkg/query/init_data.go +++ b/pkg/query/init_data.go @@ -14,9 +14,9 @@ import ( "github.com/turbot/steampipe/v2/pkg/constants" "github.com/turbot/steampipe/v2/pkg/db/db_client" "github.com/turbot/steampipe/v2/pkg/error_helpers" - "github.com/turbot/steampipe/v2/pkg/export" "github.com/turbot/steampipe/v2/pkg/initialisation" "github.com/turbot/steampipe/v2/pkg/statushooks" + "github.com/turbot/pipe-fittings/v2/export" ) type InitData struct { @@ -47,7 +47,7 @@ func NewInitData(ctx context.Context, args []string) *InitData { } func queryExporters() []export.Exporter { - return []export.Exporter{&export.SnapshotExporter{}} + return []export.Exporter{&export.SnapshotExporter{}, &export.CsvExporter{}, &export.JsonExporter{}} } func (i *InitData) Cancel() { diff --git a/pkg/query/queryexecute/execute.go b/pkg/query/queryexecute/execute.go index 247eac7369..254609645b 100644 --- a/pkg/query/queryexecute/execute.go +++ b/pkg/query/queryexecute/execute.go @@ -184,6 +184,18 @@ func executeQuery(ctx context.Context, initData *query.InitData, resolvedQuery * return nil, rowErrors } + if needCsvOrJson() { + exportArgs := viper.GetStringSlice(pconstants.ArgExport) + exportMsg, err := initData.ExportManager.DoExport(ctx, "query", r, exportArgs) + if err != nil { + return err, 0 + } + if len(exportMsg) > 0 && viper.GetBool(pconstants.ArgProgress) { + fmt.Printf("\n") //nolint:forbidigo // intentional use of fmt + fmt.Println(strings.Join(exportMsg, "\n")) //nolint:forbidigo // intentional use of fmt + fmt.Printf("\n") //nolint:forbidigo // intentional use of fmt + } + } // for other output formats, we call the querydisplay code in pipe-fittings rowCount, rowErrs := querydisplay.ShowOutput(ctx, r) // show timing @@ -201,9 +213,17 @@ func needSnapshot() bool { outputFormat := viper.GetString(pconstants.ArgOutput) shouldShare := viper.GetBool(pconstants.ArgShare) shouldUpload := viper.GetBool(pconstants.ArgSnapshot) + exportArgs := viper.GetStringSlice(constants.ArgExport) + isSnapshot := false + for _, arg := range exportArgs { + argLower := strings.ToLower(arg) + if strings.Contains(argLower, "pps") { + isSnapshot = true + } + } // Check if the output format is a snapshot format or if ArgExport is set - if outputFormat == pconstants.OutputFormatSnapshot || outputFormat == pconstants.OutputFormatSteampipeSnapshotShort || viper.IsSet(pconstants.ArgExport) || shouldShare || shouldUpload { + if outputFormat == pconstants.OutputFormatSnapshot || outputFormat == pconstants.OutputFormatSteampipeSnapshotShort || isSnapshot || shouldShare || shouldUpload { return true } @@ -211,6 +231,17 @@ func needSnapshot() bool { return false } +func needCsvOrJson() bool { + exportArgs := viper.GetStringSlice(constants.ArgExport) + for _, arg := range exportArgs { + argLower := strings.ToLower(arg) + if strings.Contains(argLower, "csv") || strings.Contains(argLower, "json") { + return true + } + } + return false +} + func publishSnapshotIfNeeded(ctx context.Context, snapshot *steampipeconfig.SteampipeSnapshot) error { shouldShare := viper.GetBool(pconstants.ArgShare) shouldUpload := viper.GetBool(pconstants.ArgSnapshot)