@repokit/core 1.3.4 → 1.3.6

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.lock CHANGED
@@ -3,40 +3,37 @@
3
3
  version = 4
4
4
 
5
5
  [[package]]
6
- name = "alphanumeric-sort"
7
- version = "1.5.5"
6
+ name = "aho-corasick"
7
+ version = "1.1.4"
8
8
  source = "registry+https://github.com/rust-lang/crates.io-index"
9
- checksum = "774ffdfeac16e9b4d75e41225dc2545d9c2082a0634b5d7f6f70e168546eecb1"
9
+ checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
10
+ dependencies = [
11
+ "memchr",
12
+ ]
10
13
 
11
14
  [[package]]
12
- name = "colored"
13
- version = "3.1.1"
15
+ name = "alphanumeric-sort"
16
+ version = "1.5.5"
14
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
15
- checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
16
- dependencies = [
17
- "windows-sys",
18
- ]
18
+ checksum = "774ffdfeac16e9b4d75e41225dc2545d9c2082a0634b5d7f6f70e168546eecb1"
19
19
 
20
20
  [[package]]
21
- name = "crossbeam"
22
- version = "0.8.4"
21
+ name = "bstr"
22
+ version = "1.12.1"
23
23
  source = "registry+https://github.com/rust-lang/crates.io-index"
24
- checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
24
+ checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
25
25
  dependencies = [
26
- "crossbeam-channel",
27
- "crossbeam-deque",
28
- "crossbeam-epoch",
29
- "crossbeam-queue",
30
- "crossbeam-utils",
26
+ "memchr",
27
+ "serde",
31
28
  ]
32
29
 
33
30
  [[package]]
34
- name = "crossbeam-channel"
35
- version = "0.5.15"
31
+ name = "colored"
32
+ version = "3.1.1"
36
33
  source = "registry+https://github.com/rust-lang/crates.io-index"
37
- checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
34
+ checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34"
38
35
  dependencies = [
39
- "crossbeam-utils",
36
+ "windows-sys",
40
37
  ]
41
38
 
42
39
  [[package]]
@@ -58,27 +55,12 @@ dependencies = [
58
55
  "crossbeam-utils",
59
56
  ]
60
57
 
61
- [[package]]
62
- name = "crossbeam-queue"
63
- version = "0.3.12"
64
- source = "registry+https://github.com/rust-lang/crates.io-index"
65
- checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
66
- dependencies = [
67
- "crossbeam-utils",
68
- ]
69
-
70
58
  [[package]]
71
59
  name = "crossbeam-utils"
72
60
  version = "0.8.21"
73
61
  source = "registry+https://github.com/rust-lang/crates.io-index"
74
62
  checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
75
63
 
76
- [[package]]
77
- name = "either"
78
- version = "1.15.0"
79
- source = "registry+https://github.com/rust-lang/crates.io-index"
80
- checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
81
-
82
64
  [[package]]
83
65
  name = "futures"
84
66
  version = "0.3.31"
@@ -169,27 +151,52 @@ dependencies = [
169
151
  ]
170
152
 
171
153
  [[package]]
172
- name = "itoa"
173
- version = "1.0.17"
154
+ name = "globset"
155
+ version = "0.4.18"
174
156
  source = "registry+https://github.com/rust-lang/crates.io-index"
175
- checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
157
+ checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3"
158
+ dependencies = [
159
+ "aho-corasick",
160
+ "bstr",
161
+ "log",
162
+ "regex-automata",
163
+ "regex-syntax",
164
+ ]
176
165
 
177
166
  [[package]]
178
- name = "jwalk"
179
- version = "0.8.1"
167
+ name = "ignore"
168
+ version = "0.4.25"
180
169
  source = "registry+https://github.com/rust-lang/crates.io-index"
181
- checksum = "2735847566356cd2179a2a38264839308f7079fa96e6bd5a42d740460e003c56"
170
+ checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a"
182
171
  dependencies = [
183
- "crossbeam",
184
- "rayon",
172
+ "crossbeam-deque",
173
+ "globset",
174
+ "log",
175
+ "memchr",
176
+ "regex-automata",
177
+ "same-file",
178
+ "walkdir",
179
+ "winapi-util",
185
180
  ]
