Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var (
e.Options.Pipeline.Target.DryRun = false
e.Options.Pipeline.Target.CleanGitBranches = applyCleanGitBranches
e.Options.Pipeline.Target.ExistingOnly = applyExistingOnly
e.Options.Pipeline.DisableChangelog = disableChangelog

logrus.Warningln("Deprecated command, please instead use `updatecli pipeline apply`")

Expand All @@ -74,4 +75,6 @@ func init() {
applyCmd.Flags().BoolVar(&applyCleanGitBranches, "clean-git-branches", false, "Remove updatecli working git branches like '--clean-git-branches=true'")
applyCmd.Flags().StringArrayVar(&pipelineIds, "pipeline-ids", []string{}, "Filter pipelines to apply by their pipeline IDs, accepted as comma separated list")
applyCmd.Flags().StringArrayVar(&labels, "labels", []string{}, "Filter pipelines by their labels, accepted as a comma separated list (key:value)")

addDisableChangelogFlag(applyCmd, &disableChangelog)
}
3 changes: 3 additions & 0 deletions cmd/compose_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ var (
e.Options.Pipeline.Target.DryRun = false
e.Options.Pipeline.Target.CleanGitBranches = composeApplyCleanGitBranches
e.Options.Pipeline.Target.ExistingOnly = composeApplyExistingOnly
e.Options.Pipeline.DisableChangelog = disableChangelog

err = run("compose/apply")
if err != nil {
Expand All @@ -77,5 +78,7 @@ func init() {
composeApplyCmd.Flags().StringArrayVar(&composeApplyOnlyPolicyIDs, "only-policy-ids", []string{}, "Filter policies to apply by their policy IDs, accepted as a comma separated list")
composeApplyCmd.Flags().StringArrayVar(&composeApplyIgnoredPolicyIDs, "ignored-policy-ids", []string{}, "Filter policies to ignore by their policy IDs, accepted as a comma separated list")

addDisableChangelogFlag(composeApplyCmd, &disableChangelog)

composeCmd.AddCommand(composeApplyCmd)
}
4 changes: 4 additions & 0 deletions cmd/compose_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var (
e.Options.Pipeline.Target.Push = false
e.Options.Pipeline.Target.Clean = composeCmdClean
e.Options.Pipeline.Target.DryRun = true
e.Options.Pipeline.DisableChangelog = disableChangelog

err = run("compose/diff")
if err != nil {
Expand All @@ -65,5 +66,8 @@ func init() {
composeDiffCmd.Flags().StringArrayVar(&labels, "labels", []string{}, "Filter pipelines to apply by their labels, accepted as a comma separated list (key:value)")
composeDiffCmd.Flags().StringArrayVar(&composeDiffOnlyPolicyIDs, "only-policy-ids", []string{}, "Filter policies to apply by their policy IDs, accepted as a comma separated list")
composeDiffCmd.Flags().StringArrayVar(&composeDiffIgnoredPolicyIDs, "ignored-policy-ids", []string{}, "Filter policies to ignore by their policy IDs, accepted as a comma separated list")

addDisableChangelogFlag(composeDiffCmd, &disableChangelog)

composeCmd.AddCommand(composeDiffCmd)
}
3 changes: 3 additions & 0 deletions cmd/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var (
e.Options.Pipeline.Target.Push = false
e.Options.Pipeline.Target.Clean = diffClean
e.Options.Pipeline.Target.DryRun = true
e.Options.Pipeline.DisableChangelog = disableChangelog

logrus.Warningln("Deprecated command, please instead use `updatecli pipeline diff`")

Expand All @@ -57,4 +58,6 @@ func init() {
diffCmd.Flags().BoolVar(&disableTLS, "disable-tls", false, "Disable TLS verification like '--disable-tls=true'")
diffCmd.Flags().StringArrayVar(&pipelineIds, "pipeline-ids", []string{}, "Filter pipelines to apply by their pipeline IDs, accepted a comma separated list")
diffCmd.Flags().StringArrayVar(&labels, "labels", []string{}, "Filter pipelines to apply by their labels, accepted as a comma separated list (key:value)")

addDisableChangelogFlag(diffCmd, &disableChangelog)
}
33 changes: 33 additions & 0 deletions cmd/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cmd

import (
"os"
"strconv"
"strings"

"github.com/sirupsen/logrus"
)

const DisableChangelogEnvVar = "UPDATECLI_DISABLE_CHANGELOG"

// getEnvBoolOrDefault reads a boolean environment variable.
// It returns defaultValue when the variable is unset or invalid.
func getEnvBoolOrDefault(envVar string, defaultValue bool) bool {
value, ok := os.LookupEnv(envVar)
if !ok {
return defaultValue
}

parsed, err := strconv.ParseBool(strings.TrimSpace(value))
if err != nil {
logrus.Debugf(
"invalid boolean value for environment variable %q: %q, defaulting to %t",
envVar,
value,
defaultValue,
)
return defaultValue
}

return parsed
}
99 changes: 99 additions & 0 deletions cmd/env_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package cmd

import (
"testing"
)

func TestGetEnvBoolOrDefault(t *testing.T) {
tests := []struct {
name string
envVar string
envValue string
setEnv bool
defaultValue bool
expected bool
}{
{
name: "not_set_returns_default_true",
envVar: "UNDEFINED_VAR_1",
defaultValue: true,
expected: true,
},
{
name: "not_set_returns_default_false",
envVar: "UNDEFINED_VAR_2",
defaultValue: false,
expected: false,
},
{
name: "set_to_true",
envVar: "TEST_VAR_TRUE",
envValue: "true",
setEnv: true,
defaultValue: false,
expected: true,
},
{
name: "set_to_false",
envVar: "TEST_VAR_FALSE",
envValue: "false",
setEnv: true,
defaultValue: true,
expected: false,
},
{
name: "set_to_1",
envVar: "TEST_VAR_1",
envValue: "1",
setEnv: true,
defaultValue: false,
expected: true,
},
{
name: "set_to_0",
envVar: "TEST_VAR_0",
envValue: "0",
setEnv: true,
defaultValue: true,
expected: false,
},
{
name: "whitespace_trimmed",
envVar: "TEST_VAR_SPACE",
envValue: " true ",
setEnv: true,
defaultValue: false,
expected: true,
},
{
name: "invalid_returns_default_true",
envVar: "TEST_VAR_INVALID_1",
envValue: "invalid",
setEnv: true,
defaultValue: true,
expected: true,
},
{
name: "invalid_returns_default_false",
envVar: "TEST_VAR_INVALID_2",
envValue: "maybe",
setEnv: true,
defaultValue: false,
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.setEnv {
t.Setenv(tt.envVar, tt.envValue)
}

result := getEnvBoolOrDefault(tt.envVar, tt.defaultValue)

if result != tt.expected {
t.Errorf("got %v, expected %v", result, tt.expected)
}
})
}
}
15 changes: 15 additions & 0 deletions cmd/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cmd

import "github.com/spf13/cobra"

// addDisableChangelogFlag registers the shared --disable-changelog flag on the
// provided command, using the value from UPDATECLI_DISABLE_CHANGELOG as the
// default when the flag is not explicitly passed.
func addDisableChangelogFlag(cmd *cobra.Command, dest *bool) {
cmd.Flags().BoolVar(
dest,
"disable-changelog",
getEnvBoolOrDefault(DisableChangelogEnvVar, false),
"Disable changelog retrieval to avoid unnecessary requests (env: "+DisableChangelogEnvVar+")",
)
}
128 changes: 128 additions & 0 deletions cmd/flags_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package cmd

import (
"strings"
"testing"

"github.com/spf13/cobra"
)

func TestAddDisableChangelogFlagRegistration(t *testing.T) {
t.Setenv(DisableChangelogEnvVar, "false")

cmd := &cobra.Command{
Use: "test",
}

var disableChangelog bool
addDisableChangelogFlag(cmd, &disableChangelog)
Comment thread
omer-cengel marked this conversation as resolved.

// Check that flag exists
flag := cmd.Flags().Lookup("disable-changelog")
if flag == nil {
t.Fatal("flag not registered")
}

// Check flag has help text
if flag.Usage == "" {
t.Error("flag help text is empty")
}

// Check that env var name appears in help text
if !strings.Contains(flag.Usage, DisableChangelogEnvVar) {
t.Errorf(
"flag help text does not mention env var %q: help text is %q",
DisableChangelogEnvVar,
flag.Usage,
)
}

// Check default value is "false" when env var not set
if flag.DefValue != "false" {
t.Errorf(
"flag default value when no env var: got %q, expected %q",
flag.DefValue,
"false",
)
}
}

func TestAddDisableChangelogFlagUsesEnvDefault(t *testing.T) {
tests := []struct {
name string
envValue string
expectedDef string
}{
{
name: "env_var_true",
envValue: "true",
expectedDef: "true",
},
{
name: "env_var_false",
envValue: "false",
expectedDef: "false",
},
{
name: "env_var_1",
envValue: "1",
expectedDef: "true",
},
{
name: "env_var_0",
envValue: "0",
expectedDef: "false",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Setenv(DisableChangelogEnvVar, tt.envValue)

cmd := &cobra.Command{
Use: "test",
}

var disableChangelog bool
addDisableChangelogFlag(cmd, &disableChangelog)

flag := cmd.Flags().Lookup("disable-changelog")
if flag == nil {
t.Fatal("flag not registered")
}

if flag.DefValue != tt.expectedDef {
t.Errorf(
"flag default value: got %q, expected %q",
flag.DefValue,
tt.expectedDef,
)
}
})
}
}

func TestDisableChangelogFlagOverridesEnv(t *testing.T) {
t.Setenv(DisableChangelogEnvVar, "true")

cmd := &cobra.Command{
Use: "test",
RunE: func(cmd *cobra.Command, args []string) error {
return nil
},
}

var disableChangelog bool
addDisableChangelogFlag(cmd, &disableChangelog)

cmd.SetArgs([]string{"--disable-changelog=false"})

err := cmd.Execute()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}

if disableChangelog {
t.Error("expected flag to override env var")
}
}
3 changes: 3 additions & 0 deletions cmd/pipeline_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var (
e.Options.Pipeline.Target.DryRun = false
e.Options.Pipeline.Target.CleanGitBranches = applyCleanGitBranches
e.Options.Pipeline.Target.ExistingOnly = applyExistingOnly
e.Options.Pipeline.DisableChangelog = disableChangelog

err = run("pipeline/apply")
if err != nil {
Expand All @@ -67,5 +68,7 @@ func init() {
pipelineApplyCmd.Flags().StringArrayVar(&pipelineIds, "pipeline-ids", []string{}, "Filter pipelines to apply by their IDs, accepted as a comma separated list")
pipelineApplyCmd.Flags().StringArrayVar(&labels, "labels", []string{}, "Filter pipelines to apply by their labels, accepted as a comma separated list (key:value)")

addDisableChangelogFlag(pipelineApplyCmd, &disableChangelog)

pipelineCmd.AddCommand(pipelineApplyCmd)
}
3 changes: 3 additions & 0 deletions cmd/pipeline_diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var (
e.Options.Pipeline.Target.Push = false
e.Options.Pipeline.Target.Clean = diffClean
e.Options.Pipeline.Target.DryRun = true
e.Options.Pipeline.DisableChangelog = disableChangelog

err = run("pipeline/diff")
if err != nil {
Expand All @@ -54,5 +55,7 @@ func init() {
pipelineDiffCmd.Flags().StringArrayVar(&pipelineIds, "pipeline-ids", []string{}, "Filter pipelines to apply by their pipeline IDs, accepted a comma separated list")
pipelineDiffCmd.Flags().StringArrayVar(&labels, "labels", []string{}, "Filter pipelines to apply by their labels, accepted as a comma separated list (key:value)")

addDisableChangelogFlag(pipelineDiffCmd, &disableChangelog)

pipelineCmd.AddCommand(pipelineDiffCmd)
}
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ var (
verbose bool
experimental bool
disableTLS bool
disableChangelog bool
uniqueTmpDir bool

rootCmd = &cobra.Command{
Expand Down
2 changes: 2 additions & 0 deletions pkg/core/pipeline/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ import (

type Options struct {
Target target.Options
// DisableChangelog disables changelog retrieval for targets.
DisableChangelog bool
}
Loading
Loading