Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add commands to usage report #1299

Merged
merged 13 commits into from
Nov 13, 2024
4 changes: 4 additions & 0 deletions artifactory/commands/buildinfo/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ func (bpc *BuildPublishCommand) IsDetailedSummary() bool {
}

func (bpc *BuildPublishCommand) CommandName() string {
isAutoPublishedTriggered, err := clientutils.GetBoolEnvValue(coreutils.UsageAutoPublishedBuild, false)
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
if err == nil && isAutoPublishedTriggered {
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
return "rt_auto_build_publish"
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
}
return "rt_build_publish"
}

Expand Down
28 changes: 27 additions & 1 deletion common/commands/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ const (
WebLogin AuthenticationMethod = "Web Login"
)

const (
// Indicates that the config command uses OIDC authentication.
ConfigOidcCommandName = "config_OIDC"
// Default config command name.
ConfigCommandName = "config"
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
)

// Internal golang locking for the same process.
var mutex sync.Mutex

Expand Down Expand Up @@ -143,7 +150,26 @@ func (cc *ConfigCommand) ServerDetails() (*config.ServerDetails, error) {
}

func (cc *ConfigCommand) CommandName() string {
return "config"
isOidcConfigured, err := clientUtils.GetBoolEnvValue(coreutils.UsageOidcConfigured, false)
if err == nil && isOidcConfigured {
return ConfigOidcCommandName
}
return ConfigCommandName
}

// ExecAndReportUsage runs the ConfigCommand and then triggers a usage report if needed,
// Report usage only if OIDC integration was used
// Usage must be sent after command execution as we need the server details to be set.
func (cc *ConfigCommand) ExecAndReportUsage() error {
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
err := cc.Run()
if cc.CommandName() == ConfigOidcCommandName {
channel := make(chan bool)
// Triggers the report usage.
go reportUsage(cc, channel)
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
// Waits for the signal from the report usage to be done.
<-channel
}
return err
}

func (cc *ConfigCommand) config() error {
Expand Down
61 changes: 61 additions & 0 deletions common/commands/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,67 @@ func TestImport(t *testing.T) {
assert.Equal(t, "password", serverDetails.GetPassword())
}

func TestCommandName(t *testing.T) {
cc := NewConfigCommand(AddOrEdit, testServerId)

// Test when the environment variable is not set
err := os.Unsetenv(coreutils.UsageOidcConfigured)
assert.NoError(t, err)
assert.Equal(t, ConfigCommandName, cc.CommandName())

// Test when the environment variable is set
err = os.Setenv(coreutils.UsageOidcConfigured, "true")
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
assert.NoError(t, err)

assert.Equal(t, ConfigOidcCommandName, cc.CommandName())

// Clean up
err = os.Unsetenv(coreutils.UsageOidcConfigured)
assert.NoError(t, err)
}

func TestConfigCommand_ExecAndReportUsage(t *testing.T) {
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
// Define test scenarios
testCases := []struct {
name string
envVarValue string // Environment variable value to set (or empty to unset)
expectedName string // Expected command name
expectError bool // Whether an error is expected
}{
{
name: "With usage report",
envVarValue: "TRUE",
expectedName: ConfigOidcCommandName,
},
{
name: "Without usage report",
envVarValue: "", // Empty to unset the environment variable
expectedName: ConfigCommandName,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Set or unset the environment variable
if tc.envVarValue != "" {
err := os.Setenv(coreutils.UsageOidcConfigured, tc.envVarValue)
assert.NoError(t, err)
} else {
err := os.Unsetenv(coreutils.UsageOidcConfigured)
assert.NoError(t, err)
}

// Initialize the command and check the expected command name
cc := NewConfigCommand(AddOrEdit, testServerId)
assert.Equal(t, tc.expectedName, cc.CommandName())

// Execute and validate no errors
err := cc.ExecAndReportUsage()
assert.NoError(t, err)
})
}
}

func testExportImport(t *testing.T, inputDetails *config.ServerDetails) {
configToken, err := config.Export(inputDetails)
assert.NoError(t, err)
Expand Down
3 changes: 3 additions & 0 deletions utils/coreutils/coreconsts.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ const (
CI = "CI"
ServerID = "JFROG_CLI_SERVER_ID"
TransitiveDownload = "JFROG_CLI_TRANSITIVE_DOWNLOAD"
// Envs used to determine command types for usage reports
EyalDelarea marked this conversation as resolved.
Show resolved Hide resolved
UsageAutoPublishedBuild = "JFROG_CLI_USAGE_AUTO_BUILD_PUBLISHED"
UsageOidcConfigured = "JFROG_CLI_USAGE_CONFIG_OIDC"

// Deprecated and replaced with TransitiveDownload
TransitiveDownloadExperimental = "JFROG_CLI_TRANSITIVE_DOWNLOAD_EXPERIMENTAL"
Expand Down