@anysphere/file-service 0.0.0-d50aa568 → 0.0.0-d785e254

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Cargo.toml CHANGED
@@ -9,6 +9,7 @@ crate-type = ["cdylib"]
9
9
  [features]
10
10
  default = ["windows-subsystem"]
11
11
  windows-subsystem = []
12
+ debugfile = []
12
13
 
13
14
  [dependencies]
14
15
  # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
@@ -28,6 +29,9 @@ binaryornot = "1.0.0"
28
29
  dunce = "1.0.1"
29
30
  encoding_rs = "0.8.33"
30
31
 
32
+ [target.'cfg(not(target_os = "linux"))'.dependencies]
33
+ tracing-axiom = "0.4"
34
+
31
35
  [build-dependencies]
32
36
  napi-build = "2.0.1"
33
37
  tonic-build = "0.9.2"
package/index.d.ts CHANGED
@@ -5,6 +5,7 @@
5
5
 
6
6
  export class MerkleClient {
7
7
  constructor(absoluteRootDirectory: string)
8
+ isTooBig(maxFiles: number, gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<boolean>
8
9
  init(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
9
10
  computeMerkleTree(gitIgnoredFiles: Array<string>, isGitRepo: boolean): Promise<void>
10
11
  updateFile(filePath: string): Promise<void>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anysphere/file-service",
3
- "version": "0.0.0-d50aa568",
3
+ "version": "0.0.0-d785e254",
4
4
  "main": "index.js",
5
5
  "types": "index.d.ts",
6
6
  "napi": {
@@ -36,12 +36,12 @@
36
36
  "version": "napi version"
37
37
  },
38
38
  "optionalDependencies": {
39
- "@anysphere/file-service-win32-x64-msvc": "0.0.0-d50aa568",
40
- "@anysphere/file-service-darwin-x64": "0.0.0-d50aa568",
41
- "@anysphere/file-service-linux-x64-gnu": "0.0.0-d50aa568",
42
- "@anysphere/file-service-darwin-arm64": "0.0.0-d50aa568",
43
- "@anysphere/file-service-win32-arm64-msvc": "0.0.0-d50aa568",
44
- "@anysphere/file-service-darwin-universal": "0.0.0-d50aa568",
45
- "@anysphere/file-service-linux-arm64-gnu": "0.0.0-d50aa568"
39
+ "@anysphere/file-service-win32-x64-msvc": "0.0.0-d785e254",
40
+ "@anysphere/file-service-darwin-x64": "0.0.0-d785e254",
41
+ "@anysphere/file-service-linux-x64-gnu": "0.0.0-d785e254",
42
+ "@anysphere/file-service-darwin-arm64": "0.0.0-d785e254",
43
+ "@anysphere/file-service-win32-arm64-msvc": "0.0.0-d785e254",
44
+ "@anysphere/file-service-darwin-universal": "0.0.0-d785e254",
45
+ "@anysphere/file-service-linux-arm64-gnu": "0.0.0-d785e254"
46
46
  }
47
47
  }
package/src/lib.rs CHANGED
@@ -2,15 +2,14 @@
2
2
  #![deny(clippy::all)]
3
3
  #![deny(unsafe_op_in_unsafe_fn)]
4
4
  pub mod file_utils;
5
+ pub mod logger;
5
6
  pub mod merkle_tree;
6
7
 
7
- use std::{vec, collections::HashSet};
8
+ use std::{collections::HashSet, vec};
8
9
 
9
10
  use anyhow::Context;
10
11
  use merkle_tree::{LocalConstruction, MerkleTree};
11
- use tracing::{info, Level};
12
- use tracing_appender::rolling::{RollingFileAppender, Rotation};
13
- use tracing_subscriber::fmt;
12
+ use tracing::{debug, info};
14
13
 
15
14
  #[macro_use]
16
15
  extern crate napi_derive;
@@ -19,30 +18,14 @@ extern crate napi_derive;
19
18
  pub struct MerkleClient {
20
19
  tree: MerkleTree,
21
20
  absolute_root_directory: String,
22
- _guard: tracing_appender::non_blocking::WorkerGuard,
23
- }
24
-
25
- pub fn init_logger() -> tracing_appender::non_blocking::WorkerGuard {
26
- let file_appender =
27
- RollingFileAppender::new(Rotation::NEVER, "./", "rust_log.txt");
28
- let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
29
- let subscriber = fmt::Subscriber::builder()
30
- .with_max_level(Level::TRACE)
31
- .with_writer(non_blocking)
32
- .with_ansi(false)
33
- .with_line_number(true)
34
- .finish();
35
-
36
- let _ = tracing::subscriber::set_global_default(subscriber);
37
-
38
- _guard
21
+ _guard: Option<logger::GuardType>,
39
22
  }
40
23
 
41
24
  #[napi]
42
25
  impl MerkleClient {
43
26
  #[napi(constructor)]
44
27
  pub fn new(absolute_root_directory: String) -> MerkleClient {
45
- let _guard = init_logger();
28
+ let _guard = logger::init_logger();
46
29
 
47
30
  // let canonical_root_directory = std::path::Path::new(&absolute_root_directory);
48
31
  // use dunce::canonicalize;
@@ -61,14 +44,74 @@ impl MerkleClient {
61
44
  }
62
45
  }
63
46
 
47
+ #[napi]
48
+ pub async fn is_too_big(
49
+ &self,
50
+ max_files: i32,
51
+ git_ignored_files: Vec<String>,
52
+ is_git_repo: bool,
53
+ ) -> bool {
54
+ let git_ignored_set =
55
+ HashSet::<String>::from_iter(git_ignored_files.into_iter());
56
+ let mut num_files = 0;
57
+ let mut dirs_to_check = vec![self.absolute_root_directory.clone()];
58
+
59
+ while let Some(dir) = dirs_to_check.pop() {
60
+ info!("dir: {:?}", dir);
61
+ let mut entries = match tokio::fs::read_dir(&dir).await {
62
+ Ok(entries) => entries,
63
+ Err(_) => continue,
64
+ };
65
+ if num_files > max_files {
66
+ return true;
67
+ }
68
+
69
+
70
+ while let Some(entry) = entries.next_entry().await.unwrap_or(None) {
71
+ let path = entry.path();
72
+ info!("entry: {:?}", path);
73
+ let path_str = match path.to_str() {
74
+ Some(path_str) => path_str.to_string(),
75
+ None => continue,
76
+ };
77
+
78
+ if git_ignored_set.contains(&path_str) {
79
+ continue;
80
+ }
81
+
82
+ match entry.file_type().await {
83
+ Ok(file_type) => {
84
+ if file_type.is_dir() {
85
+ dirs_to_check.push(path_str);
86
+ }
87
+
88
+ if file_type.is_file() {
89
+ num_files += 1;
90
+ }
91
+ }
92
+ Err(_) => continue,
93
+ }
94
+
95
+ }
96
+ }
97
+ num_files > max_files
98
+ }
99
+
64
100
  #[napi]
65
- pub async unsafe fn init(&mut self, git_ignored_files: Vec<String>, is_git_repo: bool) -> Result<(), napi::Error> {
101
+ pub async unsafe fn init(
102
+ &mut self,
103
+ git_ignored_files: Vec<String>,
104
+ is_git_repo: bool,
105
+ ) -> Result<(), napi::Error> {
66
106
  // 1. compute the merkle tree
67
107
  // 2. update the backend
68
108
  // 3. sync with the remote
69
109
  info!("Merkle tree compute started!");
110
+ info!("Root directory: {:?}", self.absolute_root_directory);
70
111
  unsafe {
71
- self.compute_merkle_tree(git_ignored_files, is_git_repo).await?;
112
+ self
113
+ .compute_merkle_tree(git_ignored_files, is_git_repo)
114
+ .await?;
72
115
  }
73
116
 
74
117
  Ok(())
@@ -82,14 +125,23 @@ impl MerkleClient {
82
125
  pub async unsafe fn compute_merkle_tree(
83
126
  &mut self,
84
127
  git_ignored_files: Vec<String>,
85
- is_git_repo: bool
128
+ is_git_repo: bool,
86
129
  ) -> Result<(), napi::Error> {
87
130
  // make the git ignored files into a hash set
88
- let git_ignored_set = HashSet::from_iter(git_ignored_files.into_iter());
131
+ let mut git_ignored_set = HashSet::from_iter(git_ignored_files.into_iter());
89
132
 
90
- let t =
91
- MerkleTree::construct_merkle_tree(self.absolute_root_directory.clone(), git_ignored_set, is_git_repo)
92
- .await;
133
+ // if the hashset itself contains the root directory, then we should remove it.
134
+ // this is because the root directory is not a file, and we don't want to ignore it.
135
+ if git_ignored_set.contains(&self.absolute_root_directory) {
136
+ git_ignored_set.remove(&self.absolute_root_directory);
137
+ }
138
+
139
+ let t = MerkleTree::construct_merkle_tree(
140
+ self.absolute_root_directory.clone(),
141
+ git_ignored_set,
142
+ is_git_repo,
143
+ )
144
+ .await;
93
145
 
94
146
  match t {
95
147
  Ok(tree) => {
@@ -118,12 +170,18 @@ impl MerkleClient {
118
170
  &self,
119
171
  relative_path: String,
120
172
  ) -> Result<String, napi::Error> {
173
+ debug!("get_subtree_hash: relative_path: {:?}", relative_path);
174
+
121
175
  let relative_path_without_leading_slash = match relative_path
122
176
  .strip_prefix('.')
123
177
  {
124
178
  Some(path) => path.strip_prefix(std::path::MAIN_SEPARATOR).unwrap_or(""),
125
179
  None => relative_path.as_str(),
126
180
  };
181
+ debug!(
182
+ "relative_path_without_leading_slash: {:?}",
183
+ relative_path_without_leading_slash
184
+ );
127
185
 
128
186
  let absolute_path = if !relative_path_without_leading_slash.is_empty() {
129
187
  std::path::Path::new(&self.absolute_root_directory)
@@ -132,6 +190,8 @@ impl MerkleClient {
132
190
  std::path::Path::new(&self.absolute_root_directory).to_path_buf()
133
191
  };
134
192
 
193
+ debug!("absolute_path: {:?}", absolute_path);
194
+
135
195
  let absolute_path_string = match absolute_path.to_str() {
136
196
  Some(path) => path.to_string(),
137
197
  None => {
@@ -142,6 +202,8 @@ impl MerkleClient {
142
202
  }
143
203
  };
144
204
 
205
+ debug!("absolute_path_string: {:?}", absolute_path_string);
206
+
145
207
  let hash = self
146
208
  .tree
147
209
  .get_subtree_hash(absolute_path_string.as_str())
package/src/logger.rs ADDED
@@ -0,0 +1,55 @@
1
+ use tracing::{info, subscriber, Level};
2
+ use tracing_appender::non_blocking::WorkerGuard;
3
+ use tracing_appender::rolling::{RollingFileAppender, Rotation};
4
+ use tracing_subscriber::fmt;
5
+ use tracing_subscriber::prelude::*;
6
+
7
+ pub enum GuardType {
8
+ #[cfg(all(not(feature = "debugfile"), not(target_os = "linux")))]
9
+ Guard(tracing_axiom::Guard),
10
+ WorkerGuard(tracing_appender::non_blocking::WorkerGuard),
11
+ }
12
+
13
+ pub fn init_logger() -> Option<GuardType> {
14
+ #[cfg(feature = "debugfile")]
15
+ let _guard = {
16
+ let file_appender =
17
+ RollingFileAppender::new(Rotation::NEVER, "./", "rust_log.txt");
18
+ let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
19
+ let subscriber = fmt::Subscriber::builder()
20
+ .with_max_level(Level::TRACE)
21
+ .with_writer(non_blocking)
22
+ .with_ansi(false)
23
+ .with_line_number(true)
24
+ .finish();
25
+
26
+ let _ = tracing::subscriber::set_global_default(subscriber);
27
+
28
+ Some(GuardType::WorkerGuard(_guard))
29
+ };
30
+
31
+ #[cfg(all(not(feature = "debugfile"), not(target_os = "linux")))]
32
+ let _guard = {
33
+ let (axiom_layer, _guard) = tracing_axiom::builder()
34
+ .with_token("xaat-a51088e6-7889-41c0-b440-cfd4601acdd7")
35
+ .with_dataset("local-indexing")
36
+ .layer()
37
+ .ok()?;
38
+ // let fmt_layer = fmt::layer().with_level(true).with_ansi(false).with_line_number(true);
39
+
40
+ let _ = tracing_subscriber::registry()
41
+ .with(axiom_layer)
42
+ .try_init()
43
+ .ok()?;
44
+ // let _ = tracing::subscriber::set_global_default(subscriber);
45
+
46
+ info!("Tracing initialized! in rust");
47
+
48
+ Some(GuardType::Guard(_guard))
49
+ };
50
+
51
+ #[cfg(all(not(feature = "debugfile"), target_os = "linux"))]
52
+ let _guard = { None };
53
+
54
+ _guard
55
+ }
@@ -9,6 +9,7 @@ use tonic::async_trait;
9
9
 
10
10
  #[async_trait]
11
11
  impl LocalConstruction for MerkleTree {
12
+ #[tracing::instrument]
12
13
  async fn new(
13
14
  root_directory: Option<String>,
14
15
  ) -> Result<MerkleTree, anyhow::Error> {
@@ -17,8 +18,9 @@ impl LocalConstruction for MerkleTree {
17
18
  let n = MerkleTree::construct_merkle_tree(
18
19
  root_directory,
19
20
  git_ignored_files,
20
- false
21
- ).await;
21
+ false,
22
+ )
23
+ .await;
22
24
  return n;
23
25
  }
24
26
 
@@ -35,7 +37,7 @@ impl LocalConstruction for MerkleTree {
35
37
  async fn construct_merkle_tree(
36
38
  absolute_path_to_root_directory: String,
37
39
  git_ignored_files_and_dirs: HashSet<String>,
38
- is_git_repo: bool
40
+ is_git_repo: bool,
39
41
  ) -> Result<MerkleTree, anyhow::Error> {
40
42
  let path = PathBuf::from(absolute_path_to_root_directory.clone());
41
43
  if !path.exists() {
@@ -58,16 +60,17 @@ impl LocalConstruction for MerkleTree {
58
60
  None,
59
61
  &git_ignored_files_and_dirs,
60
62
  absolute_path_to_root_directory.as_str(),
61
- is_git_repo
63
+ is_git_repo,
62
64
  )
63
65
  .await;
66
+
64
67
  let mut mt = MerkleTree {
65
68
  root: root_node,
66
69
  files: BTreeMap::new(),
67
70
  root_path: absolute_path_to_root_directory,
68
71
  cursor: None,
69
- git_ignored_files_and_dirs: git_ignored_files_and_dirs,
70
- is_git_repo
72
+ git_ignored_files_and_dirs,
73
+ is_git_repo,
71
74
  };
72
75
 
73
76
  // we now iterate over all the nodes and add them to the hashmap
@@ -80,7 +83,6 @@ impl LocalConstruction for MerkleTree {
80
83
  let node_reader = node.read().await;
81
84
  match &node_reader.node_type {
82
85
  NodeType::Branch(n) => {
83
- tracing::info!("Branch: {:?}", n.0);
84
86
  let children = &n.1;
85
87
  files.insert(n.0.clone(), File { node: node.clone() });
86
88
  for child in children {
@@ -107,8 +109,7 @@ impl LocalConstruction for MerkleTree {
107
109
 
108
110
  add_nodes_to_hashmap(&mt.root, &mut mt.files).await;
109
111
 
110
- tracing::info!("Merkle tree compute finished!");
111
- tracing::info!("Merkle tree: {}", mt);
112
+ tracing::info!("number of files in the tree: {}", mt.files.len());
112
113
 
113
114
  Ok(mt)
114
115
  }
@@ -152,6 +153,7 @@ impl LocalConstruction for MerkleTree {
152
153
  Ok(())
153
154
  }
154
155
 
156
+ #[tracing::instrument]
155
157
  async fn delete_file(
156
158
  &mut self,
157
159
  file_path: String,
@@ -6,13 +6,14 @@ use std::vec;
6
6
  use std::{fs, path::Path, sync::Arc};
7
7
  use tokio::sync::RwLock;
8
8
  use tonic::async_trait;
9
- use tracing::info;
9
+ use tracing::{debug, info};
10
10
 
11
11
  pub mod local_construction;
12
12
  pub mod test;
13
13
 
14
14
  pub type MerkleNodePtr = Arc<RwLock<MerkleNode>>;
15
15
 
16
+ #[derive(Debug)]
16
17
  pub struct MerkleTree {
17
18
  root_path: String,
18
19
  root: MerkleNodePtr,
@@ -64,7 +65,7 @@ pub trait LocalConstruction {
64
65
  async fn construct_merkle_tree(
65
66
  root_directory: String,
66
67
  git_ignored_files_and_dirs: HashSet<String>,
67
- is_git_repo: bool
68
+ is_git_repo: bool,
68
69
  ) -> Result<MerkleTree, anyhow::Error>;
69
70
 
70
71
  async fn update_file(
@@ -99,7 +100,7 @@ impl MerkleTree {
99
100
  root_path: "".to_string(),
100
101
  cursor: None,
101
102
  git_ignored_files_and_dirs: HashSet::new(),
102
- is_git_repo: false
103
+ is_git_repo: false,
103
104
  }
104
105
  }
105
106
 
@@ -107,6 +108,8 @@ impl MerkleTree {
107
108
  &self,
108
109
  absolute_path: &str,
109
110
  ) -> Result<String, anyhow::Error> {
111
+ debug!("get_subtree_hash: absolute_path: {:?}", absolute_path);
112
+
110
113
  let node = match self.files.get(absolute_path) {
111
114
  Some(file) => file.node.clone(),
112
115
  None => {
@@ -122,10 +125,7 @@ impl MerkleTree {
122
125
  let node_reader = node.read().await;
123
126
  let node_hash = node_reader.hash.clone();
124
127
 
125
- info!(
126
- "get_subtree_hash for path: {}, node_hash: {}",
127
- absolute_path, node_hash
128
- );
128
+ debug!("node_hash: {:?}", node_hash);
129
129
 
130
130
  Ok(node_hash)
131
131
  }
@@ -322,16 +322,11 @@ impl MerkleTree {
322
322
  &self,
323
323
  absolute_path: &str,
324
324
  ) -> Result<Vec<String>, anyhow::Error> {
325
- info!("get_spline called with absolute_path: {}", absolute_path);
326
325
  let mut files = Vec::new();
327
326
 
328
327
  let current_node = match self.files.get(absolute_path) {
329
- Some(node) => {
330
- info!("Found node for absolute_path: {}", absolute_path);
331
- node.node.clone()
332
- }
328
+ Some(node) => node.node.clone(),
333
329
  None => {
334
- info!("File not found for absolute_path: {}", absolute_path);
335
330
  return Err(anyhow::anyhow!("File not found: {}", absolute_path));
336
331
  }
337
332
  };
@@ -342,7 +337,6 @@ impl MerkleTree {
342
337
  while let Some(node) = stack.pop() {
343
338
  let parent = node.read().await.parent.clone();
344
339
  if let Some(parent) = parent {
345
- info!("Adding parent hash to files vector");
346
340
  {
347
341
  let parent_node = parent.read().await;
348
342
  match &parent_node.node_type {
@@ -361,7 +355,6 @@ impl MerkleTree {
361
355
  stack.push(parent);
362
356
  }
363
357
  }
364
- info!("Returning files vector with {} elements", files.len());
365
358
  Ok(files)
366
359
  }
367
360
 
@@ -410,7 +403,7 @@ impl MerkleTree {
410
403
  Some(ancestor.clone()),
411
404
  &self.git_ignored_files_and_dirs,
412
405
  &absolute_root_path.as_str(),
413
- self.is_git_repo
406
+ self.is_git_repo,
414
407
  )
415
408
  .await;
416
409
  ancestor.write().await.attach_child(new_node.clone()).await;
@@ -428,7 +421,7 @@ impl MerkleTree {
428
421
  Some(ancestor.clone()),
429
422
  &self.git_ignored_files_and_dirs,
430
423
  &absolute_root_path.as_str(),
431
- self.is_git_repo
424
+ self.is_git_repo,
432
425
  )
433
426
  .await;
434
427
 
@@ -736,6 +729,7 @@ impl MerkleNode {
736
729
  .await
737
730
  }
738
731
 
732
+ // #[tracing::instrument]
739
733
  async fn new(
740
734
  absolute_file_or_directory: PathBuf,
741
735
  parent: ParentPtr,
@@ -749,7 +743,6 @@ impl MerkleNode {
749
743
  "constructing node for absolute_file_or_directory: {:?}",
750
744
  absolute_file_or_directory
751
745
  );
752
- info!("bypass_git: {}, is_git_repo: {}", bypass_git, is_git_repo);
753
746
 
754
747
  MerkleNode::construct_node(
755
748
  Path::new(&absolute_file_or_directory),
@@ -778,6 +771,7 @@ impl MerkleNode {
778
771
  Box::pin(async move {
779
772
  // check if it is a file
780
773
  let path_str = absolute_file_or_directory.to_str().unwrap().to_string();
774
+
781
775
  if absolute_file_or_directory.is_file() {
782
776
  return Arc::new(RwLock::new(
783
777
  MerkleNode::construct_file_node_or_error_node(
@@ -802,6 +796,7 @@ impl MerkleNode {
802
796
  let is_git_ignored_dir = ignored_files.contains(&path_str);
803
797
 
804
798
  if is_git_ignored_dir && !bypass_git {
799
+ tracing::info!("skipping directory: {}", path_str);
805
800
  return Arc::new(RwLock::new(MerkleNode::empty_node(
806
801
  Some(absolute_file_or_directory),
807
802
  Some("Directory is git ignored!".to_string()),
@@ -812,6 +807,7 @@ impl MerkleNode {
812
807
  match entries {
813
808
  Ok(_) => (),
814
809
  Err(e) => {
810
+ tracing::error!("error reading directory: {}", e);
815
811
  return Arc::new(RwLock::new(MerkleNode::empty_node(
816
812
  Some(absolute_file_or_directory),
817
813
  Some(e.to_string()),
@@ -844,6 +840,7 @@ impl MerkleNode {
844
840
  );
845
841
  }
846
842
  Err(e) => {
843
+ tracing::error!("error reading directory: {}", e);
847
844
  children.push(Arc::new(RwLock::new(MerkleNode::empty_node(
848
845
  Some(absolute_file_or_directory),
849
846
  Some(e.to_string()),
@@ -937,11 +934,7 @@ impl MerkleNode {
937
934
  .await
938
935
  {
939
936
  Ok(node) => node,
940
- Err(e) => {
941
- // println!("constructing error node. error: {}", e);
942
- // println!("file_path: {:?}", file_path);
943
- MerkleNode::empty_node(Some(absolute_file_path), Some(e))
944
- }
937
+ Err(e) => MerkleNode::empty_node(Some(absolute_file_path), Some(e)),
945
938
  };
946
939
 
947
940
  node
@@ -1001,7 +994,6 @@ impl MerkleNode {
1001
994
  if hash == "" {
1002
995
  continue;
1003
996
  }
1004
- info!("name: {}, hash: {}", name, hash);
1005
997
  hasher.update(hash);
1006
998
  }
1007
999