grimp 3.1__tar.gz → 3.3__tar.gz

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.
Files changed (45) hide show
  1. {grimp-3.1 → grimp-3.3}/PKG-INFO +3 -2
  2. {grimp-3.1 → grimp-3.3}/pyproject.toml +3 -2
  3. {grimp-3.1 → grimp-3.3}/rust/Cargo.lock +85 -18
  4. {grimp-3.1 → grimp-3.3}/rust/Cargo.toml +3 -2
  5. {grimp-3.1 → grimp-3.3}/rust/src/containers.rs +1 -2
  6. {grimp-3.1 → grimp-3.3}/rust/src/layers.rs +171 -49
  7. grimp-3.3/rust/src/lib.rs +261 -0
  8. {grimp-3.1 → grimp-3.3}/rust/tests/large.rs +11 -6
  9. {grimp-3.1 → grimp-3.3}/src/grimp/__init__.py +3 -2
  10. grimp-3.3/src/grimp/adaptors/_layers.py +174 -0
  11. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/filesystem.py +1 -1
  12. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/graph.py +4 -3
  13. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/modulefinder.py +4 -1
  14. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/graph.py +15 -10
  15. {grimp-3.1 → grimp-3.3}/src/grimp/domain/valueobjects.py +20 -0
  16. grimp-3.1/rust/src/lib.rs +0 -177
  17. grimp-3.1/src/grimp/adaptors/_layers.py +0 -353
  18. {grimp-3.1 → grimp-3.3}/README.rst +0 -0
  19. {grimp-3.1 → grimp-3.3}/rust/.cargo/config +0 -0
  20. {grimp-3.1 → grimp-3.3}/rust/src/dependencies.rs +0 -0
  21. {grimp-3.1 → grimp-3.3}/rust/src/importgraph.rs +0 -0
  22. {grimp-3.1 → grimp-3.3}/rust/tests/large_graph.json +0 -0
  23. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/__init__.py +0 -0
  24. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/caching.py +0 -0
  25. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/importscanner.py +0 -0
  26. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/packagefinder.py +0 -0
  27. {grimp-3.1 → grimp-3.3}/src/grimp/adaptors/timing.py +0 -0
  28. {grimp-3.1 → grimp-3.3}/src/grimp/algorithms/__init__.py +0 -0
  29. {grimp-3.1 → grimp-3.3}/src/grimp/algorithms/shortest_path.py +0 -0
  30. {grimp-3.1 → grimp-3.3}/src/grimp/application/__init__.py +0 -0
  31. {grimp-3.1 → grimp-3.3}/src/grimp/application/config.py +0 -0
  32. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/__init__.py +0 -0
  33. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/caching.py +0 -0
  34. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/filesystem.py +0 -0
  35. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/importscanner.py +0 -0
  36. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/modulefinder.py +0 -0
  37. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/packagefinder.py +0 -0
  38. {grimp-3.1 → grimp-3.3}/src/grimp/application/ports/timing.py +0 -0
  39. {grimp-3.1 → grimp-3.3}/src/grimp/application/usecases.py +0 -0
  40. {grimp-3.1 → grimp-3.3}/src/grimp/domain/__init__.py +0 -0
  41. {grimp-3.1 → grimp-3.3}/src/grimp/domain/analysis.py +0 -0
  42. {grimp-3.1 → grimp-3.3}/src/grimp/exceptions.py +0 -0
  43. {grimp-3.1 → grimp-3.3}/src/grimp/helpers.py +0 -0
  44. {grimp-3.1 → grimp-3.3}/src/grimp/main.py +0 -0
  45. {grimp-3.1 → grimp-3.3}/src/grimp/py.typed +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: grimp
3
- Version: 3.1
3
+ Version: 3.3
4
4
  Classifier: Development Status :: 5 - Production/Stable
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: BSD License
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.8
12
12
  Classifier: Programming Language :: Python :: 3.9
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
15
16
  Classifier: Programming Language :: Python :: Implementation :: CPython
16
17
  Classifier: Programming Language :: Rust
17
18
  Classifier: Topic :: Utilities
@@ -8,7 +8,7 @@ module-name = "grimp._rustgrimp"
8
8
 
9
9
  [project]
10
10
  name = "grimp"