186
181
 
182
+ [[package]]
183
+ name = "itoa"
184
+ version = "1.0.17"
185
+ source = "registry+https://github.com/rust-lang/crates.io-index"
186
+ checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
187
+
187
188
  [[package]]
188
189
  name = "lexopt"
189
190
  version = "0.3.1"
190
191
  source = "registry+https://github.com/rust-lang/crates.io-index"
191
192
  checksum = "9fa0e2a1fcbe2f6be6c42e342259976206b383122fc152e872795338b5a3f3a7"
192
193
 
194
+ [[package]]
195
+ name = "log"
196
+ version = "0.4.29"
197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
198
+ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
199
+
193
200
  [[package]]
194
201
  name = "memchr"
195
202
  version = "2.7.6"
@@ -233,25 +240,34 @@ dependencies = [
233
240
  ]
234
241
 
235
242
  [[package]]
236
- name = "rayon"
237
- version = "1.11.0"
243
+ name = "regex"
244
+ version = "1.12.3"
238
245
  source = "registry+https://github.com/rust-lang/crates.io-index"
239
- checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
246
+ checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
240
247
  dependencies = [
241
- "either",
242
- "rayon-core",
248
+ "aho-corasick",
249
+ "memchr",
250
+ "regex-automata",
251
+ "regex-syntax",
243
252
  ]
244
253
 
245
254
  [[package]]
246
- name = "rayon-core"
247
- version = "1.13.0"
255
+ name = "regex-automata"
256
+ version = "0.4.14"
248
257
  source = "registry+https://github.com/rust-lang/crates.io-index"
249
- checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
258
+ checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f"
250
259
  dependencies = [
251
- "crossbeam-deque",
252
- "crossbeam-utils",
260
+ "aho-corasick",
261
+ "memchr",
262
+ "regex-syntax",
253
263
  ]
254
264
 
265
+ [[package]]
266
+ name = "regex-syntax"
267
+ version = "0.8.9"
268
+ source = "registry+https://github.com/rust-lang/crates.io-index"
269
+ checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
270
+
255
271
  [[package]]
256
272
  name = "repokit"
257
273
  version = "0.1.0"
@@ -259,13 +275,22 @@ dependencies = [
259
275
  "alphanumeric-sort",
260
276
  "colored",
261
277
  "futures",
262
- "jwalk",
278
+ "ignore",
263
279
  "lexopt",
264
280
  "normalize-path",
281
+ "regex",
265
282
  "serde",
266
283
  "serde_json",
267
284
  "tokio",
268
- "tokio-thread-pool",
285
+ ]
286
+
287
+ [[package]]
288
+ name = "same-file"
289
+ version = "1.0.6"
290
+ source = "registry+https://github.com/rust-lang/crates.io-index"
291
+ checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
292
+ dependencies = [
293
+ "winapi-util",
269
294
  ]
270
295
 
271
296
  [[package]]
@@ -338,19 +363,29 @@ dependencies = [
338
363
  ]
339
364
 
340
365
  [[package]]
341
- name = "tokio-thread-pool"
342
- version = "1.0.0"
366
+ name = "unicode-ident"
367
+ version = "1.0.22"
368
+ source = "registry+https://github.com/rust-lang/crates.io-index"
369
+ checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
370
+
371
+ [[package]]
372
+ name = "walkdir"
373
+ version = "2.5.0"
343
374
  source = "registry+https://github.com/rust-lang/crates.io-index"
344
- checksum = "d94c3392b98a14acc18fa639cb48e94355ed7aaae4a45164e394d6c4da39c9ec"
375
+ checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
345
376
  dependencies = [
346
- "tokio",
377
+ "same-file",
378
+ "winapi-util",
347
379
  ]
348
380
 
349
381
  [[package]]
350
- name = "unicode-ident"
351
- version = "1.0.22"
382
+ name = "winapi-util"
383
+ version = "0.1.11"
352
384
  source = "registry+https://github.com/rust-lang/crates.io-index"
