diff --git a/app/cli/cmd/attached_integration_add.go b/app/cli/cmd/attached_integration_add.go index 203d050cc..de53f78f0 100644 --- a/app/cli/cmd/attached_integration_add.go +++ b/app/cli/cmd/attached_integration_add.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -61,7 +62,7 @@ func newAttachedIntegrationAttachCmd() *cobra.Command { return err } - return encodeOutput([]*action.AttachedIntegrationItem{res}, attachedIntegrationListTableOutput) + return output.EncodeOutput(flagOutputFormat, []*action.AttachedIntegrationItem{res}, attachedIntegrationListTableOutput) }, } diff --git a/app/cli/cmd/attached_integration_list.go b/app/cli/cmd/attached_integration_list.go index 9029741bd..3232ea593 100644 --- a/app/cli/cmd/attached_integration_list.go +++ b/app/cli/cmd/attached_integration_list.go @@ -20,6 +20,7 @@ import ( "strings" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -38,7 +39,7 @@ func newAttachedIntegrationListCmd() *cobra.Command { return err } - return encodeOutput(res, attachedIntegrationListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, attachedIntegrationListTableOutput) }, } @@ -58,7 +59,7 @@ func attachedIntegrationListTableOutput(attachments []*action.AttachedIntegratio fmt.Println("Integrations attached to workflows") } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"ID", "Kind", "Config", "Workflow", "Attached At"}) for _, attachment := range attachments { wf := attachment.Workflow diff --git a/app/cli/cmd/attestation_add.go b/app/cli/cmd/attestation_add.go index d3bff30a5..c22ea374e 100644 --- a/app/cli/cmd/attestation_add.go +++ b/app/cli/cmd/attestation_add.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/viper" "google.golang.org/grpc" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" "github.com/chainloop-dev/chainloop/pkg/resourceloader" @@ -118,7 +119,7 @@ func newAttestationAddCmd() *cobra.Command { return err } - return encodeOutput(resp, func(s *action.AttestationStatusMaterial) error { + return output.EncodeOutput(flagOutputFormat, resp, func(s *action.AttestationStatusMaterial) error { return displayMaterialInfo(s, policies[resp.Name]) }) }, @@ -168,7 +169,7 @@ func displayMaterialInfo(status *action.AttestationStatusMaterial, policyEvaluat return nil } - mt := newTableWriter() + mt := output.NewTableWriter() mt.AppendRow(table.Row{"Name", status.Material.Name}) mt.AppendRow(table.Row{"Type", status.Material.Type}) diff --git a/app/cli/cmd/attestation_init.go b/app/cli/cmd/attestation_init.go index 87b015f03..ca3c2874f 100644 --- a/app/cli/cmd/attestation_init.go +++ b/app/cli/cmd/attestation_init.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -129,7 +130,7 @@ func newAttestationInitCmd() *cobra.Command { logger.Warn().Msg("DEPRECATION WARNING: --project not set, this will be required in the near future") } - return encodeOutput(res, fullStatusTable) + return output.EncodeOutput(flagOutputFormat, res, fullStatusTable) }} // This option is only useful for local-based attestation states diff --git a/app/cli/cmd/attestation_push.go b/app/cli/cmd/attestation_push.go index 74d2aabba..117eed628 100644 --- a/app/cli/cmd/attestation_push.go +++ b/app/cli/cmd/attestation_push.go @@ -24,6 +24,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" ) @@ -106,7 +107,7 @@ func newAttestationPushCmd() *cobra.Command { res.Status.Digest = res.Digest // If we are returning the json format, we also want to render the attestation table as one property so it can also be consumed - if flagOutputFormat == formatJSON { + if flagOutputFormat == output.FormatJSON { // Render the attestation status to a string buf := &bytes.Buffer{} if err := fullStatusTableWithWriter(res.Status, buf); err != nil { @@ -117,7 +118,7 @@ func newAttestationPushCmd() *cobra.Command { } // In TABLE format, we render the attestation status - if err := encodeOutput(res.Status, fullStatusTable); err != nil { + if err := output.EncodeOutput(flagOutputFormat, res.Status, fullStatusTable); err != nil { return fmt.Errorf("failed to render output: %w", err) } diff --git a/app/cli/cmd/attestation_status.go b/app/cli/cmd/attestation_status.go index f6dcc6673..da4281468 100644 --- a/app/cli/cmd/attestation_status.go +++ b/app/cli/cmd/attestation_status.go @@ -28,6 +28,7 @@ import ( "github.com/muesli/reflow/wrap" "github.com/spf13/cobra" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/pkg/attestation/renderer/chainloop" ) @@ -58,12 +59,12 @@ func newAttestationStatusCmd() *cobra.Command { return err } - output := simpleStatusTable + outputF := simpleStatusTable if full { - output = fullStatusTable + outputF = fullStatusTable } - return encodeOutput(res, output) + return output.EncodeOutput(flagOutputFormat, res, outputF) }, } @@ -87,7 +88,7 @@ func fullStatusTableWithWriter(status *action.AttestationStatusResult, w io.Writ func attestationStatusTableOutput(status *action.AttestationStatusResult, w io.Writer, full bool) error { // General info table - gt := newTableWriterWithWriter(w) + gt := output.NewTableWriterWithWriter(w) gt.AppendRow(table.Row{"Initialized At", status.InitializedAt.Format(time.RFC822)}) gt.AppendSeparator() meta := status.WorkflowMeta @@ -154,7 +155,7 @@ func envVarsTable(status *action.AttestationStatusResult, w io.Writer, full bool if len(status.EnvVars) > 0 { // Env Variables table - evt := newTableWriterWithWriter(w) + evt := output.NewTableWriterWithWriter(w) evt.SetTitle("Env Variables") for k, v := range status.EnvVars { if v == "" { @@ -167,7 +168,7 @@ func envVarsTable(status *action.AttestationStatusResult, w io.Writer, full bool runnerVars := status.RunnerContext.EnvVars if len(runnerVars) > 0 && full { - evt := newTableWriterWithWriter(w) + evt := output.NewTableWriterWithWriter(w) evt.SetTitle("Runner context") for k, v := range runnerVars { if v == "" { @@ -190,7 +191,7 @@ func materialsTable(status *action.AttestationStatusResult, w io.Writer, full bo return strings.Compare(a.Name, b.Name) }) - mt := newTableWriterWithWriter(w) + mt := output.NewTableWriterWithWriter(w) mt.SetTitle("Materials") for _, m := range status.Materials { diff --git a/app/cli/cmd/available_integration_describe.go b/app/cli/cmd/available_integration_describe.go index fc139a4bd..68ca78b70 100644 --- a/app/cli/cmd/available_integration_describe.go +++ b/app/cli/cmd/available_integration_describe.go @@ -21,6 +21,7 @@ import ( "fmt" "sort" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/app/controlplane/plugins/sdk/v1" "github.com/jedib0t/go-pretty/v6/table" @@ -44,7 +45,7 @@ func newAvailableIntegrationDescribeCmd() *cobra.Command { return fmt.Errorf("integration %q not found", integrationName) } - return encodeOutput([]*action.AvailableIntegrationItem{item}, availableIntegrationDescribeTableOutput) + return output.EncodeOutput(flagOutputFormat, []*action.AvailableIntegrationItem{item}, availableIntegrationDescribeTableOutput) }, } @@ -97,7 +98,7 @@ func renderSchemaTable(tableTitle string, properties sdk.SchemaPropertiesMap) er return nil } - t := newTableWriter() + t := output.NewTableWriter() t.SetTitle(tableTitle) t.AppendHeader(table.Row{"Field", "Type", "Required", "Description"}) @@ -143,7 +144,7 @@ func renderSchemaRaw(tableTitle string, s string) error { return err } - rt := newTableWriter() + rt := output.NewTableWriter() rt.SetTitle(tableTitle) rt.AppendRow(table.Row{prettyAttachmentJSON.String()}) rt.Render() diff --git a/app/cli/cmd/available_integration_list.go b/app/cli/cmd/available_integration_list.go index 1cb5a1901..3948c6725 100644 --- a/app/cli/cmd/available_integration_list.go +++ b/app/cli/cmd/available_integration_list.go @@ -19,6 +19,7 @@ import ( "fmt" "strings" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -35,7 +36,7 @@ func newAvailableIntegrationListCmd() *cobra.Command { return err } - return encodeOutput(res, availableIntegrationListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, availableIntegrationListTableOutput) }, } @@ -48,7 +49,7 @@ func availableIntegrationListTableOutput(items []*action.AvailableIntegrationIte return nil } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"Name", "Version", "Material Requirement", "Description"}) for _, i := range items { t.AppendRow(table.Row{i.Name, i.Version, strings.Join(i.SubscribedInputs, ", "), i.Description}) diff --git a/app/cli/cmd/casbackend_add_azureblob.go b/app/cli/cmd/casbackend_add_azureblob.go index 85a548040..d69368890 100644 --- a/app/cli/cmd/casbackend_add_azureblob.go +++ b/app/cli/cmd/casbackend_add_azureblob.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/pkg/blobmanager/azureblob" "github.com/go-kratos/kratos/v2/log" @@ -70,7 +71,7 @@ func newCASBackendAddAzureBlobStorageCmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_add_oci.go b/app/cli/cmd/casbackend_add_oci.go index 591bd2bb3..eee9c75df 100644 --- a/app/cli/cmd/casbackend_add_oci.go +++ b/app/cli/cmd/casbackend_add_oci.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/go-kratos/kratos/v2/log" "github.com/spf13/cobra" @@ -65,7 +66,7 @@ func newCASBackendAddOCICmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_add_s3.go b/app/cli/cmd/casbackend_add_s3.go index f9449c6c8..cfab425bf 100644 --- a/app/cli/cmd/casbackend_add_s3.go +++ b/app/cli/cmd/casbackend_add_s3.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/pkg/blobmanager/s3" "github.com/go-kratos/kratos/v2/log" @@ -74,7 +75,7 @@ func newCASBackendAddAWSS3Cmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_list.go b/app/cli/cmd/casbackend_list.go index 8d1f40166..0c259c7a9 100644 --- a/app/cli/cmd/casbackend_list.go +++ b/app/cli/cmd/casbackend_list.go @@ -21,6 +21,7 @@ import ( "time" "code.cloudfoundry.org/bytefmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/muesli/reflow/wrap" @@ -38,7 +39,7 @@ func newCASBackendListCmd() *cobra.Command { return err } - return encodeOutput(res, casBackendListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendListTableOutput) }, } @@ -56,7 +57,7 @@ func casBackendListTableOutput(backends []*action.CASBackendItem) error { return nil } - t := newTableWriter() + t := output.NewTableWriter() header := table.Row{"Name", "Location", "Provider", "Description", "Limits", "Default", "Status"} if full { header = append(header, "Created At", "Validated At") diff --git a/app/cli/cmd/casbackend_update_azureblob.go b/app/cli/cmd/casbackend_update_azureblob.go index 53a7b7817..b67ddceb9 100644 --- a/app/cli/cmd/casbackend_update_azureblob.go +++ b/app/cli/cmd/casbackend_update_azureblob.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/go-kratos/kratos/v2/log" "github.com/spf13/cobra" @@ -63,7 +64,7 @@ func newCASBackendUpdateAzureBlobCmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_update_inline.go b/app/cli/cmd/casbackend_update_inline.go index 75640a2fe..ef96ee1d4 100644 --- a/app/cli/cmd/casbackend_update_inline.go +++ b/app/cli/cmd/casbackend_update_inline.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/go-kratos/kratos/v2/log" "github.com/spf13/cobra" @@ -53,7 +54,7 @@ func newCASBackendUpdateInlineCmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_update_oci.go b/app/cli/cmd/casbackend_update_oci.go index d9909a018..1cae0e07b 100644 --- a/app/cli/cmd/casbackend_update_oci.go +++ b/app/cli/cmd/casbackend_update_oci.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/go-kratos/kratos/v2/log" "github.com/spf13/cobra" @@ -61,7 +62,7 @@ func newCASBackendUpdateOCICmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/casbackend_update_s3.go b/app/cli/cmd/casbackend_update_s3.go index e6e1b16b0..583171b70 100644 --- a/app/cli/cmd/casbackend_update_s3.go +++ b/app/cli/cmd/casbackend_update_s3.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/go-kratos/kratos/v2/log" "github.com/spf13/cobra" @@ -63,7 +64,7 @@ func newCASBackendUpdateAWSS3Cmd() *cobra.Command { return nil } - return encodeOutput(res, casBackendItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, casBackendItemTableOutput) }, } diff --git a/app/cli/cmd/options/options.go b/app/cli/cmd/options/options.go index 439371a00..f613cf4d1 100644 --- a/app/cli/cmd/options/options.go +++ b/app/cli/cmd/options/options.go @@ -1,5 +1,5 @@ // -// Copyright 2023 The Chainloop Authors. +// Copyright 2023-2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,7 +15,9 @@ package options -import "github.com/spf13/cobra" +import ( + "github.com/spf13/cobra" +) type Interface interface { // AddFlags adds this options' flags to the cobra command. diff --git a/app/cli/cmd/organization_apitoken_create.go b/app/cli/cmd/organization_apitoken_create.go index 4f04aa2c5..de922abb4 100644 --- a/app/cli/cmd/organization_apitoken_create.go +++ b/app/cli/cmd/organization_apitoken_create.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -50,7 +51,7 @@ func newAPITokenCreateCmd() *cobra.Command { return nil } - return encodeOutput(res, apiTokenItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, apiTokenItemTableOutput) }, } @@ -76,7 +77,7 @@ func apiTokenListTableOutput(tokens []*action.APITokenItem) error { return nil } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"ID", "Name", "Scope", "Description", "Created At", "Expires At", "Revoked At", "Last used at"}) for _, p := range tokens { diff --git a/app/cli/cmd/organization_apitoken_list.go b/app/cli/cmd/organization_apitoken_list.go index 46a79edce..3ce1f0b20 100644 --- a/app/cli/cmd/organization_apitoken_list.go +++ b/app/cli/cmd/organization_apitoken_list.go @@ -20,6 +20,7 @@ import ( "fmt" "slices" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -53,7 +54,7 @@ func newAPITokenListCmd() *cobra.Command { return fmt.Errorf("listing API tokens: %w", err) } - return encodeOutput(res, apiTokenListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, apiTokenListTableOutput) }, } diff --git a/app/cli/cmd/organization_describe.go b/app/cli/cmd/organization_describe.go index 3bf3a9b73..858acf6b7 100644 --- a/app/cli/cmd/organization_describe.go +++ b/app/cli/cmd/organization_describe.go @@ -19,6 +19,7 @@ import ( "fmt" "strings" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -35,7 +36,7 @@ func newOrganizationDescribeCmd() *cobra.Command { return err } - return encodeOutput(res, contextTableOutput) + return output.EncodeOutput(flagOutputFormat, res, contextTableOutput) }, } @@ -43,7 +44,7 @@ func newOrganizationDescribeCmd() *cobra.Command { } func contextTableOutput(config *action.ConfigContextItem) error { - gt := newTableWriter() + gt := output.NewTableWriter() gt.SetTitle("Current Context") gt.AppendRow(table.Row{"Logged in as", config.CurrentUser.PrintUserProfileWithEmail()}) gt.AppendSeparator() diff --git a/app/cli/cmd/organization_invitation_create.go b/app/cli/cmd/organization_invitation_create.go index 71db0a734..5bc964e5c 100644 --- a/app/cli/cmd/organization_invitation_create.go +++ b/app/cli/cmd/organization_invitation_create.go @@ -19,6 +19,7 @@ import ( "context" "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -47,7 +48,7 @@ func newOrganizationInvitationCreateCmd() *cobra.Command { return err } - return encodeOutput([]*action.OrgInvitationItem{res}, orgInvitationTableOutput) + return output.EncodeOutput(flagOutputFormat, []*action.OrgInvitationItem{res}, orgInvitationTableOutput) }, } diff --git a/app/cli/cmd/organization_invitation_list_sent.go b/app/cli/cmd/organization_invitation_list_sent.go index 5d22fc094..147f32ddc 100644 --- a/app/cli/cmd/organization_invitation_list_sent.go +++ b/app/cli/cmd/organization_invitation_list_sent.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -36,7 +37,7 @@ func newOrganizationInvitationListSentCmd() *cobra.Command { return err } - return encodeOutput(res, orgInvitationTableOutput) + return output.EncodeOutput(flagOutputFormat, res, orgInvitationTableOutput) }, } @@ -49,7 +50,7 @@ func orgInvitationTableOutput(items []*action.OrgInvitationItem) error { return nil } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"ID", "Receiver Email", "Role", "Status", "Created At"}) for _, i := range items { diff --git a/app/cli/cmd/organization_list.go b/app/cli/cmd/organization_list.go index e86da2d0b..dc20c6aec 100644 --- a/app/cli/cmd/organization_list.go +++ b/app/cli/cmd/organization_list.go @@ -19,6 +19,7 @@ import ( "fmt" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -38,7 +39,7 @@ func newOrganizationList() *cobra.Command { return err } - return encodeOutput(res, orgMembershipTableOutput) + return output.EncodeOutput(flagOutputFormat, res, orgMembershipTableOutput) }, } @@ -54,7 +55,7 @@ func orgMembershipTableOutput(items []*action.MembershipItem) error { // Get the current organization from viper configuration currentOrg := viper.GetString(confOptions.organization.viperKey) - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"Name", "Current", "Default", "Role", "Default Policy strategy", "Joined At"}) for _, i := range items { diff --git a/app/cli/cmd/organization_member_list.go b/app/cli/cmd/organization_member_list.go index a95c6e38c..714fc9d89 100644 --- a/app/cli/cmd/organization_member_list.go +++ b/app/cli/cmd/organization_member_list.go @@ -20,6 +20,7 @@ import ( "time" "github.com/chainloop-dev/chainloop/app/cli/cmd/options" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" @@ -83,7 +84,7 @@ func newOrganizationMemberList() *cobra.Command { return err } - if err := encodeOutput(res, orgMembershipsTableOutput); err != nil { + if err := output.EncodeOutput(flagOutputFormat, res, orgMembershipsTableOutput); err != nil { return err } @@ -112,7 +113,7 @@ func newOrganizationMemberList() *cobra.Command { } func orgMembershipsTableOutput(res *action.ListMembershipResult) error { - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"ID", "Email", "Role", "Joined At"}) for _, m := range res.Memberships { diff --git a/app/cli/cmd/organization_member_update.go b/app/cli/cmd/organization_member_update.go index d59adf331..f5575e041 100644 --- a/app/cli/cmd/organization_member_update.go +++ b/app/cli/cmd/organization_member_update.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -46,7 +47,7 @@ func newOrganizationMemberUpdateCmd() *cobra.Command { return err } - return encodeOutput(&action.ListMembershipResult{Memberships: []*action.MembershipItem{res}}, orgMembershipsTableOutput) + return output.EncodeOutput(flagOutputFormat, &action.ListMembershipResult{Memberships: []*action.MembershipItem{res}}, orgMembershipsTableOutput) }, } diff --git a/app/cli/cmd/organization_set.go b/app/cli/cmd/organization_set.go index d4f3ed137..976efaed0 100644 --- a/app/cli/cmd/organization_set.go +++ b/app/cli/cmd/organization_set.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -61,7 +62,7 @@ func newOrganizationSet() *cobra.Command { } logger.Info().Msg("Organization switched!") - return encodeOutput([]*action.MembershipItem{membership}, orgMembershipTableOutput) + return output.EncodeOutput(flagOutputFormat, []*action.MembershipItem{membership}, orgMembershipTableOutput) }, } diff --git a/app/cli/cmd/output.go b/app/cli/cmd/output/output.go similarity index 79% rename from app/cli/cmd/output.go rename to app/cli/cmd/output/output.go index a7f4d1434..826ae77da 100644 --- a/app/cli/cmd/output.go +++ b/app/cli/cmd/output/output.go @@ -1,5 +1,5 @@ // -// Copyright 2023-2025 The Chainloop Authors. +// Copyright 2025 The Chainloop Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cmd +package output import ( "encoding/json" @@ -28,8 +28,10 @@ import ( "google.golang.org/protobuf/proto" ) -const formatJSON = "json" -const formatTable = "table" +const FormatJSON = "json" +const FormatTable = "table" + +var ErrOutputFormatNotImplemented = errors.New("format not implemented") // Supported list of tabulated data that can be rendered as a table type tabulatedData interface { @@ -58,25 +60,23 @@ type tabulatedData interface { *action.PolicyLintResult } -var ErrOutputFormatNotImplemented = errors.New("format not implemented") - // returns either json or table representation of the result -func encodeOutput[messageType tabulatedData, f func(messageType) error](v messageType, tableWriter f) error { +func EncodeOutput[messageType tabulatedData, f func(messageType) error](flagOutputFormat string, v messageType, tableWriter f) error { switch flagOutputFormat { - case formatJSON: - return encodeJSON(v) - case formatTable: + case FormatJSON: + return EncodeJSON(v) + case FormatTable: return tableWriter(v) default: return ErrOutputFormatNotImplemented } } -func encodeJSON(v interface{}) error { - return encodeJSONToWriter(v, os.Stdout) +func EncodeJSON(v interface{}) error { + return EncodeJSONToWriter(v, os.Stdout) } -func encodeProtoJSON(v proto.Message) error { +func EncodeProtoJSON(v proto.Message) error { options := protojson.MarshalOptions{ Multiline: true, Indent: " ", @@ -92,7 +92,7 @@ func encodeProtoJSON(v proto.Message) error { return nil } -func encodeJSONToWriter(v interface{}, w io.Writer) error { +func EncodeJSONToWriter(v interface{}, w io.Writer) error { encoder := json.NewEncoder(w) encoder.SetIndent("", " ") if err := encoder.Encode(v); err != nil { @@ -102,11 +102,11 @@ func encodeJSONToWriter(v interface{}, w io.Writer) error { return nil } -func newTableWriter() table.Writer { - return newTableWriterWithWriter(os.Stdout) +func NewTableWriter() table.Writer { + return NewTableWriterWithWriter(os.Stdout) } -func newTableWriterWithWriter(w io.Writer) table.Writer { +func NewTableWriterWithWriter(w io.Writer) table.Writer { tw := table.NewWriter() tw.SetStyle(table.StyleLight) tw.SetOutputMirror(w) diff --git a/app/cli/cmd/plugins.go b/app/cli/cmd/plugins.go index e57520507..cc3fa73c0 100644 --- a/app/cli/cmd/plugins.go +++ b/app/cli/cmd/plugins.go @@ -22,6 +22,7 @@ import ( "strconv" "strings" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/app/cli/pkg/plugins" "github.com/jedib0t/go-pretty/v6/table" @@ -174,7 +175,7 @@ func newPluginListCmd() *cobra.Command { return err } - if flagOutputFormat == formatJSON { + if flagOutputFormat == output.FormatJSON { type pluginInfo struct { Name string `json:"name"` Version string `json:"version"` @@ -192,7 +193,7 @@ func newPluginListCmd() *cobra.Command { }) } - return encodeJSON(items) + return output.EncodeJSON(items) } pluginListTableOutput(result.Plugins) @@ -219,7 +220,7 @@ func newPluginDescribeCmd() *cobra.Command { return err } - if flagOutputFormat == formatJSON { + if flagOutputFormat == output.FormatJSON { type pluginDetail struct { Name string `json:"name"` Version string `json:"version"` @@ -236,7 +237,7 @@ func newPluginDescribeCmd() *cobra.Command { Commands: result.Plugin.Metadata.Commands, } - return encodeJSON(detail) + return output.EncodeJSON(detail) } pluginInfoTableOutput(result.Plugin) @@ -363,7 +364,7 @@ func pluginListTableOutput(plugins map[string]*plugins.LoadedPlugin) { return } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"Name", "Version", "Description", "Commands"}) for name, plugin := range plugins { @@ -380,7 +381,7 @@ func pluginListTableOutput(plugins map[string]*plugins.LoadedPlugin) { } func pluginInfoTableOutput(plugin *plugins.LoadedPlugin) { - t := newTableWriter() + t := output.NewTableWriter() t.SetTitle(fmt.Sprintf("Plugin: %s", plugin.Metadata.Name)) t.AppendSeparator() t.AppendRow(table.Row{"Version", plugin.Metadata.Version}) @@ -411,7 +412,7 @@ func pluginInfoFlagsTableOutput(plugin *plugins.LoadedPlugin) { } for _, cmd := range plugin.Metadata.Commands { - t := newTableWriter() + t := output.NewTableWriter() t.SetTitle(fmt.Sprintf("Command: %s", cmd.Name)) t.AppendSeparator() diff --git a/app/cli/cmd/policy_develop_eval.go b/app/cli/cmd/policy_develop_eval.go index 4aae0d702..e47df5fe8 100644 --- a/app/cli/cmd/policy_develop_eval.go +++ b/app/cli/cmd/policy_develop_eval.go @@ -19,6 +19,7 @@ import ( "fmt" "strings" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" schemaapi "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1" "github.com/spf13/cobra" @@ -65,7 +66,7 @@ evaluates the policy against the provided material or attestation.`, return err } - return encodeJSON(result) + return output.EncodeJSON(result) }, } diff --git a/app/cli/cmd/policy_develop_lint.go b/app/cli/cmd/policy_develop_lint.go index 28d1f1500..15398c86c 100644 --- a/app/cli/cmd/policy_develop_lint.go +++ b/app/cli/cmd/policy_develop_lint.go @@ -19,6 +19,7 @@ import ( "fmt" "os" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -57,7 +58,7 @@ func newPolicyDevelopLintCmd() *cobra.Command { return nil } - if err := encodeOutput(result, policyLintTable); err != nil { + if err := output.EncodeOutput(flagOutputFormat, result, policyLintTable); err != nil { return fmt.Errorf("failed to encode output: %w", err) } return fmt.Errorf("%d issues found", len(result.Errors)) diff --git a/app/cli/cmd/referrer_discover.go b/app/cli/cmd/referrer_discover.go index 9607f7b3d..c1e66af15 100644 --- a/app/cli/cmd/referrer_discover.go +++ b/app/cli/cmd/referrer_discover.go @@ -18,6 +18,7 @@ package cmd import ( "context" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -44,7 +45,7 @@ func newReferrerDiscoverCmd() *cobra.Command { } // NOTE: this is a preview/beta command, for now we only return JSON format - return encodeJSON(res) + return output.EncodeJSON(res) }, } diff --git a/app/cli/cmd/registered_integration_add.go b/app/cli/cmd/registered_integration_add.go index 0e531c348..484f50e0b 100644 --- a/app/cli/cmd/registered_integration_add.go +++ b/app/cli/cmd/registered_integration_add.go @@ -21,6 +21,7 @@ import ( "strconv" "strings" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/app/controlplane/plugins/sdk/v1" "github.com/santhosh-tekuri/jsonschema/v5" @@ -62,7 +63,7 @@ func newRegisteredIntegrationAddCmd() *cobra.Command { return err } - return encodeOutput(res, registeredIntegrationItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, registeredIntegrationItemTableOutput) }, } diff --git a/app/cli/cmd/registered_integration_list.go b/app/cli/cmd/registered_integration_list.go index 9a6279acf..987e79daa 100644 --- a/app/cli/cmd/registered_integration_list.go +++ b/app/cli/cmd/registered_integration_list.go @@ -20,6 +20,7 @@ import ( "strings" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -36,7 +37,7 @@ func newRegisteredIntegrationListCmd() *cobra.Command { return err } - return encodeOutput(res, registeredIntegrationListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, registeredIntegrationListTableOutput) }, } @@ -56,7 +57,7 @@ func registeredIntegrationListTableOutput(items []*action.RegisteredIntegrationI fmt.Println("Integrations registered and configured in your organization") } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"Name", "Description", "Kind", "Config", "Created At"}) for _, i := range items { var options []string diff --git a/app/cli/cmd/root.go b/app/cli/cmd/root.go index 0694fcb8d..5013e9e39 100644 --- a/app/cli/cmd/root.go +++ b/app/cli/cmd/root.go @@ -87,7 +87,17 @@ func Execute(rootCmd *cobra.Command) error { return nil } -func NewRootCmd(l zerolog.Logger) *cobra.Command { +type RootCmd struct { + *cobra.Command + // ActionOpts is a pointer-to-pointer to the global actionOpts variable. + // This allows the RootCmd to reference the global state that gets initialized + // in PersistentPreRunE and used across all subcommands. The double indirection + // ensures that when the global actionOpts is updated (e.g., with new connection), + // all references automatically point to the updated value. + ActionOpts **action.ActionsOpts +} + +func NewRootCmd(l zerolog.Logger) *RootCmd { rootCmd := &cobra.Command{ Use: appName, Short: "Chainloop Command Line Interface", @@ -154,6 +164,7 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command { if err != nil { return err } + actionOpts = newActionOpts(logger, conn, authToken) if !isTelemetryDisabled() { @@ -258,7 +269,7 @@ func NewRootCmd(l zerolog.Logger) *cobra.Command { } } - return rootCmd + return &RootCmd{Command: rootCmd, ActionOpts: &actionOpts} } // this could have been done using automatic + prefix but we want to have control and know the values diff --git a/app/cli/cmd/version.go b/app/cli/cmd/version.go index c3ff8d1d4..596ecf698 100644 --- a/app/cli/cmd/version.go +++ b/app/cli/cmd/version.go @@ -23,6 +23,7 @@ import ( "io" "os" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1" "github.com/spf13/cobra" ) @@ -56,8 +57,8 @@ func NewVersionCmd() *cobra.Command { } } - if flagOutputFormat == formatJSON { - return encodeJSON(version) + if flagOutputFormat == output.FormatJSON { + return output.EncodeJSON(version) } fmt.Printf("Client Version: %s\n", version.Client) diff --git a/app/cli/cmd/workflow_contract_create.go b/app/cli/cmd/workflow_contract_create.go index 68f5f361b..492c97332 100644 --- a/app/cli/cmd/workflow_contract_create.go +++ b/app/cli/cmd/workflow_contract_create.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -37,7 +38,7 @@ func newWorkflowContractCreateCmd() *cobra.Command { } logger.Info().Msg("Contract created!") - return encodeOutput(res, contractItemTableOutput) + return output.EncodeOutput(flagOutputFormat, res, contractItemTableOutput) }, } diff --git a/app/cli/cmd/workflow_contract_describe.go b/app/cli/cmd/workflow_contract_describe.go index 16251af4f..d7ad72d66 100644 --- a/app/cli/cmd/workflow_contract_describe.go +++ b/app/cli/cmd/workflow_contract_describe.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -64,8 +65,8 @@ func encodeContractOutput(run *action.WorkflowContractWithVersionItem) error { logger.Info().Msg("To download the contract, run the command with the \"--output schema\" option") } - err := encodeOutput(run, contractDescribeTableOutput) - if err == nil || !errors.Is(err, ErrOutputFormatNotImplemented) { + err := output.EncodeOutput(flagOutputFormat, run, contractDescribeTableOutput) + if err == nil || !errors.Is(err, output.ErrOutputFormatNotImplemented) { return err } @@ -74,7 +75,7 @@ func encodeContractOutput(run *action.WorkflowContractWithVersionItem) error { fmt.Fprintln(os.Stdout, run.Revision.RawBody.Body) return nil default: - return ErrOutputFormatNotImplemented + return output.ErrOutputFormatNotImplemented } } @@ -82,7 +83,7 @@ func contractDescribeTableOutput(contractWithVersion *action.WorkflowContractWit revision := contractWithVersion.Revision c := contractWithVersion.Contract - t := newTableWriter() + t := output.NewTableWriter() t.SetTitle("Contract") t.AppendRow(table.Row{"Name", c.Name}) t.AppendSeparator() @@ -97,7 +98,7 @@ func contractDescribeTableOutput(contractWithVersion *action.WorkflowContractWit t.AppendRow(table.Row{"Revision Created At", revision.CreatedAt.Format(time.RFC822)}) t.Render() - vt := newTableWriter() + vt := output.NewTableWriter() vt.AppendRow(table.Row{revision.RawBody.Body}) vt.Render() diff --git a/app/cli/cmd/workflow_contract_list.go b/app/cli/cmd/workflow_contract_list.go index becf759dd..d838ecdbb 100644 --- a/app/cli/cmd/workflow_contract_list.go +++ b/app/cli/cmd/workflow_contract_list.go @@ -18,6 +18,7 @@ package cmd import ( "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -34,7 +35,7 @@ func newWorkflowContractListCmd() *cobra.Command { return err } - return encodeOutput(res, contractListTableOutput) + return output.EncodeOutput(flagOutputFormat, res, contractListTableOutput) }, } @@ -46,7 +47,7 @@ func contractItemTableOutput(contract *action.WorkflowContractItem) error { } func contractListTableOutput(contracts []*action.WorkflowContractItem) error { - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(table.Row{"Name", "Latest Revision", "Created At", "Updated At", "# Workflows", "Scope"}) for _, p := range contracts { diff --git a/app/cli/cmd/workflow_contract_update.go b/app/cli/cmd/workflow_contract_update.go index 94d086b1a..4414edd79 100644 --- a/app/cli/cmd/workflow_contract_update.go +++ b/app/cli/cmd/workflow_contract_update.go @@ -18,6 +18,7 @@ package cmd import ( "errors" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -47,7 +48,7 @@ func newWorkflowContractUpdateCmd() *cobra.Command { } logger.Info().Msg("Contract updated!") - return encodeOutput(res, contractDescribeTableOutput) + return output.EncodeOutput(flagOutputFormat, res, contractDescribeTableOutput) }, } diff --git a/app/cli/cmd/workflow_create.go b/app/cli/cmd/workflow_create.go index 56aa128de..c0700a11f 100644 --- a/app/cli/cmd/workflow_create.go +++ b/app/cli/cmd/workflow_create.go @@ -18,6 +18,7 @@ package cmd import ( "fmt" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" "google.golang.org/grpc/codes" @@ -74,7 +75,7 @@ func newWorkflowCreateCmd() *cobra.Command { } // Print the workflow table - if err := encodeOutput(wf, workflowItemTableOutput); err != nil { + if err := output.EncodeOutput(flagOutputFormat, wf, workflowItemTableOutput); err != nil { return fmt.Errorf("failed to print workflow: %w", err) } diff --git a/app/cli/cmd/workflow_describe.go b/app/cli/cmd/workflow_describe.go index 010bf6f51..bd527ef85 100644 --- a/app/cli/cmd/workflow_describe.go +++ b/app/cli/cmd/workflow_describe.go @@ -16,6 +16,7 @@ package cmd import ( + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -32,7 +33,7 @@ func newWorkflowDescribeCmd() *cobra.Command { return err } - return encodeOutput(wf, workflowItemTableOutput) + return output.EncodeOutput(flagOutputFormat, wf, workflowItemTableOutput) }, } diff --git a/app/cli/cmd/workflow_list.go b/app/cli/cmd/workflow_list.go index e58163c84..049585b6c 100644 --- a/app/cli/cmd/workflow_list.go +++ b/app/cli/cmd/workflow_list.go @@ -20,6 +20,7 @@ import ( "time" "github.com/chainloop-dev/chainloop/app/cli/cmd/options" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -60,7 +61,7 @@ func newWorkflowListCmd() *cobra.Command { return err } - if err := encodeOutput(res, WorkflowListTableOutput); err != nil { + if err := output.EncodeOutput(flagOutputFormat, res, WorkflowListTableOutput); err != nil { return err } @@ -99,7 +100,7 @@ func WorkflowListTableOutput(workflowListResult *action.WorkflowListResult) erro headerRow := table.Row{"Name", "Project", "Contract", "Public", "Runner", "Last Run status", "Created At"} headerRowFull := table.Row{"Name", "Description", "Project", "Team", "Contract", "Public", "Runner", "Last Run status", "Created At"} - t := newTableWriter() + t := output.NewTableWriter() if full { t.AppendHeader(headerRowFull) } else { diff --git a/app/cli/cmd/workflow_update.go b/app/cli/cmd/workflow_update.go index c49ff4119..96f4e5a60 100644 --- a/app/cli/cmd/workflow_update.go +++ b/app/cli/cmd/workflow_update.go @@ -18,6 +18,7 @@ package cmd import ( "context" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/spf13/cobra" ) @@ -52,7 +53,7 @@ func newWorkflowUpdateCmd() *cobra.Command { } logger.Info().Msg("Workflow updated!") - return encodeOutput(&action.WorkflowListResult{Workflows: []*action.WorkflowItem{res}}, WorkflowListTableOutput) + return output.EncodeOutput(flagOutputFormat, &action.WorkflowListResult{Workflows: []*action.WorkflowItem{res}}, WorkflowListTableOutput) }, } diff --git a/app/cli/cmd/workflow_workflow_run_describe.go b/app/cli/cmd/workflow_workflow_run_describe.go index 6b807a9c2..f2f4568b4 100644 --- a/app/cli/cmd/workflow_workflow_run_describe.go +++ b/app/cli/cmd/workflow_workflow_run_describe.go @@ -24,6 +24,7 @@ import ( "strings" "time" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/chainloop-dev/chainloop/pkg/attestation/renderer/chainloop" "github.com/jedib0t/go-pretty/v6/table" @@ -107,7 +108,7 @@ func workflowRunDescribeTableOutput(run *action.WorkflowRunItemFull) error { wf := run.Workflow wr := run.WorkflowRun - gt := newTableWriter() + gt := output.NewTableWriter() gt.SetTitle("Workflow") gt.AppendRow(table.Row{"ID", wf.ID}) gt.AppendRow(table.Row{"Name", wf.Name}) @@ -181,7 +182,7 @@ func predicateV1Table(att *action.WorkflowRunAttestationItem) { // Materials materials := att.Materials if len(materials) > 0 { - mt := newTableWriter() + mt := output.NewTableWriter() mt.SetTitle("Materials") for _, m := range materials { @@ -225,7 +226,7 @@ func predicateV1Table(att *action.WorkflowRunAttestationItem) { envVars := att.EnvVars if len(envVars) > 0 { - mt := newTableWriter() + mt := output.NewTableWriter() mt.SetTitle("Environment Variables") header := table.Row{"Name", "Value"} @@ -272,14 +273,14 @@ func policiesTable(evs []*action.PolicyEvaluation, mt table.Writer) { func encodeAttestationOutput(run *action.WorkflowRunItemFull, writer io.Writer) error { // Try to encode as a table or json - err := encodeOutput(run, workflowRunDescribeTableOutput) + err := output.EncodeOutput(flagOutputFormat, run, workflowRunDescribeTableOutput) // It was correctly encoded, we are done if err == nil { return nil } // It could not be encoded but for a reason that's not because it was a custom format - if !errors.Is(err, ErrOutputFormatNotImplemented) { + if !errors.Is(err, output.ErrOutputFormatNotImplemented) { return err } @@ -291,7 +292,7 @@ func encodeAttestationOutput(run *action.WorkflowRunItemFull, writer io.Writer) switch flagOutputFormat { case formatStatement: - return encodeJSON(run.Attestation.Statement()) + return output.EncodeJSON(run.Attestation.Statement()) case formatAttestation: if run.Attestation.Bundle != nil { var bundle protobundle.Bundle @@ -299,14 +300,14 @@ func encodeAttestationOutput(run *action.WorkflowRunItemFull, writer io.Writer) if err != nil { return fmt.Errorf("unmarshaling attestation: %w", err) } - return encodeProtoJSON(&bundle) + return output.EncodeProtoJSON(&bundle) } else { - return encodeJSON(run.Attestation.Envelope) + return output.EncodeJSON(run.Attestation.Envelope) } case formatPayloadPAE: return encodePAE(run, writer) default: - return ErrOutputFormatNotImplemented + return output.ErrOutputFormatNotImplemented } } diff --git a/app/cli/cmd/workflow_workflow_run_list.go b/app/cli/cmd/workflow_workflow_run_list.go index 0d7c67dca..467ac4ed7 100644 --- a/app/cli/cmd/workflow_workflow_run_list.go +++ b/app/cli/cmd/workflow_workflow_run_list.go @@ -22,6 +22,7 @@ import ( "time" "github.com/chainloop-dev/chainloop/app/cli/cmd/options" + "github.com/chainloop-dev/chainloop/app/cli/cmd/output" "github.com/chainloop-dev/chainloop/app/cli/internal/action" "github.com/jedib0t/go-pretty/v6/table" "github.com/spf13/cobra" @@ -61,7 +62,7 @@ func newWorkflowWorkflowRunListCmd() *cobra.Command { return err } - if err := encodeOutput(res.Result, workflowRunListTableOutput); err != nil { + if err := output.EncodeOutput(flagOutputFormat, res.Result, workflowRunListTableOutput); err != nil { return err } @@ -101,7 +102,7 @@ func workflowRunListTableOutput(runs []*action.WorkflowRunItem) error { header = append(header, "Finished At", "Failure reason") } - t := newTableWriter() + t := output.NewTableWriter() t.AppendHeader(header) for _, p := range runs { diff --git a/app/cli/internal/action/attestation_push.go b/app/cli/internal/action/attestation_push.go index 2cc3ce75f..fcd337720 100644 --- a/app/cli/internal/action/attestation_push.go +++ b/app/cli/internal/action/attestation_push.go @@ -221,7 +221,7 @@ func (action *AttestationPush) Run(ctx context.Context, attestationID string, ru workflow := crafter.CraftingState.Attestation.GetWorkflow() - attestationResult.Digest, err = pushToControlPlane(ctx, action.ActionsOpts.CPConnection, envelope, bundle, workflow.GetWorkflowRunId(), workflow.GetVersion().GetMarkAsReleased()) + attestationResult.Digest, err = pushToControlPlane(ctx, action.CPConnection, envelope, bundle, workflow.GetWorkflowRunId(), workflow.GetVersion().GetMarkAsReleased()) if err != nil { return nil, fmt.Errorf("pushing to control plane: %w", err) } diff --git a/app/cli/main.go b/app/cli/main.go index bbaf98712..19a5eed13 100644 --- a/app/cli/main.go +++ b/app/cli/main.go @@ -35,8 +35,7 @@ func main() { // Couldn't find an easier way to disable the timestamp logger := zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr, FormatTimestamp: func(interface{}) string { return "" }}) rootCmd := cmd.NewRootCmd(logger) - // Run the command - if err := cmd.Execute(rootCmd); err != nil { + if err := cmd.Execute(rootCmd.Command); err != nil { msg, exitCode := errorInfo(err, logger) logger.Error().Msg(msg) os.Exit(exitCode)