11
- version = "3.1"
11
+ version = "3.3"
12
12
  license = {text = "BSD 2-Clause License"}
13
13
  description = "Builds a queryable graph of the imports within one or more Python packages."
14
14
  authors = [
@@ -30,6 +30,7 @@ classifiers = [
30
30
  "Programming Language :: Python :: 3.9",
31
31
  "Programming Language :: Python :: 3.10",
32
32
  "Programming Language :: Python :: 3.11",
33
+ "Programming Language :: Python :: 3.12",
33
34
  "Programming Language :: Python :: Implementation :: CPython",
34
35
  "Programming Language :: Rust",
35
36
  "Topic :: Utilities",
@@ -53,4 +54,4 @@ namespaces = false
53
54
 
54
55
  [tool.black]
55
56
  line-length = 99
56
- exclude = 'tests/assets/syntaxerrorpackage'
57
+ exclude = 'tests/assets/syntaxerrorpackage'
@@ -9,6 +9,7 @@ dependencies = [
9
9
  "log",
10
10
  "pyo3",
11
11
  "pyo3-log",
12
+ "rayon",
12
13
  "serde_json",
13
14
  ]
14
15
 
@@ -36,11 +37,48 @@ version = "1.0.0"
36
37
  source = "registry+https://github.com/rust-lang/crates.io-index"
37
38
  checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
38
39
 
40
+ [[package]]
41
+ name = "crossbeam-deque"
42
+ version = "0.8.5"
43
+ source = "registry+https://github.com/rust-lang/crates.io-index"
44
+ checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
45
+ dependencies = [
46
+ "crossbeam-epoch",
47
+ "crossbeam-utils",
48
+ ]
49
+
50
+ [[package]]
51
+ name = "crossbeam-epoch"
52
+ version = "0.9.18"
53
+ source = "registry+https://github.com/rust-lang/crates.io-index"
54
+ checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
55
+ dependencies = [
56
+ "crossbeam-utils",
57
+ ]
58
+
59
+ [[package]]
60
+ name = "crossbeam-utils"
61
+ version = "0.8.20"
62
+ source = "registry+https://github.com/rust-lang/crates.io-index"
63
+ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
64
+
65
+ [[package]]
66
+ name = "either"
67
+ version = "1.12.0"
68
+ source = "registry+https://github.com/rust-lang/crates.io-index"
69
+ checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
70
+
71
+ [[package]]
72
+ name = "heck"
73
+ version = "0.4.1"
74
+ source = "registry+https://github.com/rust-lang/crates.io-index"
75
+ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
76
+
39
77
  [[package]]
40
78
  name = "indoc"
41
- version = "1.0.9"
79
+ version = "2.0.5"
42
80
  source = "registry+https://github.com/rust-lang/crates.io-index"
43
- checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
81
+ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
44
82
 
45
83
  [[package]]
46
84
  name = "itoa"
@@ -108,6 +146,12 @@ dependencies = [
108
146
  "windows-targets",
109
147
  ]
110
148
 
149
+ [[package]]
150
+ name = "portable-atomic"
151
+ version = "1.6.0"
152
+ source = "registry+https://github.com/rust-lang/crates.io-index"
153
+ checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
154
+
111
155
  [[package]]
112
156
  name = "proc-macro2"
113
157
  version = "1.0.64"
@@ -119,15 +163,16 @@ dependencies = [
119
163
 
120
164
  [[package]]
121
165
  name = "pyo3"
122
- version = "0.19.1"
166
+ version = "0.21.2"
123
167
  source = "registry+https://github.com/rust-lang/crates.io-index"
124
- checksum = "ffb88ae05f306b4bfcde40ac4a51dc0b05936a9207a4b75b798c7729c4258a59"
168
+ checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8"
125
169
  dependencies = [
126
170
  "cfg-if",
127
171
  "indoc",
128
172
  "libc",
129
173
  "memoffset",
130
174
  "parking_lot",
175
+ "portable-atomic",
131
176
  "pyo3-build-config",
132
177
  "pyo3-ffi",
133
178
  "pyo3-macros",
@@ -136,9 +181,9 @@ dependencies = [
136
181
 
137
182
  [[package]]
138
183
  name = "pyo3-build-config"
139
- version = "0.19.1"
184
+ version = "0.21.2"
140
185
  source = "registry+https://github.com/rust-lang/crates.io-index"
141
- checksum = "554db24f0b3c180a9c0b1268f91287ab3f17c162e15b54caaae5a6b3773396b0"
186
+ checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50"
142
187
  dependencies = [
143
188
  "once_cell",
144
189
  "target-lexicon",
@@ -146,9 +191,9 @@ dependencies = [
146
191
 
147
192
  [[package]]
148
193
  name = "pyo3-ffi"
149
- version = "0.19.1"
194
+ version = "0.21.2"
150
195
  source = "registry+https://github.com/rust-lang/crates.io-index"
151
- checksum = "922ede8759e8600ad4da3195ae41259654b9c55da4f7eec84a0ccc7d067a70a4"
196
+ checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403"
152
197
  dependencies = [
153
198
  "libc",
154
199
  "pyo3-build-config",
@@ -156,9 +201,9 @@ dependencies = [
156
201
 
157
202
  [[package]]
158
203
  name = "pyo3-log"
159
- version = "0.8.3"
204
+ version = "0.10.0"
160
205
  source = "registry+https://github.com/rust-lang/crates.io-index"
161
- checksum = "f47b0777feb17f61eea78667d61103758b243a871edc09a7786500a50467b605"
206
+ checksum = "2af49834b8d2ecd555177e63b273b708dea75150abc6f5341d0a6e1a9623976c"
162
207
  dependencies = [
163
208
  "arc-swap",
164
209
  "log",
@@ -167,9 +212,9 @@ dependencies = [
167
212
 
168
213
  [[package]]
169
214
  name = "pyo3-macros"
170
- version = "0.19.1"
215
+ version = "0.21.2"
171
216
  source = "registry+https://github.com/rust-lang/crates.io-index"
172
- checksum = "8a5caec6a1dd355964a841fcbeeb1b89fe4146c87295573f94228911af3cc5a2"
217
+ checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c"
173
218
  dependencies = [
174
219
  "proc-macro2",
175
220
  "pyo3-macros-backend",
@@ -179,11 +224,13 @@ dependencies = [
179
224
 
180
225
  [[package]]
181
226
  name = "pyo3-macros-backend"
182
- version = "0.19.1"
227
+ version = "0.21.2"
183
228
  source = "registry+https://github.com/rust-lang/crates.io-index"
184
- checksum = "e0b78ccbb160db1556cdb6fd96c50334c5d4ec44dc5e0a968d0a1208fa0efa8b"
229
+ checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c"
185
230
  dependencies = [
231
+ "heck",
186
232
  "proc-macro2",
233
+ "pyo3-build-config",
187
234
  "quote",
188
235
  "syn",
189
236
  ]
@@ -197,6 +244,26 @@ dependencies = [
197
244
  "proc-macro2",
198
245
  ]
199
246
 
247
+ [[package]]
248
+ name = "rayon"
249
+ version = "1.10.0"
250
+ source = "registry+https://github.com/rust-lang/crates.io-index"
251
+ checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
252
+ dependencies = [
253
+ "either",
254
+ "rayon-core",
255
+ ]
256
+
257
+ [[package]]
258
+ name = "rayon-core"
259
+ version = "1.12.1"
260
+ source = "registry+https://github.com/rust-lang/crates.io-index"
261
+ checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
262
+ dependencies = [
263
+ "crossbeam-deque",
264
+ "crossbeam-utils",
265
+ ]
266
+
200
267
  [[package]]
201
268
  name = "redox_syscall"
202
269
  version = "0.3.5"
@@ -243,9 +310,9 @@ checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
243
310
 
244
311
  [[package]]
245
312
  name = "syn"
246
- version = "1.0.109"
313
+ version = "2.0.32"
247
314
  source = "registry+https://github.com/rust-lang/crates.io-index"
248
- checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
315
+ checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
249
316
  dependencies = [
250
317
  "proc-macro2",
251
318
  "quote",
@@ -266,9 +333,9 @@ checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
266
333
 
267
334
  [[package]]
268
335
  name = "unindent"
269
- version = "0.1.11"
336
+ version = "0.2.3"
270
337
  source = "registry+https://github.com/rust-lang/crates.io-index"
271
- checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
338
+ checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
272
339
 
273
340
  [[package]]
274
341
  name = "windows-targets"
@@ -9,11 +9,12 @@ crate-type = ["cdylib", "rlib"]
9
9
 
10
10
  [dependencies]
11
11
  log = "0.4.19"
12
- pyo3-log = "0.8.3"
12
+ pyo3-log = "0.10.0"
13
13
  serde_json = "1.0.103"
14
+ rayon = "1.10"
14
15
 
15
16
  [dependencies.pyo3]
16
- version = "0.19.1"
17
+ version = "0.21.2"
17
18
 
18
19
  [features]
19
20
  extension-module = ["pyo3/extension-module"]
@@ -1,10 +1,9 @@
1
1
  use crate::importgraph::ImportGraph;
2
2
  use std::collections::HashSet;
3
3
 
4
-
5
4
  pub fn check_containers_exist<'a>(
6
5
  graph: &'a ImportGraph,
7
- containers: &'a HashSet<&'a str>,
6
+ containers: &'a HashSet<String>,
8
7
  ) -> Result<(), String> {
9
8
  for container in containers {
10
9
  if !graph.contains_module(container) {
@@ -2,53 +2,53 @@ use crate::dependencies::{PackageDependency, Route};
2
2
  use crate::importgraph::ImportGraph;
3
3
 
4
4
  use log::info;
5
+ use rayon::prelude::*;
5
6
  use std::collections::HashSet;
6
7
  use std::time::Instant;
7
8
 
8
9
  /// A group of layers at the same level in the layering.
9
- /// These layers should be independent.
10
10
  #[derive(PartialEq, Eq, Hash, Debug)]
11
- pub struct Level<'a> {
12
- pub layers: Vec<&'a str>,
11
+ pub struct Level {
12
+ pub layers: Vec<String>,
13
+ pub independent: bool,
13
14
  }
14
15
 
15
16
  pub fn find_illegal_dependencies<'a>(
16
17
  graph: &'a ImportGraph,
17
18
  levels: &'a Vec<Level>,
18
- containers: &'a HashSet<&'a str>,
19
+ containers: &'a HashSet<String>,
19
20
  ) -> Vec<PackageDependency> {
20
- let mut dependencies: Vec<PackageDependency> = vec![];
21
21
  let layers = _layers_from_levels(levels);
22
22
 
23
- for (higher_layer_package, lower_layer_package, container) in
24
- _generate_module_permutations(graph, levels, containers)
25
- {
26
- // TODO: it's inefficient to do this for sibling layers, as we don't need
27
- // to clone and trim the graph for identical pairs.
28
- info!(
29
- "Searching for import chains from {} to {}...",
30
- lower_layer_package, higher_layer_package
31
- );
32
- let now = Instant::now();
33
- let dependency_or_none = _search_for_package_dependency(
34
- &higher_layer_package,
35
- &lower_layer_package,
36
- &layers,
37
- &container,
38
- graph,
39
- );
40
- _log_illegal_route_count(&dependency_or_none, now.elapsed().as_secs());
41
- if let Some(dependency) = dependency_or_none {
42
- dependencies.push(dependency);
43
- }
44
- }
45
- dependencies
23
+ _generate_module_permutations(graph, levels, containers)
24
+ .into_par_iter()
25
+ .filter_map(|(higher_layer_package, lower_layer_package, container)| {
26
+ // TODO: it's inefficient to do this for sibling layers, as we don't need
27
+ // to clone and trim the graph for identical pairs.
28
+ info!(
29
+ "Searching for import chains from {} to {}...",
30
+ lower_layer_package, higher_layer_package
31
+ );
32
+ let now = Instant::now();
33
+ let dependency_or_none = _search_for_package_dependency(
34
+ &higher_layer_package,
35
+ &lower_layer_package,
36
+ &layers,
37
+ &container,
38
+ graph,
39
+ );
40
+ _log_illegal_route_count(&dependency_or_none, now.elapsed().as_secs());
41
+ dependency_or_none
42
+ })
43
+ .collect()
46
44
  }
47
45
 
46
+ /// Return every permutation of modules that exist in the graph
47
+ /// in which the second should not import the first.
48
48
  fn _generate_module_permutations<'a>(
49
49
  graph: &'a ImportGraph,
50
50
  levels: &'a [Level],
51
- containers: &'a HashSet<&'a str>,
51
+ containers: &'a HashSet<String>,
52
52
  ) -> Vec<(String, String, Option<String>)> {
53
53
  let mut permutations: Vec<(String, String, Option<String>)> = vec![];
54
54
 
@@ -69,13 +69,18 @@ fn _generate_module_permutations<'a>(
69
69
  continue;
70
70
  }
71
71
 
72
- // Build the layers that mustn't import this higher layer. That
73
- // includes lower layers and siblings.
72
+ // Build the layers that mustn't import this higher layer.
73
+ // That includes:
74
+ // * lower layers.
75
+ // * sibling layers, if the layer is independent.
74
76
  let mut layers_forbidden_to_import_higher_layer: Vec<&str> = vec![];
75
- for potential_sibling_layer in &higher_level.layers {
76
- if potential_sibling_layer != higher_layer {
77
- // It's a sibling layer.
78
- layers_forbidden_to_import_higher_layer.push(potential_sibling_layer);
77
+
78
+ if higher_level.independent {
79
+ for potential_sibling_layer in &higher_level.layers {
80
+ if potential_sibling_layer != higher_layer {
81
+ // It's a sibling layer.
82
+ layers_forbidden_to_import_higher_layer.push(potential_sibling_layer);
83
+ }
79
84
  }
80
85
  }
81
86
 
@@ -157,7 +162,7 @@ fn _search_for_package_dependency<'a>(
157
162
  fn _layers_from_levels<'a>(levels: &'a Vec<Level>) -> Vec<&'a str> {
158
163
  let mut layers: Vec<&str> = vec![];
159
164
  for level in levels {
160
- layers.extend(level.layers.iter());
165
+ layers.extend(level.layers.iter().map(|s| s.as_str()));
161
166
  }
162
167
  layers
163
168
  }
@@ -333,13 +338,20 @@ mod tests {
333
338
  ]));
334
339
  let levels = vec![
335
340
  Level {
336
- layers: vec!["high"],
341
+ independent: true,
342
+ layers: vec!["high".to_string()],
337
343
  },
338
344
  Level {
339
- layers: vec!["mid_a", "mid_b", "mid_c"],
345
+ independent: true,
346
+ layers: vec![
347
+ "mid_a".to_string(),
348
+ "mid_b".to_string(),
349
+ "mid_c".to_string(),
350
+ ],
340
351
  },
341
352
  Level {
342
- layers: vec!["low"],
353
+ independent: true,
354
+ layers: vec!["low".to_string()],
343
355
  },
344
356
  ];
345
357
  let containers = HashSet::new();
@@ -405,13 +417,15 @@ mod tests {
405
417
  ]));
406
418
  let levels = vec![
407
419
  Level {
408
- layers: vec!["high"],
420
+ independent: true,
421
+ layers: vec!["high".to_string()],
409
422
  },
410
423
  Level {
411
- layers: vec!["low"],
424
+ independent: true,
425
+ layers: vec!["low".to_string()],
412
426
  },
413
427
  ];
414
- let containers = HashSet::from(["mypackage"]);
428
+ let containers = HashSet::from(["mypackage".to_string()]);
415
429
 
416
430
  let dependencies = find_illegal_dependencies(&graph, &levels, &containers);
417
431
 
@@ -460,16 +474,23 @@ mod tests {
460
474
  ]));
461
475
  let levels = vec![
462
476
  Level {
463
- layers: vec!["high"],
477
+ independent: true,
478
+ layers: vec!["high".to_string()],
464
479
  },
465
480
  Level {
466
- layers: vec!["mid_a", "mid_b", "mid_c"],
481
+ independent: true,
482
+ layers: vec![
483
+ "mid_a".to_string(),
484
+ "mid_b".to_string(),
485
+ "mid_c".to_string(),
486
+ ],
467
487
  },
468
488
  Level {
469
- layers: vec!["low"],
489
+ independent: true,
490
+ layers: vec!["low".to_string()],
470
491
  },
471
492
  ];
472
- let containers = HashSet::from(["mypackage"]);
493
+ let containers = HashSet::from(["mypackage".to_string()]);
473
494
 
474
495
  let perms = _generate_module_permutations(&graph, &levels, &containers);
475
496
 
@@ -553,17 +574,118 @@ mod tests {
553
574
  );
554
575
  }
555
576
 
577
+ #[test]
578
+ fn test_generate_module_permutations_sibling_layer_not_independent() {
579
+ let graph = ImportGraph::new(HashMap::from([
580
+ ("mypackage.low", HashSet::new()),
581
+ ("mypackage.low.blue", HashSet::from(["mypackage.utils"])),
582
+ ("mypackage.low.green", HashSet::new()),
583
+ (
584
+ "mypackage.low.green.alpha",
585
+ HashSet::from(["mypackage.high.yellow"]),
586
+ ),
587
+ ("mypackage.mid_a", HashSet::new()),
588
+ ("mypackage.mid_a.foo", HashSet::new()),
589
+ ("mypackage.mid_b", HashSet::new()),
590
+ ("mypackage.mid_b.foo", HashSet::new()),
591
+ ("mypackage.mid_c", HashSet::new()),
592
+ ("mypackage.mid_c.foo", HashSet::new()),
593
+ ("mypackage.high", HashSet::from(["mypackage.low.blue"])),
594
+ ("mypackage.high.yellow", HashSet::new()),
595
+ ("mypackage.high.red", HashSet::new()),
596
+ ("mypackage.high.red.beta", HashSet::new()),
597
+ ("mypackage.utils", HashSet::from(["mypackage.high.red"])),
598
+ ]));
599
+ let levels = vec![
600
+ Level {
601
+ independent: true,
602
+ layers: vec!["high".to_string()],
603
+ },
604
+ Level {
605
+ independent: false,
606
+ layers: vec![
607
+ "mid_a".to_string(),
608
+ "mid_b".to_string(),
609
+ "mid_c".to_string(),
610
+ ],
611
+ },
612
+ Level {
613
+ independent: true,
614
+ layers: vec!["low".to_string()],
615
+ },
616
+ ];
617
+ let containers = HashSet::from(["mypackage".to_string()]);
618
+
619
+ let perms = _generate_module_permutations(&graph, &levels, &containers);
620
+
621
+ let result: HashSet<(String, String, Option<String>)> = HashSet::from_iter(perms);
622
+ let (high, mid_a, mid_b, mid_c, low) = (
623
+ "mypackage.high",
624
+ "mypackage.mid_a",
625
+ "mypackage.mid_b",
626
+ "mypackage.mid_c",
627
+ "mypackage.low",
628
+ );
629
+ assert_eq!(
630
+ result,
631
+ HashSet::from_iter([
632
+ (
633
+ high.to_string(),
634
+ mid_a.to_string(),
635
+ Some("mypackage".to_string())
636
+ ),
637
+ (
638
+ high.to_string(),
639
+ mid_b.to_string(),
640
+ Some("mypackage".to_string())
641
+ ),
642
+ (
643
+ high.to_string(),
644
+ mid_c.to_string(),
645
+ Some("mypackage".to_string())
646
+ ),
647
+ (
648
+ high.to_string(),
649
+ low.to_string(),
650
+ Some("mypackage".to_string())
651
+ ),
652
+ (
653
+ mid_a.to_string(),
654
+ low.to_string(),
655
+ Some("mypackage".to_string())
656
+ ),
657
+ (
658
+ mid_b.to_string(),
659
+ low.to_string(),
660
+ Some("mypackage".to_string())
661
+ ),
662
+ (
663
+ mid_c.to_string(),
664
+ low.to_string(),
665
+ Some("mypackage".to_string())
666
+ ),
667
+ ])
668
+ );
669
+ }
670
+
556
671
  #[test]
557
672
  fn test_layers_from_levels() {
558
673
  let levels = vec![
559
674
  Level {
560
- layers: vec!["high"],
675
+ independent: true,
676
+ layers: vec!["high".to_string()],
561
677
  },
562
678
  Level {
563
- layers: vec!["medium_a", "medium_b", "medium_c"],
679
+ independent: true,
680
+ layers: vec![
681
+ "medium_a".to_string(),
682
+ "medium_b".to_string(),
683
+ "medium_c".to_string(),
684
+ ],
564
685
  },
565
686
  Level {
566
- layers: vec!["low"],
687
+ independent: true,
688
+ layers: vec!["low".to_string()],
567
689
  },
568
690
  ];
569
691