353
- checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
385
+ checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
386
+ dependencies = [
387
+ "windows-sys",
388
+ ]
354
389
 
355
390
  [[package]]
356
391
  name = "windows-link"
package/Cargo.toml CHANGED
@@ -14,9 +14,9 @@ colored = "3"
14
14
  lexopt = "0.3.1"
15
15
  normalize-path = "0.2.1"
16
16
  futures = "0.3.31"
17
- jwalk = "0.8.1"
18
17
  alphanumeric-sort = "1.5.5"
19
- tokio-thread-pool = "1.0.0"
20
18
  tokio = "1.49.0"
19
+ ignore = "0.4.25"
20
+ regex = { version = "1.12.3", features = ["std", "unicode"] }
21
21
 
22
22
 
@@ -4,6 +4,7 @@ CWD=$(pwd)
4
4
  MODULE_DIRECTORY="node_modules"
5
5
 
6
6
  if [[ "$CWD" != *"$MODULE_DIRECTORY"* ]]; then
7
+ yarn symlink;
7
8
  exit 0;
8
9
  fi
9
10
 
@@ -0,0 +1 @@
1
+ pub mod walker;
@@ -0,0 +1,81 @@
1
+ use std::{
2
+ fs::File,
3
+ io::{BufRead, BufReader},
4
+ sync::{Arc, Mutex},
5
+ };
6
+
7
+ use ignore::{DirEntry, Error, ParallelVisitor, ParallelVisitorBuilder, WalkState};
8
+ use regex::Regex;
9
+
10
+ pub struct TSFileVisitor {
11
+ root: String,
12
+ paths: Arc<Mutex<Vec<String>>>,
13
+ }
14
+
15
+ impl ParallelVisitor for TSFileVisitor {
16
+ fn visit(&mut self, entry: Result<DirEntry, Error>) -> WalkState {
17
+ let root_replacer = format!("{}/", self.root);
18
+ let repokit_import_matcher =
19
+ Regex::new(r#"(require\(|from[\s*]?)['"]@repokit/core["'][\)]?[;]?$"#).unwrap();
20
+ let template_matcher = Regex::new(r"externals\/templates\/[^\s]*?_template\.ts$").unwrap();
21
+ if let Ok(entry) = entry {
22
+ let path = entry.path();
23
+ let path_string = path.to_str().map_or("", |f| f);
24
+ if entry.file_type().is_some_and(|ft| ft.is_file())
25
+ && path_string.ends_with(".ts")
26
+ && !template_matcher.is_match(path_string)
27
+ {
28
+ let mut open_comment = false;
29
+ let file: File = File::open(path).expect("file");
30
+ let reader: BufReader<File> = BufReader::new(file);
31
+ for line_result in reader.lines() {
32
+ let unwrapped = line_result.unwrap();
33
+ let line = unwrapped.trim();
34
+ if !open_comment && line.starts_with("/**") {
35
+ open_comment = true;
36
+ continue;
37
+ }
38
+ if open_comment {
39
+ if line == "*/" {
40
+ open_comment = false;
41
+ }
42
+ continue;
43
+ }
44
+ if repokit_import_matcher.is_match(line) {
45
+ let mut vector = self.paths.lock().unwrap();
46
+ vector.push(path_string.to_string().replace(&root_replacer, ""));
47
+ break;
48
+ }
49
+ if !line.is_empty()
50
+ && !line.starts_with("import ")
51
+ && !line.contains("require(")
52
+ && !(line.starts_with("//") || line.starts_with("/*"))
53
+ {
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ WalkState::Continue
60
+ }
61
+ }
62
+
63
+ pub struct TSFileVisitorBuilder<'a> {
64
+ pub root: &'a str,
65
+ pub paths: &'a Arc<Mutex<Vec<String>>>,
66
+ }
67
+
68
+ impl<'a> TSFileVisitorBuilder<'a> {
69
+ pub fn new(root: &'a str, paths: &'a Arc<Mutex<Vec<String>>>) -> TSFileVisitorBuilder<'a> {
70
+ TSFileVisitorBuilder { paths, root }
71
+ }
72
+ }
73
+
74
+ impl<'s> ParallelVisitorBuilder<'s> for TSFileVisitorBuilder<'s> {
75
+ fn build(&mut self) -> Box<dyn ParallelVisitor + 's> {
76
+ Box::new(TSFileVisitor {
77
+ paths: self.paths.clone(),
78
+ root: self.root.to_string(),
79
+ })
80
+ }
81
+ }
@@ -1,4 +1,4 @@
1
- use std::path::Path;
1
+ use std::{path::Path, sync::MutexGuard};
2
2
 
3
3
  use serde_json::from_str;
4
4
 
@@ -31,7 +31,7 @@ impl TypescriptCommand {
31
31
  config
32
32
  }
33
33
 
34
- pub fn parse_commands(&self, path_list: Vec<String>) -> Vec<RepoKitCommand> {
34
+ pub fn parse_commands(&self, path_list: &MutexGuard<Vec<String>>) -> Vec<RepoKitCommand> {
35
35
  let paths = path_list.join(",");
36
36
  let executable = InternalFileSystem::new(&self.root).resolve_command("parse_commands.ts");
37
37
  let stdout =
package/internals/main.rs CHANGED
@@ -6,7 +6,7 @@ use crate::{
6
6
  mod configuration;
7
7
  mod executables;
8
8
  mod executor;
9
- mod external_commands;
9
+ mod file_walker;
10
10
  mod internal_commands;
11
11
  mod internal_filesystem;
12
12
  mod logger;
@@ -1,13 +1,18 @@
1
- use std::collections::HashMap;
1
+ use std::{
2
+ collections::HashMap,
3
+ sync::{Arc, Mutex},
4
+ };
2
5
 
3
- use futures::executor;
6
+ use ignore::WalkBuilder;
4
7
 
5
8
  use crate::{
6
9
  executables::{
7
10
  intenal_executable::InternalExecutable, internal_executable_definition::RepoKitScope,
8
11
  },
9
- external_commands::external_commands::ExternalCommands,
10
- internal_commands::internal_registry::InternalRegistry,
12
+ file_walker::walker::TSFileVisitorBuilder,
13
+ internal_commands::{
14
+ internal_registry::InternalRegistry, typescript_command::TypescriptCommand,
15
+ },
11
16
  logger::logger::Logger,
12
17
  repokit::{interfaces::RepoKitCommand, repokit::RepoKit},
13
18
  };
@@ -36,8 +41,13 @@ impl CommandValidations {
36
41
  }
37
42
 
38
43
  pub fn collect_and_validate_externals(&self) -> HashMap<String, RepoKitCommand> {
39
- let finder = ExternalCommands::new(&self.scope.root);
40
- let externals = executor::block_on(finder.find_all());
44
+ let paths: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
45
+ let mut visitor = TSFileVisitorBuilder::new(&self.scope.root, &paths);
46
+ WalkBuilder::new(&self.scope.root)
47
+ .build_parallel()
48
+ .visit(&mut visitor);
49
+ let result = paths.lock().unwrap();
50
+ let externals = TypescriptCommand::new(&self.scope.root).parse_commands(&result);
41
51
  let all = [&externals[..], &self.scope.configuration.thirdParty[..]].concat();
42
52
  self.detect_collisions_between_root_commands_and_externals(&all)
43
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@repokit/core",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
4
4
  "description": "A knowledgebase for your repository - wrapped in a CLI",
5
5
  "keywords": [
6
6
  "cli",
@@ -37,9 +37,9 @@
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^25.2.1",
40
- "oxfmt": "^0.27.0",
40
+ "oxfmt": "^0.33.0",
41
41
  "oxlint": "^1.42.0",
42
- "oxlint-tsgolint": "^0.11.3",
42
+ "oxlint-tsgolint": "^0.13.0",
43
43
  "typescript": "^5.9.3"
44
44
  }
45
45
  }
@@ -1,135 +0,0 @@
1
- use std::{
2
- fs::File,
3
- io::{BufRead, BufReader},
4
- path::Path,
5
- };
6
-
7
- use futures::{TryStreamExt, stream::FuturesUnordered};
8
- use jwalk::WalkDir;
9
- use tokio_thread_pool::ThreadPool;
10
-
11
- use crate::{
12
- internal_commands::typescript_command::TypescriptCommand, repokit::interfaces::RepoKitCommand,
13
- };
14
-
15
- pub struct ExternalCommands {
16
- pub root: String,
17
- }
18
-
19
- impl ExternalCommands {
20
- pub fn new(root: &str) -> ExternalCommands {
21
- ExternalCommands {
22
- root: root.to_string(),
23
- }
24
- }
25
-
26
- pub async fn find_all(&self) -> Vec<RepoKitCommand> {
27
- let mut futures = FuturesUnordered::new();
28
- let mut pool = ThreadPool::new(None, None, None);
29
- for entry in WalkDir::new(&self.root).into_iter().filter_map(|e| {
30
- if e.is_err() {
31
- return None;
32
- }
33
- let option = e.ok();
34
- match option {
35
- Some(file) => {
36
- let path = file.path();
37
- if file.file_type().is_file()
38
- && path.extension().is_some_and(|ext| ext == "ts")
39
- && self.allowed(path.to_str().expect("exists"))
40
- {
41
- return Some(file);
42
- }
43
- None
44
- }
45
- None => None,
46
- }
47
- }) {
48
- let path = entry.path();
49
- futures.push(pool.spawn(move || {
50
- if ExternalCommands::read(&path) {
51
- return Some(path.clone());
52
- }
53
- None
54
- }));
55
- }
56
- let mut paths: Vec<String> = Vec::new();
57
- while let Ok(Some(buffer)) = futures.try_next().await {
58
- if let Some(path) = buffer {
59
- paths.push(
60
- (path)
61
- .into_os_string()
62
- .into_string()
63
- .expect("stringify")
64
- .replace(&self.root, ""),
65
- )
66
- }
67
- }
68
- pool.pool.shutdown_background();
69
- TypescriptCommand::new(&self.root).parse_commands(paths)
70
- }
71
-
72
- fn read(path: &Path) -> bool {
73
- let file: File = File::open(path).expect("file");
74
- let reader: BufReader<File> = BufReader::new(file);
75
- for line_result in reader.lines() {
76
- let line: String = line_result.expect("line");
77
- if line.ends_with("\"@repokit/core\";") {
78
- return true;
79
- }
80
- }
81
- false
82
- }
83
-
84
- fn allowed(&self, path: &str) -> bool {
85
- let restricted_paths = ["node_modules", "target", "dist"];
86
- let restricted_extensions = ["templates/command_template.ts"];
87
- let relative_path = path.replace(format!("{}/", &self.root).as_str(), "");
88
- if ExternalCommands::restrict(
89
- &relative_path,
90
- &restricted_paths,
91
- RestrictDirection::Forwards,
92
- ) {
93
- return false;
94
- }
95
- if ExternalCommands::restrict(
96
- &relative_path,
97
- &restricted_extensions,
98
- RestrictDirection::Backwards,
99
- ) {
100
- return false;
101
- }
102
- let components = relative_path.split('/');
103
- for token in components {
104
- for restricted_path in restricted_paths {
105
- if token == restricted_path {
106
- return false;
107
- }
108
- }
109
- }
110
- true
111
- }
112
-
113
- fn restrict(path: &str, tokens: &[&str], direction: RestrictDirection) -> bool {
114
- for restricted in tokens {
115
- match direction {
116
- RestrictDirection::Forwards => {
117
- if path.starts_with(restricted) {
118
- return true;
119
- }
120
- }
121
- RestrictDirection::Backwards => {
122
- if path.ends_with(restricted) {
123
- return true;
124
- }
125
- }
126
- }
127
- }
128
- false
129
- }
130
- }
131
-
132
- enum RestrictDirection {
133
- Forwards,
134
- Backwards,
135
- }
@@ -1 +0,0 @@
1
- pub mod external_commands;