@anysphere/file-service 0.0.0-e3fdf62d → 0.0.0-e6124fba

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/src/lib.rs CHANGED
@@ -1,11 +1,16 @@
1
+ #![windows_subsystem = "windows"]
1
2
  #![deny(clippy::all)]
3
+ #![deny(unsafe_op_in_unsafe_fn)]
2
4
  pub mod file_utils;
3
- pub mod git_utils;
4
5
  pub mod merkle_tree;
5
6
 
6
- use std::vec;
7
+ use std::{collections::HashSet, vec};
7
8
 
9
+ use anyhow::Context;
8
10
  use merkle_tree::{LocalConstruction, MerkleTree};
11
+ use tracing::{info, Level};
12
+ use tracing_appender::rolling::{RollingFileAppender, Rotation};
13
+ use tracing_subscriber::fmt;
9
14
 
10
15
  #[macro_use]
11
16
  extern crate napi_derive;
@@ -13,25 +18,70 @@ extern crate napi_derive;
13
18
  #[napi]
14
19
  pub struct MerkleClient {
15
20
  tree: MerkleTree,
16
- root_directory: String,
21
+ absolute_root_directory: String,
22
+ _guard: Option<tracing_appender::non_blocking::WorkerGuard>,
23
+ }
24
+
25
+ pub fn init_logger() -> Option<tracing_appender::non_blocking::WorkerGuard> {
26
+ #[cfg(feature = "debugfile")]
27
+ let _guard = {
28
+ let file_appender =
29
+ RollingFileAppender::new(Rotation::NEVER, "./", "rust_log.txt");
30
+ let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender);
31
+ let subscriber = fmt::Subscriber::builder()
32
+ .with_max_level(Level::TRACE)
33
+ .with_writer(non_blocking)
34
+ .with_ansi(false)
35
+ .with_line_number(true)
36
+ .finish();
37
+
38
+ let _ = tracing::subscriber::set_global_default(subscriber);
39
+ Some(_guard)
40
+ };
41
+ #[cfg(not(feature = "debugfile"))]
42
+ let _guard = { None };
43
+ _guard
17
44
  }
18
45
 
19
46
  #[napi]
