From 9b9e3fe179bc567f1e504575cf002c6a731295fa Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Mon, 14 Jul 2025 11:19:51 +0330 Subject: [PATCH 01/12] feat: create telemetry crate --- Cargo.lock | 39 ++++++++++++++++ Cargo.toml | 2 + crates/cli/Cargo.toml | 3 ++ crates/telemetry/Cargo.toml | 15 +++++++ crates/telemetry/src/lib.rs | 1 + crates/telemetry/src/send_event.rs | 72 ++++++++++++++++++++++++++++++ 6 files changed, 132 insertions(+) create mode 100644 crates/telemetry/Cargo.toml create mode 100644 crates/telemetry/src/lib.rs create mode 100644 crates/telemetry/src/send_event.rs diff --git a/Cargo.lock b/Cargo.lock index fec43e79f..035aa289c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -762,6 +762,7 @@ version = "1.0.0-rc.12" dependencies = [ "anyhow", "ast-grep-language", + "async-trait", "base64 0.22.1", "butterflow-core", "butterflow-models", @@ -770,6 +771,7 @@ dependencies = [ "chrono", "clap", "codemod-sandbox", + "codemod-telemetry", "console", "dirs", "env_logger", @@ -784,6 +786,7 @@ dependencies = [ "oauth2", "open", "percent-encoding", + "posthog-rs 0.2.2", "rand 0.8.5", "regex", "reqwest 0.11.27", @@ -845,6 +848,15 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "codemod-telemetry" +version = "1.0.0-rc.12" +dependencies = [ + "async-trait", + "posthog-rs 0.3.7", + "serde", +] + [[package]] name = "colorchoice" version = "1.0.3" @@ -3488,6 +3500,33 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "posthog-rs" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad1b35ffe50419992615288c40ee90fbf30da4c6faf251414675ea64e1cdfa3" +dependencies = [ + "chrono", + "reqwest 0.11.27", + "serde", + "serde_json", +] + +[[package]] +name = "posthog-rs" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610d236077c94c96194b0d2b40989bda4bf8faf60e15a0da6ef8ffd4c78f6c1c" +dependencies = [ + "chrono", + "derive_builder", + "reqwest 0.11.27", + "semver", + "serde", + "serde_json", + "uuid", +] + [[package]] name = "potential_utf" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 9ab8188ad..d7a40e3cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "crates/state", "crates/codemod-sandbox", "crates/codemod-sandbox/build", + "crates/telemetry", "xtask" ] resolver = "2" @@ -29,6 +30,7 @@ butterflow-state = { path = "crates/state" } butterflow-runners = { path = "crates/runners" } butterflow-scheduler = { path = "crates/scheduler" } codemod-sandbox = { path = "crates/codemod-sandbox" } +codemod-telemetry = { path = "crates/telemetry" } anyhow = "1.0" ast-grep-language = "0.38.6" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 91bd4602b..782365c10 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,6 +15,7 @@ butterflow-core = { workspace = true } butterflow-state = { workspace = true } butterflow-runners = { workspace = true } codemod-sandbox = { workspace = true } +codemod-telemetry = { workspace = true } tokio = { workspace = true } clap = { version = "4.5", features = ["derive"] } flate2 = { workspace = true } @@ -57,6 +58,8 @@ libtest-mimic = "0.8" similar = "2.0" ast-grep-language.workspace = true tabled = "0.20.0" +posthog-rs = "0.2.2" +async-trait.workspace = true [features] diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml new file mode 100644 index 000000000..99813d3c6 --- /dev/null +++ b/crates/telemetry/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "codemod-telemetry" +edition = "2021" +authors.workspace = true +description.workspace = true +documentation.workspace = true +repository.workspace = true +license.workspace = true +rust-version.workspace = true +version.workspace = true + +[dependencies] +async-trait.workspace = true +posthog-rs = "0.3.7" +serde.workspace = true diff --git a/crates/telemetry/src/lib.rs b/crates/telemetry/src/lib.rs new file mode 100644 index 000000000..69943afde --- /dev/null +++ b/crates/telemetry/src/lib.rs @@ -0,0 +1 @@ +pub mod send_event; \ No newline at end of file diff --git a/crates/telemetry/src/send_event.rs b/crates/telemetry/src/send_event.rs new file mode 100644 index 000000000..33cf1028e --- /dev/null +++ b/crates/telemetry/src/send_event.rs @@ -0,0 +1,72 @@ +use std::collections::HashMap; +use posthog_rs; +use serde::Serialize; +use async_trait::async_trait; + +#[derive(Debug, Clone)] +pub struct TelemetrySenderOptions { + pub distinct_id: String, + pub cloud_role: String, +} + +#[derive(Debug, Clone)] +pub struct PartialTelemetrySenderOptions { + pub distinct_id: Option, + pub cloud_role: Option, +} + +#[derive(Debug, Serialize, Clone)] +pub struct BaseEvent { + pub kind: String, + #[serde(flatten)] + pub properties: HashMap, +} + +#[async_trait] +pub trait TelemetrySender { + async fn send_event( + &self, + event: BaseEvent, + options_override: Option, + ); +} + +pub struct PostHogSender { + client: posthog_rs::Client, + options: TelemetrySenderOptions, +} + +impl PostHogSender { + pub async fn new(options: TelemetrySenderOptions) -> Self { + let client = posthog_rs::client("phc_nGWKWP3t1fcNFqGi6UdstXjMf0fxx7SBeohHPSS6d2Y").await; + Self { client, options } + } +} + +#[async_trait] +impl TelemetrySender for PostHogSender { + async fn send_event( + &self, + event: BaseEvent, + options_override: Option, + ) { + let distinct_id = options_override + .as_ref() + .and_then(|o| o.distinct_id.clone()) + .unwrap_or_else(|| self.options.distinct_id.clone()); + + let cloud_role = options_override + .as_ref() + .and_then(|o| o.cloud_role.clone()) + .unwrap_or_else(|| self.options.cloud_role.clone()); + + let posthog_event = posthog_rs::Event::new( + format!("codemod.{}.{}", cloud_role, event.kind), + distinct_id.clone() + ); + + if let Err(e) = self.client.capture(posthog_event).await { + eprintln!("Failed to send PostHog event: {e}"); + } + } +} From 9ca91782c6d3d1fb69ac3af0260ce7e689c9dfa4 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Mon, 14 Jul 2025 17:14:10 +0330 Subject: [PATCH 02/12] feat: add send posthug event into publish and run commands --- Cargo.lock | 1 + crates/cli/src/commands/publish.rs | 18 +++++++++++++++- crates/cli/src/commands/run.rs | 34 +++++++++++++++++++++++++----- crates/cli/src/main.rs | 20 ++++++++++++++---- crates/core/Cargo.toml | 1 + crates/core/src/engine.rs | 11 +++++++++- crates/telemetry/src/lib.rs | 2 +- crates/telemetry/src/send_event.rs | 6 +++--- 8 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 035aa289c..4d394c69f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -512,6 +512,7 @@ dependencies = [ "dirs", "flate2", "log", + "once_cell", "regex", "reqwest 0.12.15", "serde", diff --git a/crates/cli/src/commands/publish.rs b/crates/cli/src/commands/publish.rs index 124f2285a..4aaf1a749 100644 --- a/crates/cli/src/commands/publish.rs +++ b/crates/cli/src/commands/publish.rs @@ -4,12 +4,14 @@ use log::{debug, info, warn}; use reqwest; use serde::{Deserialize, Serialize}; use serde_yaml; +use std::collections::HashMap; use std::fs; use std::path::{Path, PathBuf}; use tempfile::TempDir; use walkdir::WalkDir; use crate::auth::TokenStorage; +use codemod_telemetry::send_event::{BaseEvent, PostHogSender, TelemetrySender}; #[derive(Args, Debug)] pub struct Command { @@ -117,7 +119,7 @@ struct PublishedPackage { published_at: String, } -pub async fn handler(args: &Command) -> Result<()> { +pub async fn handler(args: &Command, telemetry: &PostHogSender) -> Result<()> { let package_path = args .path .as_ref() @@ -196,6 +198,20 @@ pub async fn handler(args: &Command) -> Result<()> { return Err(anyhow!("Failed to publish package")); } + let cli_version = env!("CARGO_PKG_VERSION"); + + let _ = telemetry.send_event( + BaseEvent { + kind: "codemodPublished".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), manifest.name.clone()), + ("version".to_string(), manifest.version.clone()), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ); + println!("✅ Package published successfully!"); println!("📦 {}", format_package_name(&response.package)); println!("🏷️ Version: {}", response.package.version); diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index b25d46750..9a55ada89 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -2,14 +2,18 @@ use anyhow::Result; use butterflow_core::utils::get_cache_dir; use clap::Args; use log::info; +use rand::Rng; +use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command as ProcessCommand; use crate::auth_provider::CliAuthProvider; use crate::dirty_git_check; use crate::workflow_runner::{run_workflow, WorkflowRunConfig}; -use butterflow_core::engine::Engine; +use butterflow_core::engine::{Engine, GLOBAL_STATS}; use butterflow_core::registry::{RegistryClient, RegistryConfig, RegistryError}; +use codemod_sandbox::sandbox::engine::ExecutionStats; +use codemod_telemetry::send_event::{BaseEvent, PostHogSender, TelemetrySender}; #[derive(Args, Debug)] pub struct Command { @@ -42,7 +46,7 @@ pub struct Command { allow_dirty: bool, } -pub async fn handler(engine: &Engine, args: &Command) -> Result<()> { +pub async fn handler(engine: &Engine, args: &Command, telemetry: &PostHogSender) -> Result<()> { // Create auth provider let auth_provider = CliAuthProvider::new()?; @@ -92,7 +96,7 @@ pub async fn handler(engine: &Engine, args: &Command) -> Result<()> { ); // Execute the codemod - execute_codemod( + let stats = execute_codemod( engine, &resolved_package.package_dir, &args.path, @@ -101,6 +105,25 @@ pub async fn handler(engine: &Engine, args: &Command) -> Result<()> { ) .await?; + let cli_version = env!("CARGO_PKG_VERSION"); + let execution_id: [u8; 20] = rand::thread_rng().gen(); + let execution_id = base64::Engine::encode( + &base64::engine::general_purpose::URL_SAFE_NO_PAD, + execution_id, + ); + let _ = telemetry.send_event( + BaseEvent { + kind: "codemodExecuted".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), args.package.clone()), + ("executionId".to_string(), execution_id.clone()), + ("fileCount".to_string(), stats.files_modified.to_string()), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ); + Ok(()) } @@ -139,7 +162,7 @@ async fn execute_codemod( target_path: &Path, additional_args: &[String], dry_run: bool, -) -> Result<()> { +) -> Result { let workflow_path = package_dir.join("workflow.yaml"); info!( @@ -176,6 +199,7 @@ async fn execute_codemod( // Run workflow using the extracted workflow runner run_workflow(engine, config).await?; + let stats = GLOBAL_STATS.lock().await.clone(); - Ok(()) + Ok(stats) } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index c77ae56d9..97bb28272 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -10,6 +10,8 @@ mod dirty_git_check; mod engine; mod workflow_runner; use ascii_art::print_ascii_art; +use auth::TokenStorage; +use codemod_telemetry::send_event::{PostHogSender, TelemetrySenderOptions}; #[derive(Parser)] #[command(name = "codemod")] @@ -140,6 +142,7 @@ fn is_package_name(arg: &str) -> bool { async fn handle_implicit_run_command( engine: &butterflow_core::engine::Engine, trailing_args: Vec, + telemetry_sender: &PostHogSender, ) -> Result { if trailing_args.is_empty() { return Ok(false); @@ -158,7 +161,7 @@ async fn handle_implicit_run_command( match Cli::try_parse_from(&full_args) { Ok(new_cli) => { if let Some(Commands::Run(run_args)) = new_cli.command { - commands::run::handler(engine, &run_args).await?; + commands::run::handler(engine, &run_args, telemetry_sender).await?; Ok(true) } else { Ok(false) @@ -192,6 +195,15 @@ async fn main() -> Result<()> { // Create engine let engine = engine::create_engine()?; + let storage = TokenStorage::new()?; + let auth = storage.load_auth("https://app.codemod.com")?; + let auth = auth.unwrap(); + + let telemetry_sender = PostHogSender::new(TelemetrySenderOptions { + distinct_id: auth.user.id.clone(), + cloud_role: "cli".to_string(), + }) + .await; // Handle command or implicit run match &cli.command { @@ -236,13 +248,13 @@ async fn main() -> Result<()> { commands::whoami::handler(args).await?; } Some(Commands::Publish(args)) => { - commands::publish::handler(args).await?; + commands::publish::handler(args, &telemetry_sender).await?; } Some(Commands::Search(args)) => { commands::search::handler(args).await?; } Some(Commands::Run(args)) => { - commands::run::handler(&engine, args).await?; + commands::run::handler(&engine, args, &telemetry_sender).await?; } Some(Commands::Unpublish(args)) => { commands::unpublish::handler(args).await?; @@ -252,7 +264,7 @@ async fn main() -> Result<()> { } None => { // Try to parse as implicit run command - if !handle_implicit_run_command(&engine, cli.trailing_args).await? { + if !handle_implicit_run_command(&engine, cli.trailing_args, &telemetry_sender).await? { // No valid subcommand or package name provided, show help print_ascii_art(); eprintln!("No command provided. Use --help for usage information."); diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 69f7bd67f..f09bcda62 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -31,6 +31,7 @@ tar = { workspace = true } tempfile = { workspace = true } walkdir = { workspace = true } dirs = { workspace = true } +once_cell = "1.21.3" [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/core/src/engine.rs b/crates/core/src/engine.rs index 4534662be..516df6ae7 100644 --- a/crates/core/src/engine.rs +++ b/crates/core/src/engine.rs @@ -31,13 +31,19 @@ use butterflow_scheduler::Scheduler; use butterflow_state::local_adapter::LocalStateAdapter; use butterflow_state::StateAdapter; use codemod_sandbox::sandbox::{ - engine::{language_data::get_extensions_for_language, ExecutionConfig, ExecutionEngine}, + engine::{ + language_data::get_extensions_for_language, ExecutionConfig, ExecutionEngine, + ExecutionStats, + }, filesystem::{RealFileSystem, WalkOptions}, loaders::FileSystemLoader, resolvers::FileSystemResolver, }; use codemod_sandbox::{execute_ast_grep_on_globs, execute_ast_grep_on_globs_with_fixes}; +use once_cell::sync::Lazy; +pub static GLOBAL_STATS: Lazy> = + Lazy::new(|| Mutex::new(ExecutionStats::default())); /// Workflow engine pub struct Engine { /// State adapter for persisting workflow state @@ -1429,6 +1435,9 @@ impl Engine { info!("Modified files: {:?}", stats.files_modified); info!("Unmodified files: {:?}", stats.files_unmodified); info!("Files with errors: {:?}", stats.files_with_errors); + // set global stats + let mut data = GLOBAL_STATS.lock().await; + *data = stats.clone(); // TODO: Consider writing execution stats to state or logs // Similar to AST grep, this could be extended to: diff --git a/crates/telemetry/src/lib.rs b/crates/telemetry/src/lib.rs index 69943afde..16ba48485 100644 --- a/crates/telemetry/src/lib.rs +++ b/crates/telemetry/src/lib.rs @@ -1 +1 @@ -pub mod send_event; \ No newline at end of file +pub mod send_event; diff --git a/crates/telemetry/src/send_event.rs b/crates/telemetry/src/send_event.rs index 33cf1028e..e095be68c 100644 --- a/crates/telemetry/src/send_event.rs +++ b/crates/telemetry/src/send_event.rs @@ -1,7 +1,7 @@ -use std::collections::HashMap; +use async_trait::async_trait; use posthog_rs; use serde::Serialize; -use async_trait::async_trait; +use std::collections::HashMap; #[derive(Debug, Clone)] pub struct TelemetrySenderOptions { @@ -62,7 +62,7 @@ impl TelemetrySender for PostHogSender { let posthog_event = posthog_rs::Event::new( format!("codemod.{}.{}", cloud_role, event.kind), - distinct_id.clone() + distinct_id.clone(), ); if let Err(e) = self.client.capture(posthog_event).await { From 693341c6485dee33411193245a53db2926e1b283 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Mon, 14 Jul 2025 17:27:13 +0330 Subject: [PATCH 03/12] feat: add DISABLE_ANALYTICS check --- crates/cli/src/commands/publish.rs | 28 ++++++++++++++++----------- crates/cli/src/commands/run.rs | 31 ++++++++++++++++++------------ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/crates/cli/src/commands/publish.rs b/crates/cli/src/commands/publish.rs index 4aaf1a749..6222e1b6f 100644 --- a/crates/cli/src/commands/publish.rs +++ b/crates/cli/src/commands/publish.rs @@ -200,17 +200,23 @@ pub async fn handler(args: &Command, telemetry: &PostHogSender) -> Result<()> { let cli_version = env!("CARGO_PKG_VERSION"); - let _ = telemetry.send_event( - BaseEvent { - kind: "codemodPublished".to_string(), - properties: HashMap::from([ - ("codemodName".to_string(), manifest.name.clone()), - ("version".to_string(), manifest.version.clone()), - ("cliVersion".to_string(), cli_version.to_string()), - ]), - }, - None, - ); + if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) + || std::env::var("DISABLE_ANALYTICS").is_err() + { + let _ = telemetry + .send_event( + BaseEvent { + kind: "codemodPublished".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), manifest.name.clone()), + ("version".to_string(), manifest.version.clone()), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ) + .await; + } println!("✅ Package published successfully!"); println!("📦 {}", format_package_name(&response.package)); diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index 9a55ada89..ad167dab7 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -111,18 +111,25 @@ pub async fn handler(engine: &Engine, args: &Command, telemetry: &PostHogSender) &base64::engine::general_purpose::URL_SAFE_NO_PAD, execution_id, ); - let _ = telemetry.send_event( - BaseEvent { - kind: "codemodExecuted".to_string(), - properties: HashMap::from([ - ("codemodName".to_string(), args.package.clone()), - ("executionId".to_string(), execution_id.clone()), - ("fileCount".to_string(), stats.files_modified.to_string()), - ("cliVersion".to_string(), cli_version.to_string()), - ]), - }, - None, - ); + + if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) + || std::env::var("DISABLE_ANALYTICS").is_err() + { + let _ = telemetry + .send_event( + BaseEvent { + kind: "codemodExecuted".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), args.package.clone()), + ("executionId".to_string(), execution_id.clone()), + ("fileCount".to_string(), stats.files_modified.to_string()), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ) + .await; + } Ok(()) } From e342bba660f1c713664128af5c60b3749b0bc930 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Mon, 14 Jul 2025 23:25:40 +0330 Subject: [PATCH 04/12] refactor: clean up for send null logic --- .vscode/settings.json | 3 ++ crates/cli/src/commands/publish.rs | 34 +++++++++---------- crates/cli/src/commands/run.rs | 53 ++++++++++++++++++++++-------- crates/cli/src/main.rs | 34 +++++++++++++------ crates/telemetry/src/lib.rs | 1 + crates/telemetry/src/send_event.rs | 6 +++- crates/telemetry/src/send_null.rs | 15 +++++++++ 7 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 crates/telemetry/src/send_null.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 94f74aa6b..53ed501de 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,5 +27,8 @@ "statusBar.background": "#d6ff62", "statusBar.foreground": "#0B151E", "statusBar.border": "#0B151E" + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/crates/cli/src/commands/publish.rs b/crates/cli/src/commands/publish.rs index 6222e1b6f..771e3ceaa 100644 --- a/crates/cli/src/commands/publish.rs +++ b/crates/cli/src/commands/publish.rs @@ -11,7 +11,7 @@ use tempfile::TempDir; use walkdir::WalkDir; use crate::auth::TokenStorage; -use codemod_telemetry::send_event::{BaseEvent, PostHogSender, TelemetrySender}; +use codemod_telemetry::send_event::{BaseEvent, TelemetrySender}; #[derive(Args, Debug)] pub struct Command { @@ -119,7 +119,7 @@ struct PublishedPackage { published_at: String, } -pub async fn handler(args: &Command, telemetry: &PostHogSender) -> Result<()> { +pub async fn handler(args: &Command, telemetry: &dyn TelemetrySender) -> Result<()> { let package_path = args .path .as_ref() @@ -200,23 +200,19 @@ pub async fn handler(args: &Command, telemetry: &PostHogSender) -> Result<()> { let cli_version = env!("CARGO_PKG_VERSION"); - if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) - || std::env::var("DISABLE_ANALYTICS").is_err() - { - let _ = telemetry - .send_event( - BaseEvent { - kind: "codemodPublished".to_string(), - properties: HashMap::from([ - ("codemodName".to_string(), manifest.name.clone()), - ("version".to_string(), manifest.version.clone()), - ("cliVersion".to_string(), cli_version.to_string()), - ]), - }, - None, - ) - .await; - } + let _ = telemetry + .send_event( + BaseEvent { + kind: "codemodPublished".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), manifest.name.clone()), + ("version".to_string(), manifest.version.clone()), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ) + .await; println!("✅ Package published successfully!"); println!("📦 {}", format_package_name(&response.package)); diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index ad167dab7..f42ae34cc 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -13,7 +13,7 @@ use crate::workflow_runner::{run_workflow, WorkflowRunConfig}; use butterflow_core::engine::{Engine, GLOBAL_STATS}; use butterflow_core::registry::{RegistryClient, RegistryConfig, RegistryError}; use codemod_sandbox::sandbox::engine::ExecutionStats; -use codemod_telemetry::send_event::{BaseEvent, PostHogSender, TelemetrySender}; +use codemod_telemetry::send_event::{BaseEvent, TelemetrySender}; #[derive(Args, Debug)] pub struct Command { @@ -46,7 +46,11 @@ pub struct Command { allow_dirty: bool, } -pub async fn handler(engine: &Engine, args: &Command, telemetry: &PostHogSender) -> Result<()> { +pub async fn handler( + engine: &Engine, + args: &Command, + telemetry: &dyn TelemetrySender, +) -> Result<()> { // Create auth provider let auth_provider = CliAuthProvider::new()?; @@ -103,34 +107,55 @@ pub async fn handler(engine: &Engine, args: &Command, telemetry: &PostHogSender) &args.args, args.dry_run, ) - .await?; + .await; let cli_version = env!("CARGO_PKG_VERSION"); - let execution_id: [u8; 20] = rand::thread_rng().gen(); - let execution_id = base64::Engine::encode( - &base64::engine::general_purpose::URL_SAFE_NO_PAD, - execution_id, - ); - if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) - || std::env::var("DISABLE_ANALYTICS").is_err() - { + if let Err(e) = stats { let _ = telemetry .send_event( BaseEvent { - kind: "codemodExecuted".to_string(), + kind: "failedToExecuteCommand".to_string(), properties: HashMap::from([ ("codemodName".to_string(), args.package.clone()), - ("executionId".to_string(), execution_id.clone()), - ("fileCount".to_string(), stats.files_modified.to_string()), ("cliVersion".to_string(), cli_version.to_string()), + ( + "commandName".to_string(), + "codemod.executeCodemod".to_string(), + ), ]), }, None, ) .await; + return Err(anyhow::anyhow!("Error executing codemod: {}", e)); } + let cli_version = env!("CARGO_PKG_VERSION"); + let execution_id: [u8; 20] = rand::thread_rng().gen(); + let execution_id = base64::Engine::encode( + &base64::engine::general_purpose::URL_SAFE_NO_PAD, + execution_id, + ); + + let _ = telemetry + .send_event( + BaseEvent { + kind: "codemodExecuted".to_string(), + properties: HashMap::from([ + ("codemodName".to_string(), args.package.clone()), + ("executionId".to_string(), execution_id.clone()), + ( + "fileCount".to_string(), + stats.unwrap().files_modified.to_string(), + ), + ("cliVersion".to_string(), cli_version.to_string()), + ]), + }, + None, + ) + .await; + Ok(()) } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 97bb28272..72861e63c 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -11,7 +11,10 @@ mod engine; mod workflow_runner; use ascii_art::print_ascii_art; use auth::TokenStorage; -use codemod_telemetry::send_event::{PostHogSender, TelemetrySenderOptions}; +use codemod_telemetry::{ + send_event::{PostHogSender, TelemetrySender, TelemetrySenderOptions}, + send_null::NullSender, +}; #[derive(Parser)] #[command(name = "codemod")] @@ -142,7 +145,7 @@ fn is_package_name(arg: &str) -> bool { async fn handle_implicit_run_command( engine: &butterflow_core::engine::Engine, trailing_args: Vec, - telemetry_sender: &PostHogSender, + telemetry_sender: &dyn TelemetrySender, ) -> Result { if trailing_args.is_empty() { return Ok(false); @@ -199,11 +202,20 @@ async fn main() -> Result<()> { let auth = storage.load_auth("https://app.codemod.com")?; let auth = auth.unwrap(); - let telemetry_sender = PostHogSender::new(TelemetrySenderOptions { - distinct_id: auth.user.id.clone(), - cloud_role: "cli".to_string(), - }) - .await; + let telemetry_sender: Box = + if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) + || std::env::var("DISABLE_ANALYTICS").is_err() + { + Box::new( + PostHogSender::new(TelemetrySenderOptions { + distinct_id: auth.user.id.clone(), + cloud_role: "CLI".to_string(), + }) + .await, + ) + } else { + Box::new(NullSender {}) + }; // Handle command or implicit run match &cli.command { @@ -248,13 +260,13 @@ async fn main() -> Result<()> { commands::whoami::handler(args).await?; } Some(Commands::Publish(args)) => { - commands::publish::handler(args, &telemetry_sender).await?; + commands::publish::handler(args, telemetry_sender.as_ref()).await?; } Some(Commands::Search(args)) => { commands::search::handler(args).await?; } Some(Commands::Run(args)) => { - commands::run::handler(&engine, args, &telemetry_sender).await?; + commands::run::handler(&engine, args, telemetry_sender.as_ref()).await?; } Some(Commands::Unpublish(args)) => { commands::unpublish::handler(args).await?; @@ -264,7 +276,9 @@ async fn main() -> Result<()> { } None => { // Try to parse as implicit run command - if !handle_implicit_run_command(&engine, cli.trailing_args, &telemetry_sender).await? { + if !handle_implicit_run_command(&engine, cli.trailing_args, telemetry_sender.as_ref()) + .await? + { // No valid subcommand or package name provided, show help print_ascii_art(); eprintln!("No command provided. Use --help for usage information."); diff --git a/crates/telemetry/src/lib.rs b/crates/telemetry/src/lib.rs index 16ba48485..e0ccee030 100644 --- a/crates/telemetry/src/lib.rs +++ b/crates/telemetry/src/lib.rs @@ -1 +1,2 @@ pub mod send_event; +pub mod send_null; diff --git a/crates/telemetry/src/send_event.rs b/crates/telemetry/src/send_event.rs index e095be68c..76acc7ce9 100644 --- a/crates/telemetry/src/send_event.rs +++ b/crates/telemetry/src/send_event.rs @@ -60,11 +60,15 @@ impl TelemetrySender for PostHogSender { .and_then(|o| o.cloud_role.clone()) .unwrap_or_else(|| self.options.cloud_role.clone()); - let posthog_event = posthog_rs::Event::new( + let mut posthog_event = posthog_rs::Event::new( format!("codemod.{}.{}", cloud_role, event.kind), distinct_id.clone(), ); + for (key, value) in event.properties { + posthog_event.insert_prop(key, value).unwrap(); + } + if let Err(e) = self.client.capture(posthog_event).await { eprintln!("Failed to send PostHog event: {e}"); } diff --git a/crates/telemetry/src/send_null.rs b/crates/telemetry/src/send_null.rs new file mode 100644 index 000000000..85268698c --- /dev/null +++ b/crates/telemetry/src/send_null.rs @@ -0,0 +1,15 @@ +use crate::send_event::{BaseEvent, PartialTelemetrySenderOptions, TelemetrySender}; +use async_trait::async_trait; + +pub struct NullSender; + +#[async_trait] +impl TelemetrySender for NullSender { + async fn send_event( + &self, + _event: BaseEvent, + _options_override: Option, + ) { + // Do nothing + } +} From 95d4b64b049ca79dc9f826f1a7d2a677f8c89828 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Fri, 18 Jul 2025 01:19:35 +0330 Subject: [PATCH 05/12] feat: add error handeling for add property in posthog event send --- crates/telemetry/src/send_event.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/telemetry/src/send_event.rs b/crates/telemetry/src/send_event.rs index 76acc7ce9..de73abab8 100644 --- a/crates/telemetry/src/send_event.rs +++ b/crates/telemetry/src/send_event.rs @@ -66,7 +66,9 @@ impl TelemetrySender for PostHogSender { ); for (key, value) in event.properties { - posthog_event.insert_prop(key, value).unwrap(); + if let Err(e) = posthog_event.insert_prop(key, value) { + eprintln!("Failed to insert property into PostHog event: {e}"); + } } if let Err(e) = self.client.capture(posthog_event).await { From ec12c1e3a8a1d0da1401fa2339b75199763851f4 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Fri, 18 Jul 2025 01:21:55 +0330 Subject: [PATCH 06/12] fix: remove settings changes --- .vscode/settings.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 53ed501de..94f74aa6b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -27,8 +27,5 @@ "statusBar.background": "#d6ff62", "statusBar.foreground": "#0B151E", "statusBar.border": "#0B151E" - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" } } From 8d27b7200f51d1a9a0fa68144e7268520437453e Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Fri, 18 Jul 2025 15:57:48 +0330 Subject: [PATCH 07/12] refactor: get POSTHOG_API_KEY from env before build --- crates/telemetry/Cargo.toml | 1 + crates/telemetry/src/build.rs | 4 ++++ crates/telemetry/src/send_event.rs | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 crates/telemetry/src/build.rs diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml index 99813d3c6..1885a3cf8 100644 --- a/crates/telemetry/Cargo.toml +++ b/crates/telemetry/Cargo.toml @@ -8,6 +8,7 @@ repository.workspace = true license.workspace = true rust-version.workspace = true version.workspace = true +build = "src/build.rs" [dependencies] async-trait.workspace = true diff --git a/crates/telemetry/src/build.rs b/crates/telemetry/src/build.rs new file mode 100644 index 000000000..51fcc14c3 --- /dev/null +++ b/crates/telemetry/src/build.rs @@ -0,0 +1,4 @@ +fn main() { + let api_key = std::env::var("POSTHOG_API_KEY").unwrap_or_else(|_| "".to_string()); + println!("cargo:rustc-env=POSTHOG_API_KEY={api_key}"); +} diff --git a/crates/telemetry/src/send_event.rs b/crates/telemetry/src/send_event.rs index de73abab8..c96be86e0 100644 --- a/crates/telemetry/src/send_event.rs +++ b/crates/telemetry/src/send_event.rs @@ -2,6 +2,7 @@ use async_trait::async_trait; use posthog_rs; use serde::Serialize; use std::collections::HashMap; +use std::env; #[derive(Debug, Clone)] pub struct TelemetrySenderOptions { @@ -36,9 +37,11 @@ pub struct PostHogSender { options: TelemetrySenderOptions, } +pub const POSTHOG_API_KEY: &str = env!("POSTHOG_API_KEY"); + impl PostHogSender { pub async fn new(options: TelemetrySenderOptions) -> Self { - let client = posthog_rs::client("phc_nGWKWP3t1fcNFqGi6UdstXjMf0fxx7SBeohHPSS6d2Y").await; + let client = posthog_rs::client(POSTHOG_API_KEY).await; Self { client, options } } } From 37c5fa8fe148d21d2601eeebd1ca11520fc4abb4 Mon Sep 17 00:00:00 2001 From: Amirabbas Ghasemi Date: Fri, 18 Jul 2025 16:32:59 +0330 Subject: [PATCH 08/12] fix: fix distinct_id for posthog --- Cargo.lock | 37 ++++++++++++++++++++++++++++++++++++- crates/cli/Cargo.toml | 3 +++ crates/cli/src/main.rs | 23 ++++++++++++++++------- 3 files changed, 55 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d394c69f..1696a5a35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -777,12 +777,14 @@ dependencies = [ "dirs", "env_logger", "flate2", + "hostname", "humantime", "hyper 0.14.32", "hyper-rustls 0.24.2", "inquire", "libtest-mimic", "log", + "machine-uid", "num_cpus", "oauth2", "open", @@ -807,6 +809,7 @@ dependencies = [ "urlencoding", "uuid", "walkdir", + "whoami", ] [[package]] @@ -1803,6 +1806,17 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "hostname" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" +dependencies = [ + "cfg-if", + "libc", + "windows-link", +] + [[package]] name = "hstr" version = "1.0.0" @@ -2882,6 +2896,16 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "machine-uid" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4506fa0abb0a2ea93f5862f55973da0a662d2ad0e98f337a1c5aac657f0892" +dependencies = [ + "libc", + "winreg 0.52.0", +] + [[package]] name = "md-5" version = "0.10.6" @@ -3895,7 +3919,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys 0.3.77 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.25.4", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -6897,6 +6921,7 @@ checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ "redox_syscall", "wasite", + "web-sys 0.3.77 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7312,6 +7337,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 782365c10..a5485feb8 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -60,6 +60,9 @@ ast-grep-language.workspace = true tabled = "0.20.0" posthog-rs = "0.2.2" async-trait.workspace = true +hostname = "0.4.0" +whoami = "1.6.0" +machine-uid = "0.5.3" [features] diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 72861e63c..c68296916 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,7 +1,9 @@ use anyhow::Result; use clap::{Args, Parser, Subcommand}; +use hostname::get as get_hostname; use log::info; - +use machine_uid::get as get_machine_uid; +use sha2::{Digest, Sha256}; mod ascii_art; mod auth; mod auth_provider; @@ -10,12 +12,13 @@ mod dirty_git_check; mod engine; mod workflow_runner; use ascii_art::print_ascii_art; -use auth::TokenStorage; use codemod_telemetry::{ send_event::{PostHogSender, TelemetrySender, TelemetrySenderOptions}, send_null::NullSender, }; +use crate::auth::TokenStorage; + #[derive(Parser)] #[command(name = "codemod")] #[command( @@ -184,7 +187,7 @@ async fn handle_implicit_run_command( #[tokio::main] async fn main() -> Result<()> { // Initialize logger - env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); + env_logger::init_from_env(env_logger::Env::default().default_filter_or("error")); // Parse command line arguments let cli = Cli::parse(); @@ -198,17 +201,23 @@ async fn main() -> Result<()> { // Create engine let engine = engine::create_engine()?; - let storage = TokenStorage::new()?; - let auth = storage.load_auth("https://app.codemod.com")?; - let auth = auth.unwrap(); let telemetry_sender: Box = if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) || std::env::var("DISABLE_ANALYTICS").is_err() { + let storage = TokenStorage::new()?; + let config = storage.load_config()?; + + let auth = storage.get_auth_for_registry(&config.default_registry)?; + + let distrinct_id = auth + .map(|auth| auth.user.id) + .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); + Box::new( PostHogSender::new(TelemetrySenderOptions { - distinct_id: auth.user.id.clone(), + distinct_id: distrinct_id, cloud_role: "CLI".to_string(), }) .await, From 5a90951cd5120d08dab6ebfc5d47c7a682b10bf4 Mon Sep 17 00:00:00 2001 From: Mohamad Mohebifar Date: Fri, 18 Jul 2025 22:35:48 -0700 Subject: [PATCH 09/12] chore: add POSTHOG_API_KEY environment variable to build step in cargo-release workflow --- .github/workflows/cargo-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/cargo-release.yml b/.github/workflows/cargo-release.yml index 3ce154664..46b88e513 100644 --- a/.github/workflows/cargo-release.yml +++ b/.github/workflows/cargo-release.yml @@ -77,6 +77,8 @@ jobs: - name: Build run: | cargo build --release -p codemod --target ${{ matrix.target }} + env: + POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} - name: Chmod binary run: | From 580801a6fd729e58387844aaf7730eb1c3ce93e9 Mon Sep 17 00:00:00 2001 From: Mohamad Mohebifar Date: Fri, 18 Jul 2025 22:40:13 -0700 Subject: [PATCH 10/12] refactor: replace once_cell with OnceLock for global stats management --- Cargo.lock | 1 - crates/cli/src/commands/run.rs | 7 ++++++- crates/core/Cargo.toml | 1 - crates/core/src/engine.rs | 8 ++++---- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1696a5a35..66b7c1279 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -512,7 +512,6 @@ dependencies = [ "dirs", "flate2", "log", - "once_cell", "regex", "reqwest 0.12.15", "serde", diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index f42ae34cc..feda031ef 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -6,6 +6,7 @@ use rand::Rng; use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::process::Command as ProcessCommand; +use tokio::sync::Mutex; use crate::auth_provider::CliAuthProvider; use crate::dirty_git_check; @@ -231,7 +232,11 @@ async fn execute_codemod( // Run workflow using the extracted workflow runner run_workflow(engine, config).await?; - let stats = GLOBAL_STATS.lock().await.clone(); + let stats = GLOBAL_STATS + .get_or_init(|| Mutex::new(ExecutionStats::default())) + .lock() + .await + .clone(); Ok(stats) } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index f09bcda62..69f7bd67f 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -31,7 +31,6 @@ tar = { workspace = true } tempfile = { workspace = true } walkdir = { workspace = true } dirs = { workspace = true } -once_cell = "1.21.3" [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/core/src/engine.rs b/crates/core/src/engine.rs index 516df6ae7..98eadfe55 100644 --- a/crates/core/src/engine.rs +++ b/crates/core/src/engine.rs @@ -40,10 +40,9 @@ use codemod_sandbox::sandbox::{ resolvers::FileSystemResolver, }; use codemod_sandbox::{execute_ast_grep_on_globs, execute_ast_grep_on_globs_with_fixes}; -use once_cell::sync::Lazy; +use std::sync::OnceLock; -pub static GLOBAL_STATS: Lazy> = - Lazy::new(|| Mutex::new(ExecutionStats::default())); +pub static GLOBAL_STATS: OnceLock> = OnceLock::new(); /// Workflow engine pub struct Engine { /// State adapter for persisting workflow state @@ -1436,7 +1435,8 @@ impl Engine { info!("Unmodified files: {:?}", stats.files_unmodified); info!("Files with errors: {:?}", stats.files_with_errors); // set global stats - let mut data = GLOBAL_STATS.lock().await; + let data = GLOBAL_STATS.get_or_init(|| Mutex::new(ExecutionStats::default())); + let mut data = data.lock().await; *data = stats.clone(); // TODO: Consider writing execution stats to state or logs From 881c322e7a937d45ebd4ea2927a75cb9409b6be3 Mon Sep 17 00:00:00 2001 From: Mohamad Mohebifar Date: Fri, 18 Jul 2025 23:04:06 -0700 Subject: [PATCH 11/12] chore: update posthog-rs dependency and improve analytics handling --- Cargo.lock | 16 ++-------------- crates/cli/Cargo.toml | 2 +- crates/cli/src/commands/run.rs | 7 +++---- crates/cli/src/main.rs | 8 ++++---- crates/telemetry/Cargo.toml | 2 +- crates/telemetry/{src => }/build.rs | 0 6 files changed, 11 insertions(+), 24 deletions(-) rename crates/telemetry/{src => }/build.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 66b7c1279..021f0b46f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -788,7 +788,7 @@ dependencies = [ "oauth2", "open", "percent-encoding", - "posthog-rs 0.2.2", + "posthog-rs", "rand 0.8.5", "regex", "reqwest 0.11.27", @@ -856,7 +856,7 @@ name = "codemod-telemetry" version = "1.0.0-rc.12" dependencies = [ "async-trait", - "posthog-rs 0.3.7", + "posthog-rs", "serde", ] @@ -3524,18 +3524,6 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "posthog-rs" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad1b35ffe50419992615288c40ee90fbf30da4c6faf251414675ea64e1cdfa3" -dependencies = [ - "chrono", - "reqwest 0.11.27", - "serde", - "serde_json", -] - [[package]] name = "posthog-rs" version = "0.3.7" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index a5485feb8..5315b7568 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -58,7 +58,7 @@ libtest-mimic = "0.8" similar = "2.0" ast-grep-language.workspace = true tabled = "0.20.0" -posthog-rs = "0.2.2" +posthog-rs = "0.3.7" async-trait.workspace = true hostname = "0.4.0" whoami = "1.6.0" diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index feda031ef..230fa989b 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -132,6 +132,8 @@ pub async fn handler( return Err(anyhow::anyhow!("Error executing codemod: {}", e)); } + let stats = stats.unwrap(); + let cli_version = env!("CARGO_PKG_VERSION"); let execution_id: [u8; 20] = rand::thread_rng().gen(); let execution_id = base64::Engine::encode( @@ -146,10 +148,7 @@ pub async fn handler( properties: HashMap::from([ ("codemodName".to_string(), args.package.clone()), ("executionId".to_string(), execution_id.clone()), - ( - "fileCount".to_string(), - stats.unwrap().files_modified.to_string(), - ), + ("fileCount".to_string(), stats.files_modified.to_string()), ("cliVersion".to_string(), cli_version.to_string()), ]), }, diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index c68296916..20f496841 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -203,9 +203,11 @@ async fn main() -> Result<()> { let engine = engine::create_engine()?; let telemetry_sender: Box = - if std::env::var("DISABLE_ANALYTICS") == Ok("false".to_string()) - || std::env::var("DISABLE_ANALYTICS").is_err() + if std::env::var("DISABLE_ANALYTICS") == Ok("true".to_string()) + || std::env::var("DISABLE_ANALYTICS") == Ok("1".to_string()) { + Box::new(NullSender {}) + } else { let storage = TokenStorage::new()?; let config = storage.load_config()?; @@ -222,8 +224,6 @@ async fn main() -> Result<()> { }) .await, ) - } else { - Box::new(NullSender {}) }; // Handle command or implicit run diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml index 1885a3cf8..2a653b9e9 100644 --- a/crates/telemetry/Cargo.toml +++ b/crates/telemetry/Cargo.toml @@ -8,7 +8,7 @@ repository.workspace = true license.workspace = true rust-version.workspace = true version.workspace = true -build = "src/build.rs" +build = "build.rs" [dependencies] async-trait.workspace = true diff --git a/crates/telemetry/src/build.rs b/crates/telemetry/build.rs similarity index 100% rename from crates/telemetry/src/build.rs rename to crates/telemetry/build.rs From 6f7b233a50cec282715529634da9acea9bd93b0b Mon Sep 17 00:00:00 2001 From: Mohamad Mohebifar Date: Fri, 18 Jul 2025 23:44:25 -0700 Subject: [PATCH 12/12] chore: remove unused dependencies (hostname, machine-uid, whoami) --- Cargo.lock | 37 +--------------------------------- crates/cli/Cargo.toml | 4 ---- crates/cli/src/commands/run.rs | 2 +- crates/cli/src/main.rs | 7 ++----- 4 files changed, 4 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 021f0b46f..52022a965 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,14 +776,12 @@ dependencies = [ "dirs", "env_logger", "flate2", - "hostname", "humantime", "hyper 0.14.32", "hyper-rustls 0.24.2", "inquire", "libtest-mimic", "log", - "machine-uid", "num_cpus", "oauth2", "open", @@ -808,7 +806,6 @@ dependencies = [ "urlencoding", "uuid", "walkdir", - "whoami", ] [[package]] @@ -1805,17 +1802,6 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "hostname" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" -dependencies = [ - "cfg-if", - "libc", - "windows-link", -] - [[package]] name = "hstr" version = "1.0.0" @@ -2895,16 +2881,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "machine-uid" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4506fa0abb0a2ea93f5862f55973da0a662d2ad0e98f337a1c5aac657f0892" -dependencies = [ - "libc", - "winreg 0.52.0", -] - [[package]] name = "md-5" version = "0.10.6" @@ -3906,7 +3882,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys 0.3.77 (registry+https://github.com/rust-lang/crates.io-index)", "webpki-roots 0.25.4", - "winreg 0.50.0", + "winreg", ] [[package]] @@ -6908,7 +6884,6 @@ checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ "redox_syscall", "wasite", - "web-sys 0.3.77 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -7324,16 +7299,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "wit-bindgen-rt" version = "0.39.0" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 5315b7568..1d4ec6e1a 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -60,10 +60,6 @@ ast-grep-language.workspace = true tabled = "0.20.0" posthog-rs = "0.3.7" async-trait.workspace = true -hostname = "0.4.0" -whoami = "1.6.0" -machine-uid = "0.5.3" - [features] default = [] diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index 230fa989b..b47cd2e99 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -129,7 +129,7 @@ pub async fn handler( None, ) .await; - return Err(anyhow::anyhow!("Error executing codemod: {}", e)); + return Err(e); } let stats = stats.unwrap(); diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 20f496841..99953b051 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,9 +1,6 @@ use anyhow::Result; use clap::{Args, Parser, Subcommand}; -use hostname::get as get_hostname; use log::info; -use machine_uid::get as get_machine_uid; -use sha2::{Digest, Sha256}; mod ascii_art; mod auth; mod auth_provider; @@ -213,13 +210,13 @@ async fn main() -> Result<()> { let auth = storage.get_auth_for_registry(&config.default_registry)?; - let distrinct_id = auth + let distinct_id = auth .map(|auth| auth.user.id) .unwrap_or_else(|| uuid::Uuid::new_v4().to_string()); Box::new( PostHogSender::new(TelemetrySenderOptions { - distinct_id: distrinct_id, + distinct_id, cloud_role: "CLI".to_string(), }) .await, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy