(root: Option<&Path>, event: &str, mut fields: serde_json::Value)
| 98 | } |
| 99 | |
| 100 | fn record_hook_analytics(root: Option<&Path>, event: &str, mut fields: serde_json::Value) { |
| 101 | let Some(path) = hook_analytics_path(root) else { |
| 102 | return; |
| 103 | }; |
| 104 | let Some(fields) = fields.as_object_mut() else { |
| 105 | return; |
| 106 | }; |
| 107 | // Attribute the row to its project even when it lands in the user-level |
| 108 | // fallback file, so readers can re-join the split streams per project. |
| 109 | if let Some(root) = root { |
| 110 | fields.insert( |
| 111 | "project_root".to_string(), |
| 112 | serde_json::Value::String(root.display().to_string()), |
| 113 | ); |
| 114 | } |
| 115 | fields.insert( |
| 116 | "event".to_string(), |
| 117 | serde_json::Value::String(event.to_string()), |
| 118 | ); |
| 119 | fields.insert( |
| 120 | "ts_unix_ms".to_string(), |
| 121 | serde_json::Value::Number(serde_json::Number::from(now_unix_millis())), |
| 122 | ); |
| 123 | let Ok(line) = serde_json::to_string(&fields) else { |
| 124 | return; |
| 125 | }; |
| 126 | append_private_jsonl(&path, &line); |
| 127 | } |
| 128 | |
| 129 | fn hook_analytics_path(root: Option<&Path>) -> Option<PathBuf> { |
| 130 | match root { |
no test coverage detected