diff --git a/cmd/root.go b/cmd/root.go index bb4b7b1a..1885c95c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -204,7 +204,7 @@ func NewRootCommand( cmd.AddCommand(logincmd.NewLoginCmd(resources.NewClient(version))) cmd.AddCommand(resourcecmd.NewResourcesCmd()) cmd.AddCommand(devcmd.NewDevServerCmd(resources.NewClient(version), analyticsTrackerFn, dev_server.NewClient(version))) - cmd.AddCommand(sourcemapscmd.NewSourcemapsCmd()) + cmd.AddCommand(sourcemapscmd.NewSourcemapsCmd(resources.NewClient(version), analyticsTrackerFn)) resourcecmd.AddAllResourceCmds(cmd, clients.ResourcesClient, analyticsTrackerFn) // add non-generated commands diff --git a/cmd/sourcemaps/sourcemaps.go b/cmd/sourcemaps/sourcemaps.go index e56b4c4b..eea25f11 100644 --- a/cmd/sourcemaps/sourcemaps.go +++ b/cmd/sourcemaps/sourcemaps.go @@ -3,20 +3,21 @@ package sourcemaps import ( "github.com/spf13/cobra" + resourcescmd "github.com/launchdarkly/ldcli/cmd/resources" + "github.com/launchdarkly/ldcli/internal/analytics" "github.com/launchdarkly/ldcli/internal/resources" ) -func NewSourcemapsCmd() *cobra.Command { +func NewSourcemapsCmd(client resources.Client, analyticsTrackerFn analytics.TrackerFn) *cobra.Command { cmd := &cobra.Command{ Use: "sourcemaps", Short: "Manage sourcemaps", Long: "Manage sourcemaps for LaunchDarkly error monitoring", - Run: func(cmd *cobra.Command, args []string) { - _ = cmd.Help() - }, + Args: cobra.MinimumNArgs(1), } - cmd.AddCommand(NewUploadCmd(resources.NewClient(""))) + cmd.AddCommand(NewUploadCmd(client, analyticsTrackerFn)) + cmd.SetUsageTemplate(resourcescmd.SubcommandUsageTemplate()) return cmd } diff --git a/cmd/sourcemaps/upload.go b/cmd/sourcemaps/upload.go index 06256c0d..d81879ad 100644 --- a/cmd/sourcemaps/upload.go +++ b/cmd/sourcemaps/upload.go @@ -16,9 +16,11 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + cmdAnalytics "github.com/launchdarkly/ldcli/cmd/analytics" "github.com/launchdarkly/ldcli/cmd/cliflags" resourcescmd "github.com/launchdarkly/ldcli/cmd/resources" "github.com/launchdarkly/ldcli/cmd/validators" + "github.com/launchdarkly/ldcli/internal/analytics" "github.com/launchdarkly/ldcli/internal/output" "github.com/launchdarkly/ldcli/internal/resources" ) @@ -66,13 +68,26 @@ type SourceMapFile struct { Name string } -func NewUploadCmd(client resources.Client) *cobra.Command { +func NewUploadCmd(client resources.Client, analyticsTrackerFn analytics.TrackerFn) *cobra.Command { cmd := &cobra.Command{ Args: validators.Validate(), Use: "upload", Short: "Upload sourcemaps", Long: "Upload JavaScript sourcemaps to LaunchDarkly for error monitoring", RunE: runE(client), + PersistentPreRun: func(cmd *cobra.Command, args []string) { + tracker := analyticsTrackerFn( + viper.GetString(cliflags.AccessTokenFlag), + viper.GetString(cliflags.BaseURIFlag), + viper.GetBool(cliflags.AnalyticsOptOut), + ) + tracker.SendCommandRunEvent(cmdAnalytics.CmdRunEventProperties( + cmd, + "sourcemaps", + map[string]interface{}{ + "action": cmd.Name(), + })) + }, } cmd.SetUsageTemplate(resourcescmd.SubcommandUsageTemplate()) diff --git a/cmd/sourcemaps/upload_test.go b/cmd/sourcemaps/upload_test.go index bed12489..3f78d0cd 100644 --- a/cmd/sourcemaps/upload_test.go +++ b/cmd/sourcemaps/upload_test.go @@ -13,8 +13,10 @@ import ( "github.com/stretchr/testify/assert" + "github.com/launchdarkly/ldcli/internal/analytics" "github.com/launchdarkly/ldcli/internal/resources" ) + // Mock resources.Client implementation for testing type mockResourcesClient struct { responses map[string][]byte @@ -35,9 +37,6 @@ func (m *mockResourcesClient) GetVersion() string { return "test-version" } - - - func TestGetSourceMapUploadUrls(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodPost, r.Method) @@ -131,7 +130,9 @@ func TestUploadFile(t *testing.T) { func TestNewUploadCmd(t *testing.T) { client := resources.NewClient("") - cmd := NewUploadCmd(client) + cmd := NewUploadCmd(client, func(accessToken, baseURI string, analyticsOptOut bool) analytics.Tracker { + return &analytics.MockTracker{} + }) assert.Equal(t, "upload", cmd.Use) assert.Equal(t, "Upload sourcemaps", cmd.Short) @@ -200,7 +201,6 @@ func TestGetAllSourceMapFiles(t *testing.T) { assert.Contains(t, err.Error(), "no .js.map files found") } - func TestGetSourceMapUploadUrlsErrors(t *testing.T) { _, err := getSourceMapUploadUrls("test-key", "project123", []string{"path"}, "://invalid-url") assert.Error(t, err) @@ -227,7 +227,9 @@ func TestRunE(t *testing.T) { }, } - cmd := NewUploadCmd(mockClient) + cmd := NewUploadCmd(mockClient, func(accessToken, baseURI string, analyticsOptOut bool) analytics.Tracker { + return &analytics.MockTracker{} + }) args := []string{} tempDir, err := os.MkdirTemp("", "sourcemap-test") @@ -254,14 +256,14 @@ func TestRunE(t *testing.T) { runFunc := runE(mockClient) err = runFunc(cmd, args) assert.Error(t, err) - + err = cmd.Flags().Set("project", "test-project") assert.NoError(t, err) err = cmd.Flags().Set(pathFlag, testMapFile) assert.NoError(t, err) err = cmd.Flags().Set(backendUrlFlag, urlsServer.URL) assert.NoError(t, err) - + err = runFunc(cmd, args) assert.Error(t, err) }