diff --git a/docs/stackit_argus_scrape-config_generate-payload.md b/docs/stackit_argus_scrape-config_generate-payload.md index 9f246dfbd..a6d725a27 100644 --- a/docs/stackit_argus_scrape-config_generate-payload.md +++ b/docs/stackit_argus_scrape-config_generate-payload.md @@ -20,19 +20,23 @@ stackit argus scrape-config generate-payload [flags] ``` Generate a Create payload with default values, and adapt it with custom values for the different configuration options - $ stackit argus scrape-config generate-payload > ./payload.json + $ stackit argus scrape-config generate-payload --file-path ./payload.json $ stackit argus scrape-config create my-config --payload @./payload.json Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and adapt it with custom values for the different configuration options - $ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx > ./payload.json + $ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx --file-path ./payload.json $ stackit argus scrape-config update my-config --payload @./payload.json + + Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and preview it in the terminal + $ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx ``` ### Options ``` + -f, --file-path string If set, writes the payload to the given file. If unset, writes the payload to the standard output -h, --help Help for "stackit argus scrape-config generate-payload" --instance-id string Instance ID -n, --job-name string If set, generates an update payload with the current state of the given scrape config. If unset, generates a create payload with default values diff --git a/docs/stackit_load-balancer_generate-payload.md b/docs/stackit_load-balancer_generate-payload.md index b0533dfb2..07636cb2e 100644 --- a/docs/stackit_load-balancer_generate-payload.md +++ b/docs/stackit_load-balancer_generate-payload.md @@ -15,21 +15,25 @@ stackit load-balancer generate-payload [flags] ``` Generate a payload, and adapt it with custom values for the different configuration options - $ stackit load-balancer generate-payload > ./payload.json + $ stackit load-balancer generate-payload --file-path ./payload.json $ stackit load-balancer create --payload @./payload.json Generate a payload with values of an existing load balancer, and adapt it with custom values for the different configuration options - $ stackit load-balancer generate-payload --lb-name xxx > ./payload.json + $ stackit load-balancer generate-payload --lb-name xxx --file-path ./payload.json $ stackit load-balancer update xxx --payload @./payload.json + + Generate a payload with values of an existing load balancer, and preview it in the terminal + $ stackit load-balancer generate-payload --lb-name xxx ``` ### Options ``` - -h, --help Help for "stackit load-balancer generate-payload" - -n, --lb-name string If set, generates the payload with the current values of the given load balancer. If unset, generates the payload with empty values + -f, --file-path string If set, writes the payload to the given file. If unset, writes the payload to the standard output + -h, --help Help for "stackit load-balancer generate-payload" + -n, --lb-name string If set, generates the payload with the current values of the given load balancer. If unset, generates the payload with empty values ``` ### Options inherited from parent commands diff --git a/docs/stackit_ske_cluster_generate-payload.md b/docs/stackit_ske_cluster_generate-payload.md index dc07bfa22..9a40bb105 100644 --- a/docs/stackit_ske_cluster_generate-payload.md +++ b/docs/stackit_ske_cluster_generate-payload.md @@ -15,20 +15,24 @@ stackit ske cluster generate-payload [flags] ``` Generate a payload with default values, and adapt it with custom values for the different configuration options - $ stackit ske cluster generate-payload > ./payload.json + $ stackit ske cluster generate-payload --file-path ./payload.json $ stackit ske cluster create my-cluster --payload @./payload.json Generate a payload with values of a cluster, and adapt it with custom values for the different configuration options - $ stackit ske cluster generate-payload --cluster-name my-cluster > ./payload.json + $ stackit ske cluster generate-payload --cluster-name my-cluster --file-path ./payload.json $ stackit ske cluster update my-cluster --payload @./payload.json + + Generate a payload with values of a cluster, and preview it in the terminal + $ stackit ske cluster generate-payload --cluster-name my-cluster ``` ### Options ``` -n, --cluster-name string If set, generates the payload with the current state of the given cluster. If unset, generates the payload with default values + -f, --file-path string If set, writes the payload to the given file. If unset, writes the payload to the standard output -h, --help Help for "stackit ske cluster generate-payload" ``` diff --git a/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go b/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go index 310ac67f3..9d5e720f2 100644 --- a/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go +++ b/internal/cmd/argus/scrape-config/generate-payload/generate_payload.go @@ -7,6 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/fileutils" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -20,12 +21,14 @@ import ( const ( jobNameFlag = "job-name" instanceIdFlag = "instance-id" + filePathFlag = "file-path" ) type inputModel struct { *globalflags.GlobalFlagModel JobName *string InstanceId string + FilePath *string } func NewCmd(p *print.Printer) *cobra.Command { @@ -44,14 +47,17 @@ func NewCmd(p *print.Printer) *cobra.Command { Example: examples.Build( examples.NewExample( `Generate a Create payload with default values, and adapt it with custom values for the different configuration options`, - `$ stackit argus scrape-config generate-payload > ./payload.json`, + `$ stackit argus scrape-config generate-payload --file-path ./payload.json`, ``, `$ stackit argus scrape-config create my-config --payload @./payload.json`), examples.NewExample( `Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and adapt it with custom values for the different configuration options`, - `$ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx > ./payload.json`, + `$ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx --file-path ./payload.json`, ``, `$ stackit argus scrape-config update my-config --payload @./payload.json`), + examples.NewExample( + `Generate an Update payload with the values of an existing configuration named "my-config" for Argus instance xxx, and preview it in the terminal`, + `$ stackit argus scrape-config generate-payload --job-name my-config --instance-id xxx`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -68,7 +74,7 @@ func NewCmd(p *print.Printer) *cobra.Command { if model.JobName == nil { createPayload := argusUtils.DefaultCreateScrapeConfigPayload - return outputCreateResult(p, &createPayload) + return outputCreateResult(p, model.FilePath, &createPayload) } req := buildRequest(ctx, model, apiClient) @@ -82,7 +88,7 @@ func NewCmd(p *print.Printer) *cobra.Command { return fmt.Errorf("map update scrape config payloads: %w", err) } - return outputUpdateResult(p, payload) + return outputUpdateResult(p, model.FilePath, payload) }, } configureFlags(cmd) @@ -92,6 +98,7 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().Var(flags.UUIDFlag(), instanceIdFlag, "Instance ID") cmd.Flags().StringP(jobNameFlag, "n", "", "If set, generates an update payload with the current state of the given scrape config. If unset, generates a create payload with default values") + cmd.Flags().StringP(filePathFlag, "f", "", "If set, writes the payload to the given file. If unset, writes the payload to the standard output") } func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { @@ -108,6 +115,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { GlobalFlagModel: globalFlags, JobName: jobName, InstanceId: flags.FlagToStringValue(p, cmd, instanceIdFlag), + FilePath: flags.FlagToStringPointer(p, cmd, filePathFlag), }, nil } @@ -116,22 +124,38 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *argus.APICl return req } -func outputCreateResult(p *print.Printer, payload *argus.CreateScrapeConfigPayload) error { +func outputCreateResult(p *print.Printer, filePath *string, payload *argus.CreateScrapeConfigPayload) error { payloadBytes, err := json.MarshalIndent(*payload, "", " ") if err != nil { return fmt.Errorf("marshal payload: %w", err) } - p.Outputln(string(payloadBytes)) + + if filePath != nil { + err = fileutils.WriteToFile(*filePath, string(payloadBytes)) + if err != nil { + return fmt.Errorf("write payload to the file: %w", err) + } + } else { + p.Outputln(string(payloadBytes)) + } return nil } -func outputUpdateResult(p *print.Printer, payload *argus.UpdateScrapeConfigPayload) error { +func outputUpdateResult(p *print.Printer, filePath *string, payload *argus.UpdateScrapeConfigPayload) error { payloadBytes, err := json.MarshalIndent(*payload, "", " ") if err != nil { return fmt.Errorf("marshal payload: %w", err) } - p.Outputln(string(payloadBytes)) + + if filePath != nil { + err = fileutils.WriteToFile(*filePath, string(payloadBytes)) + if err != nil { + return fmt.Errorf("write payload to the file: %w", err) + } + } else { + p.Outputln(string(payloadBytes)) + } return nil } diff --git a/internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go b/internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go index 3c1fafd38..5c04abd5c 100644 --- a/internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go +++ b/internal/cmd/argus/scrape-config/generate-payload/generate_payload_test.go @@ -22,13 +22,17 @@ var testClient = &argus.APIClient{} var testProjectId = uuid.NewString() var testInstanceId = uuid.NewString() -const testJobName = "test-job-name" +const ( + testJobName = "test-job-name" + testFilePath = "example-file" +) func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ projectIdFlag: testProjectId, instanceIdFlag: testInstanceId, jobNameFlag: testJobName, + filePathFlag: testFilePath, } for _, mod := range mods { mod(flagValues) @@ -44,6 +48,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { }, InstanceId: testInstanceId, JobName: utils.Ptr(testJobName), + FilePath: utils.Ptr(testFilePath), } for _, mod := range mods { mod(model) @@ -80,6 +85,16 @@ func TestParseInput(t *testing.T) { GlobalFlagModel: &globalflags.GlobalFlagModel{Verbosity: globalflags.VerbosityDefault}, }, }, + { + description: "file path missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, filePathFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.FilePath = nil + }), + }, { description: "job name missing", flagValues: fixtureFlagValues(func(flagValues map[string]string) { diff --git a/internal/cmd/load-balancer/generate-payload/generate_payload.go b/internal/cmd/load-balancer/generate-payload/generate_payload.go index 6275ba819..4d560fc42 100644 --- a/internal/cmd/load-balancer/generate-payload/generate_payload.go +++ b/internal/cmd/load-balancer/generate-payload/generate_payload.go @@ -8,6 +8,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/fileutils" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -20,11 +21,13 @@ import ( const ( loadBalancerNameFlag = "lb-name" + filePathFlag = "file-path" ) type inputModel struct { *globalflags.GlobalFlagModel LoadBalancerName *string + FilePath *string } var ( @@ -118,14 +121,17 @@ func NewCmd(p *print.Printer) *cobra.Command { Example: examples.Build( examples.NewExample( `Generate a payload, and adapt it with custom values for the different configuration options`, - `$ stackit load-balancer generate-payload > ./payload.json`, + `$ stackit load-balancer generate-payload --file-path ./payload.json`, ``, `$ stackit load-balancer create --payload @./payload.json`), examples.NewExample( `Generate a payload with values of an existing load balancer, and adapt it with custom values for the different configuration options`, - `$ stackit load-balancer generate-payload --lb-name xxx > ./payload.json`, + `$ stackit load-balancer generate-payload --lb-name xxx --file-path ./payload.json`, ``, `$ stackit load-balancer update xxx --payload @./payload.json`), + examples.NewExample( + `Generate a payload with values of an existing load balancer, and preview it in the terminal`, + `$ stackit load-balancer generate-payload --lb-name xxx`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -142,7 +148,7 @@ func NewCmd(p *print.Printer) *cobra.Command { if model.LoadBalancerName == nil { createPayload := DefaultCreateLoadBalancerPayload - return outputCreateResult(p, &createPayload) + return outputCreateResult(p, model.FilePath, &createPayload) } req := buildRequest(ctx, model, apiClient) @@ -162,7 +168,7 @@ func NewCmd(p *print.Printer) *cobra.Command { TargetPools: resp.TargetPools, Version: resp.Version, } - return outputUpdateResult(p, updatePayload) + return outputUpdateResult(p, model.FilePath, updatePayload) }, } configureFlags(cmd) @@ -171,6 +177,7 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(loadBalancerNameFlag, "n", "", "If set, generates the payload with the current values of the given load balancer. If unset, generates the payload with empty values") + cmd.Flags().StringP(filePathFlag, "f", "", "If set, writes the payload to the given file. If unset, writes the payload to the standard output") } func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { @@ -185,6 +192,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, LoadBalancerName: loadBalancerName, + FilePath: flags.FlagToStringPointer(p, cmd, filePathFlag), } if p.IsVerbosityDebug() { @@ -204,22 +212,38 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *loadbalance return req } -func outputCreateResult(p *print.Printer, payload *loadbalancer.CreateLoadBalancerPayload) error { +func outputCreateResult(p *print.Printer, filePath *string, payload *loadbalancer.CreateLoadBalancerPayload) error { payloadBytes, err := json.MarshalIndent(*payload, "", " ") if err != nil { return fmt.Errorf("marshal create load balancer payload: %w", err) } - p.Outputln(string(payloadBytes)) + + if filePath != nil { + err = fileutils.WriteToFile(*filePath, string(payloadBytes)) + if err != nil { + return fmt.Errorf("write create load balancer payload to the file: %w", err) + } + } else { + p.Outputln(string(payloadBytes)) + } return nil } -func outputUpdateResult(p *print.Printer, payload *loadbalancer.UpdateLoadBalancerPayload) error { +func outputUpdateResult(p *print.Printer, filePath *string, payload *loadbalancer.UpdateLoadBalancerPayload) error { payloadBytes, err := json.MarshalIndent(*payload, "", " ") if err != nil { return fmt.Errorf("marshal update load balancer payload: %w", err) } - p.Outputln(string(payloadBytes)) + + if filePath != nil { + err = fileutils.WriteToFile(*filePath, string(payloadBytes)) + if err != nil { + return fmt.Errorf("write update load balancer payload to the file: %w", err) + } + } else { + p.Outputln(string(payloadBytes)) + } return nil } diff --git a/internal/cmd/load-balancer/generate-payload/generate_payload_test.go b/internal/cmd/load-balancer/generate-payload/generate_payload_test.go index a1661d545..b8f48fc69 100644 --- a/internal/cmd/load-balancer/generate-payload/generate_payload_test.go +++ b/internal/cmd/load-balancer/generate-payload/generate_payload_test.go @@ -23,10 +23,16 @@ var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") var testClient = &loadbalancer.APIClient{} var testProjectId = uuid.NewString() +const ( + testLoadBalancerName = "example-name" + testFilePath = "example-file" +) + func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ projectIdFlag: testProjectId, - loadBalancerNameFlag: "example-name", + loadBalancerNameFlag: testLoadBalancerName, + filePathFlag: testFilePath, } for _, mod := range mods { mod(flagValues) @@ -40,7 +46,8 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { ProjectId: testProjectId, Verbosity: globalflags.VerbosityDefault, }, - LoadBalancerName: utils.Ptr("example-name"), + LoadBalancerName: utils.Ptr(testLoadBalancerName), + FilePath: utils.Ptr(testFilePath), } for _, mod := range mods { mod(model) @@ -49,7 +56,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *loadbalancer.ApiGetLoadBalancerRequest)) loadbalancer.ApiGetLoadBalancerRequest { - request := testClient.GetLoadBalancer(testCtx, testProjectId, "example-name") + request := testClient.GetLoadBalancer(testCtx, testProjectId, testLoadBalancerName) for _, mod := range mods { mod(&request) } @@ -87,6 +94,16 @@ func TestParseInput(t *testing.T) { model.LoadBalancerName = nil }), }, + { + description: "file path missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, filePathFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.FilePath = nil + }), + }, { description: "project id missing", flagValues: fixtureFlagValues(func(flagValues map[string]string) { diff --git a/internal/cmd/ske/cluster/generate-payload/generate_payload.go b/internal/cmd/ske/cluster/generate-payload/generate_payload.go index 130495b0a..054fea2b3 100644 --- a/internal/cmd/ske/cluster/generate-payload/generate_payload.go +++ b/internal/cmd/ske/cluster/generate-payload/generate_payload.go @@ -8,6 +8,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/fileutils" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" @@ -20,11 +21,13 @@ import ( const ( clusterNameFlag = "cluster-name" + filePathFlag = "file-path" ) type inputModel struct { *globalflags.GlobalFlagModel ClusterName *string + FilePath *string } func NewCmd(p *print.Printer) *cobra.Command { @@ -39,14 +42,17 @@ func NewCmd(p *print.Printer) *cobra.Command { Example: examples.Build( examples.NewExample( `Generate a payload with default values, and adapt it with custom values for the different configuration options`, - `$ stackit ske cluster generate-payload > ./payload.json`, + `$ stackit ske cluster generate-payload --file-path ./payload.json`, ``, `$ stackit ske cluster create my-cluster --payload @./payload.json`), examples.NewExample( `Generate a payload with values of a cluster, and adapt it with custom values for the different configuration options`, - `$ stackit ske cluster generate-payload --cluster-name my-cluster > ./payload.json`, + `$ stackit ske cluster generate-payload --cluster-name my-cluster --file-path ./payload.json`, ``, `$ stackit ske cluster update my-cluster --payload @./payload.json`), + examples.NewExample( + `Generate a payload with values of a cluster, and preview it in the terminal`, + `$ stackit ske cluster generate-payload --cluster-name my-cluster`), ), RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -83,7 +89,7 @@ func NewCmd(p *print.Printer) *cobra.Command { } } - return outputResult(p, payload) + return outputResult(p, model.FilePath, payload) }, } configureFlags(cmd) @@ -92,6 +98,7 @@ func NewCmd(p *print.Printer) *cobra.Command { func configureFlags(cmd *cobra.Command) { cmd.Flags().StringP(clusterNameFlag, "n", "", "If set, generates the payload with the current state of the given cluster. If unset, generates the payload with default values") + cmd.Flags().StringP(filePathFlag, "f", "", "If set, writes the payload to the given file. If unset, writes the payload to the standard output") } func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { @@ -106,6 +113,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command) (*inputModel, error) { model := inputModel{ GlobalFlagModel: globalFlags, ClusterName: clusterName, + FilePath: flags.FlagToStringPointer(p, cmd, filePathFlag), } if p.IsVerbosityDebug() { @@ -125,12 +133,20 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *ske.APIClie return req } -func outputResult(p *print.Printer, payload *ske.CreateOrUpdateClusterPayload) error { +func outputResult(p *print.Printer, filePath *string, payload *ske.CreateOrUpdateClusterPayload) error { payloadBytes, err := json.MarshalIndent(*payload, "", " ") if err != nil { return fmt.Errorf("marshal payload: %w", err) } - p.Outputln(string(payloadBytes)) + + if filePath != nil { + err = fileutils.WriteToFile(*filePath, string(payloadBytes)) + if err != nil { + return fmt.Errorf("write payload to the file: %w", err) + } + } else { + p.Outputln(string(payloadBytes)) + } return nil } diff --git a/internal/cmd/ske/cluster/generate-payload/generate_payload_test.go b/internal/cmd/ske/cluster/generate-payload/generate_payload_test.go index 502596390..3cf60e949 100644 --- a/internal/cmd/ske/cluster/generate-payload/generate_payload_test.go +++ b/internal/cmd/ske/cluster/generate-payload/generate_payload_test.go @@ -22,10 +22,16 @@ var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") var testClient = &ske.APIClient{} var testProjectId = uuid.NewString() +const ( + testClusterName = "example-name" + testFilePath = "example-file" +) + func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ projectIdFlag: testProjectId, - clusterNameFlag: "example-name", + clusterNameFlag: testClusterName, + filePathFlag: testFilePath, } for _, mod := range mods { mod(flagValues) @@ -39,7 +45,8 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { ProjectId: testProjectId, Verbosity: globalflags.VerbosityDefault, }, - ClusterName: utils.Ptr("example-name"), + ClusterName: utils.Ptr(testClusterName), + FilePath: utils.Ptr(testFilePath), } for _, mod := range mods { mod(model) @@ -48,7 +55,7 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { } func fixtureRequest(mods ...func(request *ske.ApiGetClusterRequest)) ske.ApiGetClusterRequest { - request := testClient.GetCluster(testCtx, testProjectId, "example-name") + request := testClient.GetCluster(testCtx, testProjectId, testClusterName) for _, mod := range mods { mod(&request) } @@ -86,6 +93,16 @@ func TestParseInput(t *testing.T) { model.ClusterName = nil }), }, + { + description: "file path missing", + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, filePathFlag) + }), + isValid: true, + expectedModel: fixtureInputModel(func(model *inputModel) { + model.FilePath = nil + }), + }, { description: "project id missing", flagValues: fixtureFlagValues(func(flagValues map[string]string) { diff --git a/internal/pkg/fileutils/file_utils.go b/internal/pkg/fileutils/file_utils.go new file mode 100644 index 000000000..69a0234c6 --- /dev/null +++ b/internal/pkg/fileutils/file_utils.go @@ -0,0 +1,28 @@ +package fileutils + +import ( + "fmt" + "os" +) + +func WriteToFile(outputFileName, content string) (err error) { + fo, err := os.Create(outputFileName) + if err != nil { + return fmt.Errorf("create output file: %w", err) + } + defer func() { + tempErr := fo.Close() + if tempErr != nil { + if err != nil { + err = fmt.Errorf("%w; close output file: %w", err, tempErr) + } else { + err = fmt.Errorf("close output file: %w", tempErr) + } + } + }() + _, err = fo.WriteString(content) + if err != nil { + return fmt.Errorf("write content to output file: %w", err) + } + return err +} diff --git a/internal/pkg/fileutils/file_utils_test.go b/internal/pkg/fileutils/file_utils_test.go new file mode 100644 index 000000000..746249353 --- /dev/null +++ b/internal/pkg/fileutils/file_utils_test.go @@ -0,0 +1,43 @@ +package fileutils + +import ( + "os" + "testing" +) + +const outputFilePath = "./testPayload.json" + +func TestWriteToFile(t *testing.T) { + tests := []struct { + description string + content string + outputFile string + }{ + { + description: "write into file", + content: "Test message", + outputFile: outputFilePath, + }, + } + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + err := WriteToFile(tt.outputFile, tt.content) + if err != nil { + t.Fatalf("unexpected error: %s", err.Error()) + } + + output, err := os.ReadFile(tt.outputFile) + if err != nil { + t.Fatalf("unexpected error: %s", err.Error()) + } + if string(output) != tt.content { + t.Errorf("unexpected output: got %q, want %q", output, tt.content) + } + }) + } + // Cleanup + err := os.RemoveAll(outputFilePath) + if err != nil { + t.Errorf("failed cleaning test data") + } +}