Add events for identifying node projects (#13078)

Joseph T. Lyons created

Release Notes:

- N/A

Change summary

crates/project/src/project.rs | 75 ++++++++++++++++++++++++++++++------
1 file changed, 62 insertions(+), 13 deletions(-)

Detailed changes

crates/project/src/project.rs 🔗

@@ -230,7 +230,40 @@ pub struct Project {
     hosted_project_id: Option<ProjectId>,
     dev_server_project_id: Option<client::DevServerProjectId>,
     search_history: SearchHistory,
-    yarn_worktree_ids_reported: Vec<WorktreeId>,
+    telemetry_worktree_id_map: TelemetryWorktreeIdMap,
+}
+
+#[derive(Debug)]
+struct TelemetryWorktreeIdMap(HashMap<String, ProjectTypeTelemetry>);
+
+impl Default for TelemetryWorktreeIdMap {
+    fn default() -> Self {
+        Self(HashMap::from_iter([
+            (
+                "yarn.lock".to_string(),
+                ProjectTypeTelemetry::new("yarn".to_string()),
+            ),
+            (
+                "package.json".to_string(),
+                ProjectTypeTelemetry::new("node".to_string()),
+            ),
+        ]))
+    }
+}
+
+#[derive(Debug)]
+struct ProjectTypeTelemetry {
+    name: String,
+    worktree_ids_reported: HashSet<WorktreeId>,
+}
+
+impl ProjectTypeTelemetry {
+    fn new(name: String) -> Self {
+        Self {
+            name,
+            worktree_ids_reported: HashSet::default(),
+        }
+    }
 }
 
 pub enum LanguageServerToQuery {
@@ -790,7 +823,7 @@ impl Project {
                 hosted_project_id: None,
                 dev_server_project_id: None,
                 search_history: Self::new_search_history(),
-                yarn_worktree_ids_reported: Vec::new(),
+                telemetry_worktree_id_map: TelemetryWorktreeIdMap::default(),
             }
         })
     }
@@ -955,7 +988,7 @@ impl Project {
                     .dev_server_project_id
                     .map(|dev_server_project_id| DevServerProjectId(dev_server_project_id)),
                 search_history: Self::new_search_history(),
-                yarn_worktree_ids_reported: Vec::new(),
+                telemetry_worktree_id_map: TelemetryWorktreeIdMap::default(),
             };
             this.set_role(role, cx);
             for worktree in worktrees {
@@ -7758,7 +7791,7 @@ impl Project {
                         changes.clone(),
                     ));
 
-                    this.report_yarn_project(&worktree, changes, cx);
+                    this.report_project_events(&worktree, changes, cx);
                 }
                 worktree::Event::UpdatedGitRepositories(updated_repos) => {
                     if is_local {
@@ -7811,7 +7844,7 @@ impl Project {
         self.metadata_changed(cx);
     }
 
-    fn report_yarn_project(
+    fn report_project_events(
         &mut self,
         worktree: &Model<Worktree>,
         updated_entries_set: &UpdatedEntriesSet,
@@ -7819,21 +7852,37 @@ impl Project {
     ) {
         let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
 
-        if !self.yarn_worktree_ids_reported.contains(&worktree_id) {
-            let is_yarn_project = updated_entries_set.iter().any(|(path, _, _)| {
+        let client = self.client();
+
+        for (project_file_name, project_type_telemetry) in
+            self.telemetry_worktree_id_map.0.iter_mut()
+        {
+            if project_type_telemetry
+                .worktree_ids_reported
+                .contains(&worktree_id)
+            {
+                continue;
+            }
+
+            let project_file_found = updated_entries_set.iter().any(|(path, _, _)| {
                 path.as_ref()
                     .file_name()
                     .and_then(|name| name.to_str())
-                    .map(|name_str| name_str == "yarn.lock")
+                    .map(|name_str| name_str == project_file_name)
                     .unwrap_or(false)
             });
 
-            if is_yarn_project {
-                self.client()
-                    .telemetry()
-                    .report_app_event("open yarn project".to_string());
-                self.yarn_worktree_ids_reported.push(worktree_id);
+            if !project_file_found {
+                continue;
             }
+
+            client
+                .telemetry()
+                .report_app_event(format!("open {} project", project_type_telemetry.name));
+
+            project_type_telemetry
+                .worktree_ids_reported
+                .insert(worktree_id);
         }
     }