20
47
  impl MerkleClient {
21
48
  #[napi(constructor)]
22
- pub fn new(root_directory: String) -> MerkleClient {
49
+ pub fn new(absolute_root_directory: String) -> MerkleClient {
50
+ let _guard = init_logger();
51
+
52
+ // let canonical_root_directory = std::path::Path::new(&absolute_root_directory);
53
+ // use dunce::canonicalize;
54
+ // let canonical_root_directory = match dunce::canonicalize(&canonical_root_directory) {
55
+ // Ok(path) => path.to_str().unwrap_or(&absolute_root_directory).to_string().to_lowercase(),
56
+ // Err(e) => {
57
+ // info!("Error in canonicalizing path: path: {:?}, error {:?}", canonical_root_directory, e);
58
+ // absolute_root_directory
59
+ // }
60
+ // };
61
+
23
62
  MerkleClient {
24
63
  tree: MerkleTree::empty_tree(),
25
- root_directory,
64
+ absolute_root_directory,
65
+ _guard,
26
66
  }
27
67
  }
28
68
 
29
69
  #[napi]
30
- pub async unsafe fn init(&mut self) -> Result<(), napi::Error> {
70
+ pub async unsafe fn init(
71
+ &mut self,
72
+ git_ignored_files: Vec<String>,
73
+ is_git_repo: bool,
74
+ ) -> Result<(), napi::Error> {
31
75
  // 1. compute the merkle tree
32
76
  // 2. update the backend
33
77
  // 3. sync with the remote
34
- self.compute_merkle_tree().await?;
78
+ info!("Merkle tree compute started!");
79
+ info!("Root directory: {:?}", self.absolute_root_directory);
80
+ unsafe {
81
+ self
82
+ .compute_merkle_tree(git_ignored_files, is_git_repo)
83
+ .await?;
84
+ }
35
85
 
36
86
  Ok(())
37
87
  }
@@ -40,12 +90,23 @@ impl MerkleClient {
40
90
  unimplemented!("Interrupt is not implemented yet");
41
91
  }
42
92
 
43
- // #[napi]
93
+ #[napi]
44
94
  pub async unsafe fn compute_merkle_tree(
45
95
  &mut self,
96
+ git_ignored_files: Vec<String>,
97
+ is_git_repo: bool,
46
98
  ) -> Result<(), napi::Error> {
47
- let t =
48
- MerkleTree::construct_merkle_tree(self.root_directory.clone()).await;
99
+ // make the git ignored files into a hash set
100
+ let git_ignored_set = HashSet::from_iter(git_ignored_files.into_iter());
101
+
102
+ info!("Git ignored set: {:?}", git_ignored_set);
103
+
104
+ let t = MerkleTree::construct_merkle_tree(
105
+ self.absolute_root_directory.clone(),
106
+ git_ignored_set,
107
+ is_git_repo,
108
+ )
109
+ .await;
49
110
 
50
111
  match t {
51
112
  Ok(tree) => {
@@ -72,15 +133,42 @@ impl MerkleClient {
72
133
  #[napi]
73
134
  pub async fn get_subtree_hash(
74
135
  &self,
75
- path: String,
136
+ relative_path: String,
76
137
  ) -> Result<String, napi::Error> {
77
- let hash = self.tree.get_subtree_hash(path).await;
138
+ let relative_path_without_leading_slash = match relative_path
139
+ .strip_prefix('.')
140
+ {
141
+ Some(path) => path.strip_prefix(std::path::MAIN_SEPARATOR).unwrap_or(""),
142
+ None => relative_path.as_str(),
143
+ };
144
+
145
+ let absolute_path = if !relative_path_without_leading_slash.is_empty() {
146
+ std::path::Path::new(&self.absolute_root_directory)
147
+ .join(relative_path_without_leading_slash)
148
+ } else {
149
+ std::path::Path::new(&self.absolute_root_directory).to_path_buf()
150
+ };
151
+
152
+ let absolute_path_string = match absolute_path.to_str() {
153
+ Some(path) => path.to_string(),
154
+ None => {
155
+ return Err(napi::Error::new(
156
+ napi::Status::Unknown,
157
+ format!("some string error"),
158
+ ))
159
+ }
160
+ };
161
+
162
+ let hash = self
163
+ .tree
164
+ .get_subtree_hash(absolute_path_string.as_str())
165
+ .await;
78
166
 
79
167
  match hash {
80
168
  Ok(hash) => Ok(hash),
81
169
  Err(e) => Err(napi::Error::new(
82
170
  napi::Status::Unknown,
83
- format!("Error in get_subtree_hash: {:?}", e),
171
+ format!("Error in get_subtree_hash. \nRelative path: {:?}, \nAbsolute path: {:?}, \nRoot directory: {:?}\nError: {:?}", &relative_path, absolute_path, self.absolute_root_directory, e)
84
172
  )),
85
173
  }
86
174
  }
@@ -98,6 +186,28 @@ impl MerkleClient {
98
186
  }
99
187
  }
100
188
 
189
+ pub async fn get_num_embeddable_files_in_subtree(
190
+ &self,
191
+ relative_path: String,
192
+ ) -> Result<i32, napi::Error> {
193
+ let absolute_path = std::path::Path::new(&self.absolute_root_directory)
194
+ .join(relative_path)
195
+ .canonicalize()?;
196
+
197
+ let num = self
198
+ .tree
199
+ .get_num_embeddable_files_in_subtree(absolute_path)
200
+ .await;
201
+
202
+ match num {
203
+ Ok(num) => Ok(num),
204
+ Err(e) => Err(napi::Error::new(
205
+ napi::Status::Unknown,
206
+ format!("Error in get_num_embeddable_files_in_subtree: {:?}", e),
207
+ )),
208
+ }
209
+ }
210
+
101
211
  #[napi]
102
212
  pub async fn get_all_files(&self) -> Result<Vec<String>, napi::Error> {
103
213
  let files = self.tree.get_all_files().await;
@@ -111,6 +221,28 @@ impl MerkleClient {
111
221
  }
112
222
  }
113
223
 
224
+ #[napi]
225
+ pub async fn get_all_dir_files_to_embed(
226
+ &self,
227
+ absolute_file_path: String,
228
+ ) -> Result<Vec<String>, napi::Error> {
229
+ // let absolute_path = absolute_file_path.to_lowercase();
230
+ // let absolute_path_str = absolute_path.as_str();
231
+
232
+ let files = self
233
+ .tree
234
+ .get_all_dir_files_to_embed(absolute_file_path.as_str())
235
+ .await;
236
+
237
+ match files {
238
+ Ok(files) => Ok(files),
239
+ Err(e) => Err(napi::Error::new(
240
+ napi::Status::Unknown,
241
+ format!("Error in get_all_dir_files_to_embed: {:?}", e),
242
+ )),
243
+ }
244
+ }
245
+
114
246
  #[napi]
115
247
  pub async unsafe fn get_next_file_to_embed(
116
248
  &mut self,
@@ -125,7 +257,6 @@ impl MerkleClient {
125
257
 
126
258
  let ret = vec![file];
127
259
  let ret = ret.into_iter().chain(path.into_iter()).collect::<Vec<_>>();
128
-
129
260
  Ok(ret)
130
261
  }
131
262
  Err(e) => Err(napi::Error::new(
@@ -135,6 +266,25 @@ impl MerkleClient {
135
266
  }
136
267
  }
137
268
 
269
+ // FIXME(sualeh): get_spline
270
+ #[napi]
271
+ pub async fn get_spline(
272
+ &self,
273
+ absolute_file_path: String,
274
+ ) -> Result<Vec<String>, napi::Error> {
275
+ // let absolute_path = absolute_file_path.to_lowercase();
276
+ // let absolute_path_str = absolute_path.as_str();
277
+ let spline = self.tree.get_spline(absolute_file_path.as_str()).await;
278
+
279
+ match spline {
280
+ Ok(spline) => Ok(spline),
281
+ Err(e) => Err(napi::Error::new(
282
+ napi::Status::Unknown,
283
+ format!("Error in get_spline: {:?}", e),
284
+ )),
285
+ }
286
+ }
287
+
138
288
  #[napi]
139
289
  pub async fn get_hashes_for_files(
140
290
  &self,
@@ -151,8 +301,8 @@ impl MerkleClient {
151
301
  }
152
302
  }
153
303
 
154
- // #[napi]
304
+ #[napi]
155
305
  pub fn update_root_directory(&mut self, root_directory: String) {
156
- self.root_directory = root_directory;
306
+ self.absolute_root_directory = root_directory;
157
307
  }
158
308
  }
@@ -3,8 +3,8 @@ use crate::merkle_tree::{
3
3
  };
4
4
 
5
5
  use super::{LocalConstruction, MerkleTree};
6
- use std::path::PathBuf;
7
- use std::{collections::HashMap, path::Path, sync::Arc};
6
+ use std::collections::{BTreeMap, HashSet};
7
+ use std::path::{Path, PathBuf};
8
8
  use tonic::async_trait;
9
9
 
10
10
  #[async_trait]
@@ -12,8 +12,13 @@ impl LocalConstruction for MerkleTree {
12
12
  async fn new(
13
13
  root_directory: Option<String>,
14
14
  ) -> Result<MerkleTree, anyhow::Error> {
15
+ let git_ignored_files = HashSet::<String>::new();
15
16
  if let Some(root_directory) = root_directory {
16
- let n = MerkleTree::construct_merkle_tree(root_directory).await;
17
+ let n = MerkleTree::construct_merkle_tree(
18
+ root_directory,
19
+ git_ignored_files,
20
+ false
21
+ ).await;
17
22
  return n;
18
23
  }
19
24
 
@@ -28,32 +33,54 @@ impl LocalConstruction for MerkleTree {
28
33
  /// 3. construct merkle tree
29
34
  /// 4. return merkle tree
30
35
  async fn construct_merkle_tree(
31
- root_directory: String,
36
+ absolute_path_to_root_directory: String,
37
+ git_ignored_files_and_dirs: HashSet<String>,
38
+ is_git_repo: bool
32
39
  ) -> Result<MerkleTree, anyhow::Error> {
33
- let path = PathBuf::from(root_directory.clone());
40
+ let path = PathBuf::from(absolute_path_to_root_directory.clone());
34
41
  if !path.exists() {
35
42
  // FIXME: we should report this via a good logger.
36
43
  panic!("Root directory does not exist!");
37
44
  }
38
45
 
39
- let root_node = MerkleNode::new(path, None).await;
46
+ // 1. get all the gitignored files
47
+ // let git_ignored_files_and_dirs =
48
+ // match git_utils::list_ignored_files_and_directories(
49
+ // absolute_path_to_root_directory.as_str(),
50
+ // true,
51
+ // ) {
52
+ // Ok(git_ignored) => git_ignored,
53
+ // Err(_e) => HashSet::new(),
54
+ // };
55
+
56
+ let root_node = MerkleNode::new(
57
+ path,
58
+ None,
59
+ &git_ignored_files_and_dirs,
60
+ absolute_path_to_root_directory.as_str(),
61
+ is_git_repo
62
+ )
63
+ .await;
40
64
  let mut mt = MerkleTree {
41
65
  root: root_node,
42
- files: HashMap::new(),
43
- root_path: root_directory,
66
+ files: BTreeMap::new(),
67
+ root_path: absolute_path_to_root_directory,
44
68
  cursor: None,
69
+ git_ignored_files_and_dirs,
70
+ is_git_repo
45
71
  };
46
72
 
47
73
  // we now iterate over all the nodes and add them to the hashmap
48
74
  // TODO(later): i can make this parallel.
49
75
  fn add_nodes_to_hashmap<'a>(
50
76
  node: &'a MerkleNodePtr,
51
- files: &'a mut HashMap<String, File>,
77
+ files: &'a mut BTreeMap<String, File>,
52
78
  ) -> PinnedFuture<'a, ()> {
53
79
  Box::pin(async move {
54
80
  let node_reader = node.read().await;
55
81
  match &node_reader.node_type {
56
82
  NodeType::Branch(n) => {
83
+ tracing::info!("Branch: {:?}", n.0);
57
84
  let children = &n.1;
58
85
  files.insert(n.0.clone(), File { node: node.clone() });
59
86
  for child in children {
@@ -62,6 +89,13 @@ impl LocalConstruction for MerkleTree {
62
89
  }
63
90
  NodeType::File(file_name) => {
64
91
  let f = File { node: node.clone() };
92
+
93
+ // i dont reallly like this :(((
94
+ // let canonical_file_name = match dunce::canonicalize(file_name) {
95
+ // Ok(path) => path.to_str().unwrap_or(file_name).to_string(),
96
+ // Err(_) => file_name.clone(),
97
+ // };
98
+
65
99
  files.insert(file_name.clone(), f);
66
100
  }
67
101
  NodeType::ErrorNode(_) => {
@@ -73,6 +107,9 @@ impl LocalConstruction for MerkleTree {
73
107
 
74
108
  add_nodes_to_hashmap(&mt.root, &mut mt.files).await;
75
109
 
110
+ tracing::info!("Merkle tree compute finished!");
111
+ tracing::info!("Merkle tree: {}", mt);
112
+
76
113
  Ok(mt)
77
114
  }
78
115