mirror of
https://github.com/luxfi/cli.git
synced 2026-10-30 17:01:20 +00:00
141 lines
4.2 KiB
Go
141 lines
4.2 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
package utils
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
|
|
"github.com/luxfi/cli/v2/pkg/types"
|
|
|
|
"github.com/luxfi/cli/v2/pkg/ux"
|
|
|
|
"github.com/posthog/posthog-go"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// telemetryToken value is set at build and install scripts using ldflags
|
|
var (
|
|
telemetryToken = ""
|
|
telemetryInstance = "https://app.posthog.com"
|
|
)
|
|
|
|
func GetCLIVersion() string {
|
|
wdPath, err := os.Getwd()
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
versionPath := filepath.Join(wdPath, "VERSION")
|
|
content, err := os.ReadFile(versionPath)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(content)
|
|
}
|
|
|
|
func PrintMetricsOptOutPrompt() {
|
|
ux.Logger.PrintToUser(
|
|
"Lux CLI (the \"software\") may collect statistical data on how the software is used on an anonymous " +
|
|
"basis for purposes of product improvement. This data will not (i) include any passwords, scripts, or data " +
|
|
"files, (ii) be associated with any particular user or entity, or (iii) include any personally identifiable " +
|
|
"information or be used to identify individuals or entities using the software. You can disable such data " +
|
|
"collection with `lux config metrics disable` command, which will result in no data being collected; " +
|
|
"by using the software without so disabling such data collection you expressly consent to the collection of " +
|
|
"such data. You can also read our privacy statement <https://lux.network/privacy> to learn more. \n")
|
|
ux.Logger.PrintToUser("You can disable data collection with `lux config metrics disable` command. " +
|
|
"You can also read our privacy statement <https://lux.network/privacy> to learn more.\n")
|
|
}
|
|
|
|
func saveMetricsConfig(writer types.ConfigWriter, metricsEnabled bool) {
|
|
cfg := types.Config{MetricsEnabled: metricsEnabled}
|
|
jsonBytes, _ := json.Marshal(&cfg)
|
|
_ = writer.WriteConfigFile(jsonBytes)
|
|
}
|
|
|
|
func HandleUserMetricsPreference(app interface{}) error {
|
|
writer, ok := app.(types.ConfigWriter)
|
|
if !ok {
|
|
return fmt.Errorf("app does not implement ConfigWriter")
|
|
}
|
|
prompter, ok := app.(types.PrompterInterface)
|
|
if !ok {
|
|
return fmt.Errorf("app does not implement PrompterInterface")
|
|
}
|
|
|
|
PrintMetricsOptOutPrompt()
|
|
txt := "Press [Enter] to opt-in, or opt out by choosing 'No'"
|
|
yes, err := prompter.CaptureYesNo(txt)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !yes {
|
|
ux.Logger.PrintToUser("Lux CLI usage metrics will not be collected")
|
|
} else {
|
|
ux.Logger.PrintToUser("Thank you for opting in Lux CLI usage metrics collection")
|
|
}
|
|
saveMetricsConfig(writer, yes)
|
|
return nil
|
|
}
|
|
|
|
func userIsOptedIn(app interface{}) bool {
|
|
loader, ok := app.(types.ConfigLoader)
|
|
if !ok {
|
|
return false
|
|
}
|
|
// if config file is not found or unable to be read, will return false (user is not opted in)
|
|
config, err := loader.LoadConfig()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return config.MetricsEnabled
|
|
}
|
|
|
|
func HandleTracking(cmd *cobra.Command, app interface{}, flags map[string]string) {
|
|
if userIsOptedIn(app) {
|
|
if !cmd.HasSubCommands() && checkCommandIsNotCompletion(cmd) {
|
|
TrackMetrics(cmd, flags)
|
|
}
|
|
}
|
|
}
|
|
|
|
func checkCommandIsNotCompletion(cmd *cobra.Command) bool {
|
|
result := strings.Fields(cmd.CommandPath())
|
|
if len(result) >= 2 && result[1] == "completion" {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func TrackMetrics(command *cobra.Command, flags map[string]string) {
|
|
if telemetryToken == "" || os.Getenv("RUN_E2E") != "" {
|
|
return
|
|
}
|
|
|
|
client, _ := posthog.NewWithConfig(telemetryToken, posthog.Config{Endpoint: telemetryInstance})
|
|
|
|
defer client.Close()
|
|
|
|
usr, _ := user.Current() // use empty string if err
|
|
hash := sha256.Sum256([]byte(fmt.Sprintf("%s%s", usr.Username, usr.Uid)))
|
|
userID := base64.StdEncoding.EncodeToString(hash[:])
|
|
telemetryProperties := make(map[string]interface{})
|
|
telemetryProperties["command"] = command.CommandPath()
|
|
telemetryProperties["version"] = GetCLIVersion()
|
|
telemetryProperties["os"] = runtime.GOOS
|
|
for propertyKey, propertyValue := range flags {
|
|
telemetryProperties[propertyKey] = propertyValue
|
|
}
|
|
_ = client.Enqueue(posthog.Capture{
|
|
DistinctId: userID,
|
|
Event: "cli-command",
|
|
Properties: telemetryProperties,
|
|
})
|
|
}
|