Add event for yarn project identification (#12785)

Joseph T. Lyons created

Report a `open yarn project` `app_event` for each worktree where
`yarn.lock` is found and only report it once per session.

Release Notes:

- N/A

Change summary

crates/project/src/project.rs | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)

Detailed changes

crates/project/src/project.rs 🔗

@@ -217,6 +217,7 @@ pub struct Project {
     hosted_project_id: Option<ProjectId>,
     dev_server_project_id: Option<client::DevServerProjectId>,
     search_history: SearchHistory,
+    yarn_worktree_ids_reported: Vec<WorktreeId>,
 }
 
 pub enum LanguageServerToQuery {
@@ -773,6 +774,7 @@ impl Project {
                 hosted_project_id: None,
                 dev_server_project_id: None,
                 search_history: Self::new_search_history(),
+                yarn_worktree_ids_reported: Vec::new(),
             }
         })
     }
@@ -930,6 +932,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(),
             };
             this.set_role(role, cx);
             for worktree in worktrees {
@@ -7592,6 +7595,8 @@ impl Project {
                         worktree.read(cx).id(),
                         changes.clone(),
                     ));
+
+                    this.report_yarn_project(&worktree, changes, cx);
                 }
                 worktree::Event::UpdatedGitRepositories(updated_repos) => {
                     if is_local {
@@ -7644,6 +7649,32 @@ impl Project {
         self.metadata_changed(cx);
     }
 
+    fn report_yarn_project(
+        &mut self,
+        worktree: &Model<Worktree>,
+        updated_entries_set: &UpdatedEntriesSet,
+        cx: &mut ModelContext<Self>,
+    ) {
+        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, _, _)| {
+                path.as_ref()
+                    .file_name()
+                    .and_then(|name| name.to_str())
+                    .map(|name_str| name_str == "yarn.lock")
+                    .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);
+            }
+        }
+    }
+
     fn update_local_worktree_buffers(
         &mut self,
         worktree_handle: &Model<Worktree>,