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

feat: track help cmd #245

Merged
merged 3 commits into from
May 7, 2024
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
11 changes: 10 additions & 1 deletion cmd/analytics/analytics.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import (
"github.com/spf13/viper"
)

func CmdRunEventProperties(cmd *cobra.Command, name string) map[string]interface{} {
func CmdRunEventProperties(
cmd *cobra.Command,
name string,
overrides map[string]interface{},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add overrides so we can pass in an optional "action: help". We could make this functional options if we want to use it for more than the one-off case this introduces.

) map[string]interface{} {
baseURI := viper.GetString(cliflags.BaseURIFlag)
var flags []string
cmd.Flags().Visit(func(f *pflag.Flag) {
Expand All @@ -23,5 +27,10 @@ func CmdRunEventProperties(cmd *cobra.Command, name string) map[string]interface
if baseURI != cliflags.BaseURIDefault {
properties["baseURI"] = baseURI
}

for k, v := range overrides {
properties[k] = v
}

return properties
}
28 changes: 22 additions & 6 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ func NewConfigCmd(analyticsTracker analytics.Tracker) *cobra.Command {
Short: "View and modify specific configuration values",
Use: "config",
PreRun: func(cmd *cobra.Command, args []string) {
analyticsTracker.SendCommandRunEvent(
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(cmd, "config"),
)
// only track event if there are flags
if len(os.Args[1:]) > 1 {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there's a better way to do this. Since we define config --list/--set/--unset with no action, we only want to send this if we're not showing help.

analyticsTracker.SendCommandRunEvent(
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(cmd, "config", nil),
)
}
},
}

Expand All @@ -53,6 +56,19 @@ func NewConfigCmd(analyticsTracker analytics.Tracker) *cobra.Command {
sb.WriteString(fmt.Sprintf("- `%s`: %s\n", s, cliflags.AllFlagsHelp()[s]))
}
cmd.Long += sb.String()

analyticsTracker.SendCommandRunEvent(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to what we do in the root command.

viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(cmd,
"config",
map[string]interface{}{
"action": "help",
},
),
)

helpFun(cmd, args)
})

Expand Down
2 changes: 1 addition & 1 deletion cmd/members/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func NewMembersCmd(analyticsTracker analytics.Tracker, client members.Client) (*
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(cmd, "members"),
cmdAnalytics.CmdRunEventProperties(cmd, "members", nil),
)
},
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/resources/resource_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func removeResourceFromOperationId(resourceName, operationId string) string {
// a lot of "list" operations say "GetFor{ResourceName}"
fmt.Sprintf("For%s", singularResourceName), "",
fmt.Sprintf("For%s", resourceName), "",
fmt.Sprint("ByProject"), "",
"ByProject", "",
resourceName, "",
singularResourceName, "",
)
Expand Down Expand Up @@ -98,7 +98,7 @@ func isListResponse(op *openapi3.Operation, spec *openapi3.T) bool {
return true
}
}

return false
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func NewResourceCmd(parentCmd *cobra.Command, analyticsTracker analytics.Tracker
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(cmd, resourceName),
cmdAnalytics.CmdRunEventProperties(cmd, resourceName, nil),
)
},
}
Expand Down
30 changes: 30 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"

cmdAnalytics "ldcli/cmd/analytics"
"ldcli/cmd/cliflags"
configcmd "ldcli/cmd/config"
resourcecmd "ldcli/cmd/resources"
Expand Down Expand Up @@ -66,6 +67,24 @@ func NewRootCommand(
SilenceUsage: true,
}

hf := cmd.HelpFunc()
cmd.SetHelpFunc(func(c *cobra.Command, args []string) {
// get the resource for the tracking event, not the action
resourceCommand := getResourceCommand(c)
analyticsTracker.SendCommandRunEvent(
viper.GetString(cliflags.AccessTokenFlag),
viper.GetString(cliflags.BaseURIFlag),
viper.GetBool(cliflags.AnalyticsOptOut),
cmdAnalytics.CmdRunEventProperties(c,
resourceCommand.Name(),
map[string]interface{}{
"action": "help",
},
),
)
hf(c, args)
})

if useConfigFile {
setFlagsFromConfig()
}
Expand Down Expand Up @@ -174,3 +193,14 @@ func setFlagsFromConfig() {
viper.SetConfigFile(config.GetConfigFile())
_ = viper.ReadInConfig()
}

// getResourceCommand returns the command for a resource or an action's parent resource.
// ldcli projects // returns projects command
// ldcli projects list // returns projects command
func getResourceCommand(c *cobra.Command) *cobra.Command {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need this since a user could call help in various ways.

if !c.HasParent() || c.Parent() == c.Root() {
return c
}

return getResourceCommand(c.Parent())
}
19 changes: 14 additions & 5 deletions internal/analytics/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ type Tracker interface {
}

type Client struct {
ID string
HTTPClient *http.Client
Version string
sentRunEvent bool
wg sync.WaitGroup
ID string
HTTPClient *http.Client
Version string
sentHelpEvent bool
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep state here to know if we already tracked a help event.

sentRunEvent bool
wg sync.WaitGroup
}

// SendEvent makes an async request to track the given event with properties.
Expand Down Expand Up @@ -127,6 +128,10 @@ func (c *Client) SendCommandRunEvent(
)
if !optOut {
c.sentRunEvent = true
action, ok := properties["action"]
if ok && action == "help" {
c.sentHelpEvent = true
}
}
}

Expand All @@ -137,6 +142,10 @@ func (c *Client) SendCommandCompletedEvent(
outcome string,
) {
if c.sentRunEvent {
if c.sentHelpEvent {
outcome = HELP
}

c.sendEvent(
accessToken,
baseURI,
Expand Down
3 changes: 2 additions & 1 deletion internal/analytics/events.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package analytics

const (
SUCCESS = "success"
ERROR = "error"
HELP = "help"
SUCCESS = "success"
)

func MockedTracker(name string, action string, flags []string, outcome string) *MockTracker {
Expand Down
Loading