fluidattacks_core_filesystem 12.0.0__tar.gz → 14.0.0__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.
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/.gitignore +4 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/PKG-INFO +1 -1
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/defaults.py +16 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/detection.py +22 -2
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/partitioning.py +63 -5
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/import-linter.cfg +1 -10
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/pyproject.toml +1 -1
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_partitioning.py +134 -2
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_projects.py +10 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/uv.lock +1 -1
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/.envrc +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/build/default.nix +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/build/filter.nix +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/flake.lock +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/flake.nix +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/__init__.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/language.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/parts.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/projects.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/fluidattacks_core/filesystem/py.typed +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/mypy.ini +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/ruff.toml +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/__init__.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/data/partitioning_snapshot.golden.json +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_defaults.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_extract_db.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_language_detection.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_partitioning_snapshot.py +0 -0
- {fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_parts.py +0 -0
|
@@ -23,6 +23,22 @@ class MarkerSet(TypedDict):
|
|
|
23
23
|
globs: list[str]
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
class WorkspaceSpec(TypedDict):
|
|
27
|
+
declares: frozenset[str]
|
|
28
|
+
claims: frozenset[str]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
BUNDLE_DIR_GLOBS = ["*.xcodeproj", "*.xcworkspace"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
WORKSPACE_MARKERS: dict[str, WorkspaceSpec] = {
|
|
35
|
+
"gradle": {
|
|
36
|
+
"declares": frozenset({"settings.gradle", "settings.gradle.kts"}),
|
|
37
|
+
"claims": frozenset({"build.gradle", "build.gradle.kts"}),
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
26
42
|
CONFIG_MARKERS: dict[Language, MarkerSet] = {
|
|
27
43
|
Language.Java: {
|
|
28
44
|
"names": {
|
|
@@ -3,11 +3,11 @@ from __future__ import annotations
|
|
|
3
3
|
from fnmatch import fnmatch
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
-
from .defaults import CONFIG_MARKERS, MANIFEST_MARKERS, MarkerSet
|
|
6
|
+
from .defaults import CONFIG_MARKERS, MANIFEST_MARKERS, WORKSPACE_MARKERS, MarkerSet
|
|
7
7
|
from .language import Language
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
-
from collections.abc import Iterable
|
|
10
|
+
from collections.abc import Collection, Iterable
|
|
11
11
|
|
|
12
12
|
__all__ = ["detect_anchor_language", "detect_languages_in_dir", "is_config_marker"]
|
|
13
13
|
|
|
@@ -17,6 +17,14 @@ _FOLDED_MARKER_NAMES = frozenset(
|
|
|
17
17
|
|
|
18
18
|
_MARKER_GLOBS = tuple(pat for markers in CONFIG_MARKERS.values() for pat in markers["globs"])
|
|
19
19
|
|
|
20
|
+
_FOLDED_WORKSPACES = {
|
|
21
|
+
kind: (
|
|
22
|
+
frozenset(name.casefold() for name in spec["declares"]),
|
|
23
|
+
frozenset(name.casefold() for name in spec["claims"]),
|
|
24
|
+
)
|
|
25
|
+
for kind, spec in WORKSPACE_MARKERS.items()
|
|
26
|
+
}
|
|
27
|
+
|
|
20
28
|
_FOLDED_MANIFESTS = {
|
|
21
29
|
language: frozenset(name.casefold() for name in names)
|
|
22
30
|
for language, names in MANIFEST_MARKERS.items()
|
|
@@ -112,3 +120,15 @@ def detect_anchor_language(files: Iterable[str]) -> Language | None:
|
|
|
112
120
|
sorted(anchors, key=lambda language: language.value)
|
|
113
121
|
)
|
|
114
122
|
return ranked[0] if len(ranked) == 1 else Language.Unknown
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def declared_workspaces(files: Iterable[str]) -> frozenset[str]:
|
|
126
|
+
folded = {name.casefold() for name in files}
|
|
127
|
+
return frozenset(
|
|
128
|
+
kind for kind, (declares, _) in _FOLDED_WORKSPACES.items() if declares & folded
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def is_claimed_manifest(name: str, kinds: Collection[str]) -> bool:
|
|
133
|
+
folded = name.casefold()
|
|
134
|
+
return any(folded in _FOLDED_WORKSPACES[kind][1] for kind in kinds)
|
|
@@ -9,8 +9,14 @@ from fnmatch import fnmatch
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import TYPE_CHECKING
|
|
11
11
|
|
|
12
|
-
from .defaults import EXTENDED_EXCLUDE_DIRS
|
|
13
|
-
from .detection import
|
|
12
|
+
from .defaults import BUNDLE_DIR_GLOBS, EXTENDED_EXCLUDE_DIRS
|
|
13
|
+
from .detection import (
|
|
14
|
+
declared_workspaces,
|
|
15
|
+
detect_anchor_language,
|
|
16
|
+
detect_languages_in_dir,
|
|
17
|
+
is_claimed_manifest,
|
|
18
|
+
is_config_marker,
|
|
19
|
+
)
|
|
14
20
|
from .parts import Part, PartIdentity, PartTree
|
|
15
21
|
|
|
16
22
|
if TYPE_CHECKING:
|
|
@@ -63,11 +69,63 @@ def _root_filenames(listing: DirListing, root_path: Path) -> tuple[str, ...]:
|
|
|
63
69
|
return ()
|
|
64
70
|
|
|
65
71
|
|
|
66
|
-
def
|
|
72
|
+
def _workspace_kinds_by_dir(listing: DirListing) -> Mapping[Path, frozenset[str]]:
|
|
73
|
+
return {
|
|
74
|
+
dir_path: kinds
|
|
75
|
+
for dir_path, filenames in listing
|
|
76
|
+
if (kinds := declared_workspaces(filenames))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _claiming_kinds(dir_path: Path, workspaces: Mapping[Path, frozenset[str]]) -> frozenset[str]:
|
|
81
|
+
kinds: set[str] = set()
|
|
82
|
+
current = dir_path
|
|
83
|
+
while current != current.parent:
|
|
84
|
+
current = current.parent
|
|
85
|
+
kinds.update(workspaces.get(current, frozenset()))
|
|
86
|
+
return frozenset(kinds)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _is_bundle_name(name: str) -> bool:
|
|
90
|
+
return any(fnmatch(name, pattern) for pattern in BUNDLE_DIR_GLOBS)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _within_bundle(dir_path: Path, root_path: Path) -> bool:
|
|
94
|
+
current = dir_path
|
|
95
|
+
while current != root_path:
|
|
96
|
+
if _is_bundle_name(current.name):
|
|
97
|
+
return True
|
|
98
|
+
if current == current.parent:
|
|
99
|
+
return False
|
|
100
|
+
current = current.parent
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _anchor_names(
|
|
105
|
+
dir_path: Path,
|
|
106
|
+
filenames: Sequence[str],
|
|
107
|
+
workspaces: Mapping[Path, frozenset[str]],
|
|
108
|
+
root_path: Path,
|
|
109
|
+
) -> tuple[str, ...]:
|
|
110
|
+
if _within_bundle(dir_path, root_path):
|
|
111
|
+
return ()
|
|
112
|
+
kinds = _claiming_kinds(dir_path, workspaces)
|
|
113
|
+
if not kinds:
|
|
114
|
+
return tuple(filenames)
|
|
115
|
+
return tuple(name for name in filenames if not is_claimed_manifest(name, kinds))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _discover_potential_parts(listing: DirListing, root_path: Path) -> tuple[PotentialPart, ...]:
|
|
119
|
+
workspaces = _workspace_kinds_by_dir(listing)
|
|
67
120
|
return tuple(
|
|
68
121
|
(dir_path, _find_config_files(dir_path, filenames), language.value)
|
|
69
122
|
for dir_path, filenames in listing
|
|
70
|
-
if (
|
|
123
|
+
if (
|
|
124
|
+
language := detect_anchor_language(
|
|
125
|
+
_anchor_names(dir_path, filenames, workspaces, root_path)
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
is not None
|
|
71
129
|
)
|
|
72
130
|
|
|
73
131
|
|
|
@@ -187,7 +245,7 @@ def _build_single_root_tree(root_path: Path, listing: DirListing) -> PartTree:
|
|
|
187
245
|
|
|
188
246
|
|
|
189
247
|
def decide_part_tree(root_path: Path, listing: DirListing) -> PartTree:
|
|
190
|
-
potential_parts = _discover_potential_parts(listing)
|
|
248
|
+
potential_parts = _discover_potential_parts(listing, root_path)
|
|
191
249
|
if not potential_parts:
|
|
192
250
|
return _build_single_root_tree(root_path, listing)
|
|
193
251
|
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/import-linter.cfg
RENAMED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
[importlinter]
|
|
2
|
-
root_package = fluidattacks_core
|
|
2
|
+
root_package = fluidattacks_core.filesystem
|
|
3
3
|
include_external_packages = True
|
|
4
4
|
|
|
5
|
-
[importlinter:contract:portion]
|
|
6
|
-
name = Single Portion
|
|
7
|
-
type = layers
|
|
8
|
-
containers =
|
|
9
|
-
fluidattacks_core
|
|
10
|
-
exhaustive = true
|
|
11
|
-
layers =
|
|
12
|
-
filesystem
|
|
13
|
-
|
|
14
5
|
[importlinter:contract:dag]
|
|
15
6
|
name = Direct Acyclic Graph
|
|
16
7
|
type = layers
|
|
@@ -5,6 +5,7 @@ import pytest
|
|
|
5
5
|
|
|
6
6
|
from fluidattacks_core.filesystem import build_part_tree
|
|
7
7
|
from fluidattacks_core.filesystem.partitioning import (
|
|
8
|
+
DirListing,
|
|
8
9
|
PotentialPart,
|
|
9
10
|
_assign_files_to_parts,
|
|
10
11
|
_build_hierarchy,
|
|
@@ -28,6 +29,17 @@ _LISTING = (
|
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
|
|
32
|
+
_GRADLE_ROOT = Path("/service")
|
|
33
|
+
|
|
34
|
+
_GRADLE_MODULES = (
|
|
35
|
+
"applications/app-service",
|
|
36
|
+
"domain/model",
|
|
37
|
+
"domain/usecase",
|
|
38
|
+
"infrastructure/driven-adapters/rest-consumer",
|
|
39
|
+
"infrastructure/entry-points/reactive-web",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
31
43
|
def test_part_names_are_posix_relative_paths() -> None:
|
|
32
44
|
assert _generate_part_name(_ROOT, _ROOT) == "."
|
|
33
45
|
assert _generate_part_name(_ROOT / "web", _ROOT) == "web"
|
|
@@ -41,7 +53,7 @@ def test_config_files_are_found_by_name_and_glob() -> None:
|
|
|
41
53
|
|
|
42
54
|
|
|
43
55
|
def test_only_directories_holding_a_manifest_become_parts() -> None:
|
|
44
|
-
discovered = _discover_potential_parts(_LISTING)
|
|
56
|
+
discovered = _discover_potential_parts(_LISTING, _ROOT)
|
|
45
57
|
assert [(path, language) for path, _, language in discovered] == [
|
|
46
58
|
(_ROOT, "Python"),
|
|
47
59
|
(_ROOT / "web", "JavaScript"),
|
|
@@ -49,7 +61,7 @@ def test_only_directories_holding_a_manifest_become_parts() -> None:
|
|
|
49
61
|
|
|
50
62
|
|
|
51
63
|
def test_a_lone_hint_does_not_make_a_potential_part() -> None:
|
|
52
|
-
assert _discover_potential_parts(((_ROOT / "tools", ("mypy.ini", "tox.ini")),)) == ()
|
|
64
|
+
assert _discover_potential_parts(((_ROOT / "tools", ("mypy.ini", "tox.ini")),), _ROOT) == ()
|
|
53
65
|
|
|
54
66
|
|
|
55
67
|
def test_hierarchy_nests_parts_under_their_nearest_ancestor() -> None:
|
|
@@ -189,6 +201,126 @@ def test_part_names_stay_unique_for_nested_directories() -> None:
|
|
|
189
201
|
assert sorted(names) == [".", "a/svc", "b/svc"]
|
|
190
202
|
|
|
191
203
|
|
|
204
|
+
def _gradle_listing(suffix: str) -> DirListing:
|
|
205
|
+
return (
|
|
206
|
+
(_GRADLE_ROOT, (f"settings{suffix}", f"build{suffix}", "gradlew")),
|
|
207
|
+
*(
|
|
208
|
+
(_GRADLE_ROOT.joinpath(*module.split("/")), (f"build{suffix}",))
|
|
209
|
+
for module in _GRADLE_MODULES
|
|
210
|
+
),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def test_a_settings_file_claims_every_subproject_manifest() -> None:
|
|
215
|
+
tree = decide_part_tree(_GRADLE_ROOT, _gradle_listing(".gradle"))
|
|
216
|
+
|
|
217
|
+
assert sorted(tree.parts) == ["."]
|
|
218
|
+
assert tree.children_map["."] == ()
|
|
219
|
+
root = tree.root
|
|
220
|
+
assert root is not None
|
|
221
|
+
assert root.detected_language == "Java"
|
|
222
|
+
assert Path("domain/model/build.gradle") in root.files
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def test_the_kotlin_gradle_dsl_collapses_the_same_way() -> None:
|
|
226
|
+
tree = decide_part_tree(_GRADLE_ROOT, _gradle_listing(".gradle.kts"))
|
|
227
|
+
|
|
228
|
+
assert sorted(tree.parts) == ["."]
|
|
229
|
+
root = tree.root
|
|
230
|
+
assert root is not None
|
|
231
|
+
assert root.detected_language == "Kotlin"
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def test_a_settings_file_claims_the_other_gradle_dsl() -> None:
|
|
235
|
+
listing = (
|
|
236
|
+
(_GRADLE_ROOT, ("settings.gradle",)),
|
|
237
|
+
(_GRADLE_ROOT / "mod", ("build.gradle.kts",)),
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
assert sorted(decide_part_tree(_GRADLE_ROOT, listing).parts) == ["."]
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_a_nested_workspace_anchors_but_its_modules_do_not() -> None:
|
|
244
|
+
listing = (
|
|
245
|
+
(_GRADLE_ROOT, ("settings.gradle",)),
|
|
246
|
+
(_GRADLE_ROOT / "sub", ("settings.gradle", "build.gradle")),
|
|
247
|
+
(_GRADLE_ROOT / "sub" / "mod", ("build.gradle",)),
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
assert sorted(decide_part_tree(_GRADLE_ROOT, listing).parts) == [".", "sub"]
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def test_a_claimed_directory_with_its_own_settings_still_anchors() -> None:
|
|
254
|
+
listing = (
|
|
255
|
+
(_GRADLE_ROOT, ("settings.gradle", "build.gradle")),
|
|
256
|
+
(_GRADLE_ROOT / "mod", ("build.gradle",)),
|
|
257
|
+
(_GRADLE_ROOT / "deployment" / "acceptance-test", ("settings.gradle", "build.gradle")),
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
assert sorted(decide_part_tree(_GRADLE_ROOT, listing).parts) == [
|
|
261
|
+
".",
|
|
262
|
+
"deployment/acceptance-test",
|
|
263
|
+
]
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_a_workspace_does_not_claim_a_foreign_manifest() -> None:
|
|
267
|
+
listing = (
|
|
268
|
+
(_GRADLE_ROOT, ("settings.gradle", "build.gradle")),
|
|
269
|
+
(_GRADLE_ROOT / "frontend", ("build.gradle", "package.json")),
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
tree = decide_part_tree(_GRADLE_ROOT, listing)
|
|
273
|
+
|
|
274
|
+
assert sorted(tree.parts) == [".", "frontend"]
|
|
275
|
+
frontend = tree.get_part("frontend")
|
|
276
|
+
assert frontend is not None
|
|
277
|
+
assert frontend.detected_language == "JavaScript"
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
def test_a_gradle_module_without_a_settings_file_anchors_alone() -> None:
|
|
281
|
+
listing = (
|
|
282
|
+
(_GRADLE_ROOT, ("README",)),
|
|
283
|
+
(_GRADLE_ROOT / "deployment" / "acceptance-test", ("build.gradle",)),
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
tree = decide_part_tree(_GRADLE_ROOT, listing)
|
|
287
|
+
|
|
288
|
+
assert sorted(tree.parts) == [".", "deployment/acceptance-test"]
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def test_an_xcode_bundle_does_not_anchor_beside_its_project() -> None:
|
|
292
|
+
listing = (
|
|
293
|
+
(_ROOT, ("pubspec.yaml",)),
|
|
294
|
+
(_ROOT / "app" / "ios", ("Podfile",)),
|
|
295
|
+
(_ROOT / "app" / "ios" / "Runner.xcodeproj", ("project.pbxproj",)),
|
|
296
|
+
(_ROOT / "app" / "ios" / "Runner.xcworkspace", ("project.pbxproj",)),
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
assert sorted(decide_part_tree(_ROOT, listing).parts) == [".", "app/ios"]
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def test_a_manifest_nested_inside_a_bundle_does_not_anchor() -> None:
|
|
303
|
+
listing = (
|
|
304
|
+
(_ROOT, ("Podfile",)),
|
|
305
|
+
(_ROOT / "Runner.xcodeproj", ("project.pbxproj",)),
|
|
306
|
+
(_ROOT / "Runner.xcodeproj" / "project.xcworkspace", ("Package.swift",)),
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
assert sorted(decide_part_tree(_ROOT, listing).parts) == ["."]
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def test_a_root_named_like_a_bundle_still_anchors() -> None:
|
|
313
|
+
root = Path("/Thing.xcodeproj")
|
|
314
|
+
|
|
315
|
+
assert sorted(decide_part_tree(root, ((root, ("project.pbxproj",)),)).parts) == ["."]
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def test_a_swift_package_outside_a_bundle_still_anchors() -> None:
|
|
319
|
+
listing = ((_ROOT, ("README",)), (_ROOT / "lib", ("Package.swift",)))
|
|
320
|
+
|
|
321
|
+
assert sorted(decide_part_tree(_ROOT, listing).parts) == [".", "lib"]
|
|
322
|
+
|
|
323
|
+
|
|
192
324
|
def _write(root: Path, files: list[str]) -> None:
|
|
193
325
|
for name in files:
|
|
194
326
|
path = root / name
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_projects.py
RENAMED
|
@@ -6,6 +6,7 @@ import pytest
|
|
|
6
6
|
|
|
7
7
|
from fluidattacks_core.filesystem import (
|
|
8
8
|
Language,
|
|
9
|
+
build_part_tree,
|
|
9
10
|
detect_root_language,
|
|
10
11
|
find_parent_project,
|
|
11
12
|
find_projects,
|
|
@@ -270,3 +271,12 @@ def test_no_marker_name_is_excluded_as_an_artifact() -> None:
|
|
|
270
271
|
if any(fnmatch(name, pat) for pat in EXCLUDE_FILES)
|
|
271
272
|
]
|
|
272
273
|
assert excluded == []
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def test_find_projects_still_splits_a_gradle_workspace(tmp_path: Path) -> None:
|
|
277
|
+
_make(tmp_path, ["settings.gradle", "build.gradle", "mod/build.gradle"])
|
|
278
|
+
root = tmp_path.resolve()
|
|
279
|
+
|
|
280
|
+
assert _by_path(find_projects(tmp_path), root) == {".": "Java", "mod": "Java"}
|
|
281
|
+
assert find_parent_project(root / "mod" / "build.gradle", root) == (root / "mod", "Java")
|
|
282
|
+
assert sorted(build_part_tree(tmp_path).parts) == ["."]
|
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/build/default.nix
RENAMED
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/build/filter.nix
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_defaults.py
RENAMED
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_extract_db.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_core_filesystem-12.0.0 → fluidattacks_core_filesystem-14.0.0}/tests/test_parts.py
RENAMED
|
File without changes
|