Skip to content

Commit

Permalink
chore: Added telemetry events for completion, config, diagnostic, fol…
Browse files Browse the repository at this point in the history
…low and open
  • Loading branch information
JulesFaucherre committed Aug 1, 2023
1 parent 9bacba5 commit c0c284e
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 52 deletions.
9 changes: 8 additions & 1 deletion cmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package cmd
import (
"os"

"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/spf13/cobra"
)

func newCompletionCommand() *cobra.Command {
func newCompletionCommand(config *settings.Config) *cobra.Command {
completionCmd := &cobra.Command{
Use: "completion",
Short: "Generate shell completion scripts",
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
telemetryClient := createTelemetry(config)
defer telemetryClient.Close()
telemetryClient.Track(telemetry.CreateCompletionCommand(getCommandInformation(cmd, false)))
},
Run: func(cmd *cobra.Command, _ []string) {
err := cmd.Help()
if err != nil {
Expand Down
37 changes: 34 additions & 3 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import (
"github.com/CircleCI-Public/circleci-cli/filetree"
"github.com/CircleCI-Public/circleci-cli/proxy"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)

// Path to the config.yml file to operate on.
Expand All @@ -29,16 +33,34 @@ var configAnnotations = map[string]string{
}

func newConfigCommand(globalConfig *settings.Config) *cobra.Command {
var telemetryClient telemetry.Client

closeTelemetryClient := func() {
if telemetryClient != nil {
telemetryClient.Close()
telemetryClient = nil
}
}

configCmd := &cobra.Command{
Use: "config",
Short: "Operate on build config files",
PersistentPreRun: func(_ *cobra.Command, _ []string) {
telemetryClient = createTelemetry(globalConfig)
},
PersistentPostRun: func(cmd *cobra.Command, args []string) {
closeTelemetryClient()
},
}

packCommand := &cobra.Command{
Use: "pack <path>",
Short: "Pack up your CircleCI configuration into a single file.",
RunE: func(_ *cobra.Command, args []string) error {
return packConfig(args)
RunE: func(cmd *cobra.Command, args []string) error {
defer closeTelemetryClient()
err := packConfig(args)
telemetryClient.Track(telemetry.CreateConfigEvent(getCommandInformation(cmd, true)))
return err
},
Args: cobra.ExactArgs(1),
Annotations: make(map[string]string),
Expand All @@ -50,6 +72,8 @@ func newConfigCommand(globalConfig *settings.Config) *cobra.Command {
Aliases: []string{"check"},
Short: "Check that the config file is well formed.",
RunE: func(cmd *cobra.Command, args []string) error {
defer closeTelemetryClient()

compiler := config.New(globalConfig)
orgID, _ := cmd.Flags().GetString("org-id")
orgSlug, _ := cmd.Flags().GetString("org-slug")
Expand All @@ -60,13 +84,17 @@ func newConfigCommand(globalConfig *settings.Config) *cobra.Command {
if len(args) == 1 {
path = args[0]
}
return compiler.ValidateConfig(config.ValidateConfigOpts{

err := compiler.ValidateConfig(config.ValidateConfigOpts{
ConfigPath: path,
OrgID: orgID,
OrgSlug: orgSlug,
IgnoreDeprecatedImages: ignoreDeprecatedImages,
VerboseOutput: verboseOutput,
})
telemetryClient.Track(telemetry.CreateConfigEvent(getCommandInformation(cmd, true)))

return err
},
Args: cobra.MaximumNArgs(1),
Annotations: make(map[string]string),
Expand All @@ -86,6 +114,8 @@ func newConfigCommand(globalConfig *settings.Config) *cobra.Command {
Use: "process <path>",
Short: "Validate config and display expanded configuration.",
RunE: func(cmd *cobra.Command, args []string) error {
defer closeTelemetryClient()

compiler := config.New(globalConfig)
pipelineParamsFilePath, _ := cmd.Flags().GetString("pipeline-parameters")
orgID, _ := cmd.Flags().GetString("org-id")
Expand All @@ -97,6 +127,7 @@ func newConfigCommand(globalConfig *settings.Config) *cobra.Command {
if len(args) == 1 {
path = args[0]
}
telemetryClient.Track(telemetry.CreateConfigEvent(getCommandInformation(cmd, true)))
response, err := compiler.ProcessConfig(config.ProcessConfigOpts{
ConfigPath: path,
OrgID: orgID,
Expand Down
37 changes: 37 additions & 0 deletions cmd/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path/filepath"

"github.com/CircleCI-Public/circleci-cli/clitest"
"github.com/CircleCI-Public/circleci-cli/telemetry"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
Expand All @@ -29,6 +30,42 @@ var _ = Describe("Config", func() {
tempSettings.Close()
})

Describe("telemetry", func() {
var telemetryDestFilePath string

BeforeEach(func() {
telemetryDestFilePath = filepath.Join(tempSettings.Home, "telemetry-content")

tempSettings = clitest.WithTempSettings()
command = commandWithHome(pathCLI, tempSettings.Home,
"config", "pack",
"--skip-update-check",
"testdata/hugo-pack/.circleci",
"--mock-telemetry", telemetryDestFilePath,
)
})

AfterEach(func() {
tempSettings.Close()
if _, err := os.Stat(telemetryDestFilePath); err == nil || !os.IsNotExist(err) {
os.Remove(telemetryDestFilePath)
}
})

It("should send telemetry event", func() {
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())

Eventually(session).Should(gexec.Exit(0))
clitest.CompareTelemetryEvent(telemetryDestFilePath, []telemetry.Event{
telemetry.CreateConfigEvent(telemetry.CommandInfo{
Name: "pack",
LocalArgs: map[string]string{"help": "false"},
}),
})
})
})

Describe("a .circleci folder with config.yml and local orbs folder containing the hugo orb", func() {
BeforeEach(func() {
command = exec.Command(pathCLI,
Expand Down
12 changes: 7 additions & 5 deletions cmd/diagnostic.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ func newDiagnosticCommand(config *settings.Config) *cobra.Command {
Use: "diagnostic",
Short: "Check the status of your CircleCI CLI.",
PreRun: func(cmd *cobra.Command, args []string) {
telemetryClient := createTelemetry(config)
defer telemetryClient.Close()
telemetryClient.Track(telemetry.CreateDiagnosticEvent())

opts.args = args
opts.cl = graphql.NewClient(config.HTTPClient, config.Host, config.Endpoint, config.Token, config.Debug)
},
RunE: func(_ *cobra.Command, _ []string) error {
return diagnostic(opts)
telemetryClient := createTelemetry(config)
defer telemetryClient.Close()

err := diagnostic(opts)
telemetryClient.Track(telemetry.CreateDiagnosticEvent(err))

return err
},
}

Expand Down
29 changes: 25 additions & 4 deletions cmd/diagnostic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package cmd_test
import (
"fmt"
"net/http"
"os"
"os/exec"
"path/filepath"

"github.com/CircleCI-Public/circleci-cli/api/graphql"
"github.com/CircleCI-Public/circleci-cli/clitest"
"github.com/CircleCI-Public/circleci-cli/telemetry"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
Expand All @@ -17,18 +19,21 @@ import (

var _ = Describe("Diagnostic", func() {
var (
tempSettings *clitest.TempSettings
command *exec.Cmd
defaultEndpoint = "graphql-unstable"
telemetryDestFilePath string
tempSettings *clitest.TempSettings
command *exec.Cmd
defaultEndpoint = "graphql-unstable"
)

BeforeEach(func() {
tempSettings = clitest.WithTempSettings()
telemetryDestFilePath = filepath.Join(tempSettings.Home, "telemetry-content")

command = commandWithHome(pathCLI, tempSettings.Home,
"diagnostic",
"--skip-update-check",
"--host", tempSettings.TestServer.URL())
"--host", tempSettings.TestServer.URL(),
"--mock-telemetry", telemetryDestFilePath)

query := `query IntrospectionQuery {
__schema {
Expand Down Expand Up @@ -77,6 +82,22 @@ var _ = Describe("Diagnostic", func() {

AfterEach(func() {
tempSettings.Close()
if _, err := os.Stat(telemetryDestFilePath); err == nil || !os.IsNotExist(err) {
os.Remove(telemetryDestFilePath)
}
})

Describe("telemetry", func() {
It("should send telemetry event", func() {
tempSettings.Config.Write([]byte(`token: mytoken`))
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())

Eventually(session).Should(gexec.Exit(0))
clitest.CompareTelemetryEvent(telemetryDestFilePath, []telemetry.Event{
telemetry.CreateDiagnosticEvent(nil),
})
})
})

Describe("existing config file", func() {
Expand Down
9 changes: 8 additions & 1 deletion cmd/follow.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/CircleCI-Public/circleci-cli/api"
"github.com/CircleCI-Public/circleci-cli/git"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -54,7 +55,13 @@ func followProjectCommand(config *settings.Config) *cobra.Command {
Use: "follow",
Short: "Attempt to follow the project for the current git repository.",
RunE: func(_ *cobra.Command, _ []string) error {
return followProject(opts)
telemetryClient := createTelemetry(config)
defer telemetryClient.Close()

err := followProject(opts)
telemetryClient.Track(telemetry.CreateFollowEvent(err))

return err
},
}
return followCommand
Expand Down
14 changes: 11 additions & 3 deletions cmd/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ import (
"strings"

"github.com/CircleCI-Public/circleci-cli/git"
"github.com/CircleCI-Public/circleci-cli/settings"
"github.com/CircleCI-Public/circleci-cli/telemetry"
"github.com/pkg/browser"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

// errorMessage string containing the error message displayed in both the open command and the follow command
var errorMessage = `
This command is intended to be run from a git repository with a remote named 'origin' that is hosted on Github or Bitbucket only.
This command is intended to be run from a git repository with a remote named 'origin' that is hosted on Github or Bitbucket only.
We are not currently supporting any other hosts.`

// projectUrl uses the provided values to create the url to open
Expand All @@ -39,12 +41,18 @@ func openProjectInBrowser() error {
}

// newOpenCommand creates the cli command open
func newOpenCommand() *cobra.Command {
func newOpenCommand(config *settings.Config) *cobra.Command {
openCommand := &cobra.Command{
Use: "open",
Short: "Open the current project in the browser.",
RunE: func(_ *cobra.Command, _ []string) error {
return openProjectInBrowser()
telemetryClient := createTelemetry(config)
defer telemetryClient.Close()

err := openProjectInBrowser()
_ = telemetryClient.Track(telemetry.CreateOpenEvent(err))

return err
},
}
return openCommand
Expand Down
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ func MakeCommands() *cobra.Command {
return validateToken(rootOptions)
}

rootCmd.AddCommand(newOpenCommand())
rootCmd.AddCommand(newOpenCommand(rootOptions))
rootCmd.AddCommand(newTestsCommand())
rootCmd.AddCommand(newContextCommand(rootOptions))
rootCmd.AddCommand(project.NewProjectCommand(rootOptions, validator))
Expand Down Expand Up @@ -173,7 +173,7 @@ func MakeCommands() *cobra.Command {
rootCmd.AddCommand(newStepCommand(rootOptions))
rootCmd.AddCommand(newSwitchCommand(rootOptions))
rootCmd.AddCommand(newAdminCommand(rootOptions))
rootCmd.AddCommand(newCompletionCommand())
rootCmd.AddCommand(newCompletionCommand(rootOptions))
rootCmd.AddCommand(newEnvCmd())
rootCmd.AddCommand(newTelemetryCommand(rootOptions))

Expand Down
Loading

0 comments on commit c0c284e

Please sign in to comment.