diff --git a/config.go b/config.go index 82288cd..84f2e2c 100644 --- a/config.go +++ b/config.go @@ -27,7 +27,7 @@ import ( ) const ( - configVersion string = "1" + configVersion string = "1.1" ) var config map[string]*ini.File = make(map[string]*ini.File) @@ -92,55 +92,64 @@ func migrateConfig() { return } - if _, err = os.Stat(configPath); err == nil { - // Do we need to migrate from an older version? - if getConfigValue("cli", "config-version") == configVersion { - return - } - } - - // Create v1 _, err = openConfig() if err != nil { return } - setConfigValue("cli", "config-version", configVersion) - saveConfig() + var currentVersion string + if _, err = os.Stat(configPath); err == nil { + // Do we need to migrate from an older version? + currentVersion = getConfigValue("cli", "config-version") + if currentVersion == configVersion { + return + } + } - cliPath, _ := getAkamaiCliPath() + switch currentVersion { + case "": + // Create v1 + cliPath, _ := getAkamaiCliPath() - var data []byte - upgradeFile := filepath.Join(cliPath, ".upgrade-check") - if _, err := os.Stat(upgradeFile); err == nil { - data, _ = ioutil.ReadFile(upgradeFile) - } else { - upgradeFile = filepath.Join(cliPath, ".update-check") + var data []byte + upgradeFile := filepath.Join(cliPath, ".upgrade-check") if _, err := os.Stat(upgradeFile); err == nil { data, _ = ioutil.ReadFile(upgradeFile) } else { - return + upgradeFile = filepath.Join(cliPath, ".update-check") + if _, err := os.Stat(upgradeFile); err == nil { + data, _ = ioutil.ReadFile(upgradeFile) + } } - } - if len(data) != 0 { - date := string(data) - if date == "never" || date == "ignore" { - setConfigValue("cli", "last-upgrade-check", date) - } else { - if m := strings.LastIndex(date, "m="); m != -1 { - date = date[0 : m-1] - } - lastUpgrade, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", date) - if err == nil { - setConfigValue("cli", "last-upgrade-check", lastUpgrade.Format(time.RFC3339)) + if len(data) != 0 { + date := string(data) + if date == "never" || date == "ignore" { + setConfigValue("cli", "last-upgrade-check", date) + } else { + if m := strings.LastIndex(date, "m="); m != -1 { + date = date[0 : m-1] + } + lastUpgrade, err := time.Parse("2006-01-02 15:04:05.999999999 -0700 MST", date) + if err == nil { + setConfigValue("cli", "last-upgrade-check", lastUpgrade.Format(time.RFC3339)) + } } + + os.Remove(upgradeFile) } - os.Remove(upgradeFile) + setConfigValue("cli", "config-version", "1") + case "1": + // Upgrade to v1.1 + if getConfigValue("cli", "enable-cli-statistics") == "true" { + setConfigValue("cli", "stats-version", "1.0") + } + setConfigValue("cli", "config-version", "1.1") } saveConfig() + migrateConfig() } func getConfigValue(sectionName string, keyName string) string { diff --git a/stats.go b/stats.go index a718583..53a91af 100644 --- a/stats.go +++ b/stats.go @@ -32,17 +32,20 @@ import ( // // This is done by generating an anonymous UUID that events are tied to +const statsVersion string = "1.1" + func firstRunCheckStats(bannerShown bool) bool { - if getConfigValue("cli", "client-id") == "" { + anonymous := color.New(color.FgWhite, color.Bold).Sprint("anonymous") + + if getConfigValue("cli", "enable-cli-statistics") == "" { if !bannerShown { bannerShown = true showBanner() } - anonymous := color.New(color.FgWhite, color.Bold).Sprint("anonymous") fmt.Fprintf(akamai.App.Writer, "Help Akamai improve Akamai CLI by automatically sending %s diagnostics and usage data.\n", anonymous) - fmt.Fprintln(akamai.App.Writer, "Examples of data being send include upgrade statistics, and packages installed and updated.") - fmt.Fprintln(akamai.App.Writer, "Note: if you choose to opt-out, a single anonymous event will be submitted to help track overall usage.") - fmt.Fprintf(akamai.App.Writer, "\nSend %s diagnostics and usage data to Akamai? [Y/n]: ", anonymous) + fmt.Fprintln(akamai.App.Writer, "Examples of data being sent include upgrade statistics, and packages installed and updated.") + fmt.Fprintf(akamai.App.Writer, "Note: if you choose to opt-out, a single %s event will be submitted to help track overall usage.", anonymous) + fmt.Fprintf(akamai.App.Writer, "\n\nSend %s diagnostics and usage data to Akamai? [Y/n]: ", anonymous) answer := "" fmt.Scanln(&answer) @@ -53,16 +56,60 @@ func firstRunCheckStats(bannerShown bool) bool { return bannerShown } - setConfigValue("cli", "enable-cli-statistics", "true") + setConfigValue("cli", "enable-cli-statistics", statsVersion) setConfigValue("cli", "last-ping", "never") setupUUID() saveConfig() - trackEvent("first-run", "stats-enabled", getConfigValue("cli", "client-id")) + trackEvent("first-run", "stats-enabled", statsVersion) + } else if getConfigValue("cli", "enable-cli-statistics") != "false" { + migrateStats(bannerShown) } return bannerShown } +func migrateStats(bannerShown bool) bool { + currentVersion := getConfigValue("cli", "stats-version") + if currentVersion == statsVersion { + return bannerShown + } + + if !bannerShown { + bannerShown = true + showBanner() + } + + var newStats []string + switch currentVersion { + case "1.0": + newStats = []string{"command name executed (no arguments)"} + } + + anonymous := color.New(color.FgWhite, color.Bold).Sprint("anonymous") + fmt.Fprintf(akamai.App.Writer, "Akamai CLI has changed the %s data it collects. It now additionally collects the following: \n\n", anonymous) + for _, value := range newStats { + fmt.Fprintf(akamai.App.Writer, " - %s\n", value) + } + fmt.Fprintf(akamai.App.Writer, "\nTo continue collecting %s statistics, Akamai CLI requires that you re-affirm you decision.\n", anonymous) + fmt.Fprintln(akamai.App.Writer, "Note: if you choose to opt-out, a single anonymous event will be submitted to help track overall usage.") + fmt.Fprintf(akamai.App.Writer, "\nContinue sending %s diagnostics and usage data to Akamai? [Y/n]: ", anonymous) + + answer := "" + fmt.Scanln(&answer) + if answer != "" && strings.ToLower(answer) != "y" { + trackEvent("first-run", "stats-update-opt-out", statsVersion) + setConfigValue("cli", "enable-cli-statistics", "false") + saveConfig() + return bannerShown + } + + setConfigValue("cli", "stats-version", statsVersion) + saveConfig() + trackEvent("first-run", "stats-update-opt-in", statsVersion) + + return bannerShown +} + func setupUUID() error { if getConfigValue("cli", "client-id") == "" { uuid, err := uuid.NewRandom() @@ -82,15 +129,20 @@ func trackEvent(category string, action string, value string) { return } + clientId := "anonymous" + if val := getConfigValue("cli", "client-id"); val != "" { + clientId = val + } + form := url.Values{} form.Add("tid", "UA-34796267-23") - form.Add("v", "1") // Version 1 - form.Add("aip", "1") // Anonymize IP - form.Add("cid", getConfigValue("cli", "client-id")) // Unique Cilent ID - form.Add("t", "event") // Type - form.Add("ec", category) // Category - form.Add("ea", action) // Action - form.Add("el", value) // Label + form.Add("v", "1") // Version 1 + form.Add("aip", "1") // Anonymize IP + form.Add("cid", clientId) // Client ID + form.Add("t", "event") // Type + form.Add("ec", category) // Category + form.Add("ea", action) // Action + form.Add("el", value) // Label hc := http.Client{} debug := os.Getenv("AKAMAI_CLI_DEBUG_ANALYTICS")