gulp-cli 1.1.6__tar.gz → 1.1.8__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 (68) hide show
  1. {gulp_cli-1.1.6/src/gulp_cli.egg-info → gulp_cli-1.1.8}/PKG-INFO +1 -1
  2. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/_version.py +3 -3
  3. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/ingest.py +25 -6
  4. {gulp_cli-1.1.6 → gulp_cli-1.1.8/src/gulp_cli.egg-info}/PKG-INFO +1 -1
  5. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/SOURCES.txt +2 -0
  6. gulp_cli-1.1.8/src/gulp_cli.egg-info/scm_file_list.json +61 -0
  7. gulp_cli-1.1.8/src/gulp_cli.egg-info/scm_version.json +8 -0
  8. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/tests/test_zip_create.py +45 -2
  9. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/.github/workflows/portable-bundles.yml +0 -0
  10. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/.github/workflows/python-package.yml +0 -0
  11. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/.gitignore +0 -0
  12. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/GULP_DUAL_LICENSE.txt +0 -0
  13. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/LICENSE.AGPL-3.0.txt +0 -0
  14. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/LICENSE.md +0 -0
  15. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/README.md +0 -0
  16. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/command-reference.md +0 -0
  17. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/examples.md +0 -0
  18. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/extensions.md +0 -0
  19. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/getting-started.md +0 -0
  20. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/portable.md +0 -0
  21. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/resource-management.md +0 -0
  22. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/docs/troubleshooting-cli.md +0 -0
  23. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/gulp-cli.spec +0 -0
  24. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/portable/launch-linux.sh +0 -0
  25. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/portable/launch-macos.sh +0 -0
  26. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/portable/launch-windows.bat +0 -0
  27. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/pyproject.toml +0 -0
  28. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/setup.cfg +0 -0
  29. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/__init__.py +0 -0
  30. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/__main__.py +0 -0
  31. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/cli.py +0 -0
  32. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/client.py +0 -0
  33. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/__init__.py +0 -0
  34. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/acl.py +0 -0
  35. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/auth.py +0 -0
  36. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/collab.py +0 -0
  37. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/context.py +0 -0
  38. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/db.py +0 -0
  39. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/enhance_map.py +0 -0
  40. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/enrich.py +0 -0
  41. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/glyph.py +0 -0
  42. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/mapping.py +0 -0
  43. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/operations.py +0 -0
  44. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/plugin.py +0 -0
  45. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/query.py +0 -0
  46. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/source.py +0 -0
  47. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/stats.py +0 -0
  48. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/storage.py +0 -0
  49. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/user_group.py +0 -0
  50. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/users.py +0 -0
  51. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/commands/utility.py +0 -0
  52. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/config.py +0 -0
  53. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/extension/__init__.py +0 -0
  54. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/extension/query_sigma_zip.py +0 -0
  55. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/extension/story.py +0 -0
  56. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/extension_helpers.py +0 -0
  57. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/extensions.py +0 -0
  58. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/output.py +0 -0
  59. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/utils.py +0 -0
  60. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli/version.py +0 -0
  61. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/dependency_links.txt +0 -0
  62. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/entry_points.txt +0 -0
  63. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/requires.txt +0 -0
  64. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/top_level.txt +0 -0
  65. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/tests/test_enrich_live.py +0 -0
  66. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/tests/test_ingest_paths_file.py +0 -0
  67. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/tests/test_ingest_wait_log.py +0 -0
  68. {gulp_cli-1.1.6 → gulp_cli-1.1.8}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gulp-cli
3
- Version: 1.1.6
3
+ Version: 1.1.8
4
4
  Summary: Command-line client for gULP
5
5
  Author-email: Mentat <info@mentat.is>
6
6
  Requires-Python: >=3.12
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.1.6'
22
- __version_tuple__ = version_tuple = (1, 1, 6)
21
+ __version__ = version = '1.1.8'
22
+ __version_tuple__ = version_tuple = (1, 1, 8)
23
23
 
24
- __commit_id__ = commit_id = 'g8d034cc8b'
24
+ __commit_id__ = commit_id = 'g6f1fa3720'
@@ -280,6 +280,29 @@ def _resolve_glob_base(pattern_path: Path) -> Path:
280
280
  return base_dir.resolve()
281
281
 
282
282
 
283
+ def _safe_archive_name(path: str) -> str:
284
+ """Return a ZIP entry path without roots or dot-directory components."""
285
+ return "/".join(
286
+ _zip_path_part(part)
287
+ for part in path.replace("\\", "/").split("/")
288
+ if part not in ("", ".", "..")
289
+ )
290
+
291
+
292
+ def _zip_path_part(part: str) -> str:
293
+ if re.fullmatch(r"[A-Za-z]:", part):
294
+ return part[0]
295
+ return part
296
+
297
+
298
+ def _preserved_archive_name(source_path: Path) -> str:
299
+ try:
300
+ absolute_path = source_path.resolve()
301
+ except OSError:
302
+ absolute_path = Path(os.path.abspath(source_path))
303
+ return _safe_archive_name(str(absolute_path))
304
+
305
+
283
306
  def _build_zip_from_sources(
284
307
  output_zip: Path,
285
308
  sources: list[tuple[Path, Path]],
@@ -299,16 +322,12 @@ def _build_zip_from_sources(
299
322
 
300
323
  def _archive_name_for_path(source_path: Path, base_dir: Path) -> str:
301
324
  if preserve_path:
302
- try:
303
- rel_path = os.path.relpath(source_path, Path.cwd())
304
- except ValueError:
305
- rel_path = source_path.name
306
- return Path(rel_path).as_posix()
325
+ return _preserved_archive_name(source_path)
307
326
  try:
308
327
  rel_path = source_path.relative_to(base_dir)
309
328
  except ValueError:
310
329
  rel_path = source_path.name
311
- return rel_path.as_posix()
330
+ return _safe_archive_name(rel_path.as_posix())
312
331
 
313
332
  planned_entries: list[tuple[Path, Path, str]] = []
314
333
  for source_path, base_dir in sources:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gulp-cli
3
- Version: 1.1.6
3
+ Version: 1.1.8
4
4
  Summary: Command-line client for gULP
5
5
  Author-email: Mentat <info@mentat.is>
6
6
  Requires-Python: >=3.12
@@ -33,6 +33,8 @@ src/gulp_cli.egg-info/SOURCES.txt
33
33
  src/gulp_cli.egg-info/dependency_links.txt
34
34
  src/gulp_cli.egg-info/entry_points.txt
35
35
  src/gulp_cli.egg-info/requires.txt
36
+ src/gulp_cli.egg-info/scm_file_list.json
37
+ src/gulp_cli.egg-info/scm_version.json
36
38
  src/gulp_cli.egg-info/top_level.txt
37
39
  src/gulp_cli/commands/__init__.py
38
40
  src/gulp_cli/commands/acl.py
@@ -0,0 +1,61 @@
1
+ {
2
+ "files": [
3
+ "GULP_DUAL_LICENSE.txt",
4
+ "README.md",
5
+ "pyproject.toml",
6
+ "LICENSE.AGPL-3.0.txt",
7
+ "LICENSE.md",
8
+ "gulp-cli.spec",
9
+ ".gitignore",
10
+ "portable/launch-windows.bat",
11
+ "portable/launch-linux.sh",
12
+ "portable/launch-macos.sh",
13
+ "docs/troubleshooting-cli.md",
14
+ "docs/examples.md",
15
+ "docs/getting-started.md",
16
+ "docs/extensions.md",
17
+ "docs/resource-management.md",
18
+ "docs/portable.md",
19
+ "docs/command-reference.md",
20
+ "src/gulp_cli/__init__.py",
21
+ "src/gulp_cli/version.py",
22
+ "src/gulp_cli/extension_helpers.py",
23
+ "src/gulp_cli/output.py",
24
+ "src/gulp_cli/config.py",
25
+ "src/gulp_cli/utils.py",
26
+ "src/gulp_cli/client.py",
27
+ "src/gulp_cli/extensions.py",
28
+ "src/gulp_cli/cli.py",
29
+ "src/gulp_cli/__main__.py",
30
+ "src/gulp_cli/extension/query_sigma_zip.py",
31
+ "src/gulp_cli/extension/story.py",
32
+ "src/gulp_cli/extension/__init__.py",
33
+ "src/gulp_cli/commands/__init__.py",
34
+ "src/gulp_cli/commands/source.py",
35
+ "src/gulp_cli/commands/ingest.py",
36
+ "src/gulp_cli/commands/users.py",
37
+ "src/gulp_cli/commands/glyph.py",
38
+ "src/gulp_cli/commands/context.py",
39
+ "src/gulp_cli/commands/acl.py",
40
+ "src/gulp_cli/commands/user_group.py",
41
+ "src/gulp_cli/commands/utility.py",
42
+ "src/gulp_cli/commands/operations.py",
43
+ "src/gulp_cli/commands/auth.py",
44
+ "src/gulp_cli/commands/stats.py",
45
+ "src/gulp_cli/commands/enrich.py",
46
+ "src/gulp_cli/commands/query.py",
47
+ "src/gulp_cli/commands/enhance_map.py",
48
+ "src/gulp_cli/commands/storage.py",
49
+ "src/gulp_cli/commands/db.py",
50
+ "src/gulp_cli/commands/collab.py",
51
+ "src/gulp_cli/commands/mapping.py",
52
+ "src/gulp_cli/commands/plugin.py",
53
+ "tests/test_ingest_paths_file.py",
54
+ "tests/test_version.py",
55
+ "tests/test_enrich_live.py",
56
+ "tests/test_zip_create.py",
57
+ "tests/test_ingest_wait_log.py",
58
+ ".github/workflows/portable-bundles.yml",
59
+ ".github/workflows/python-package.yml"
60
+ ]
61
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "tag": "1.1.8",
3
+ "distance": 0,
4
+ "node": "g6f1fa372096bd3824cc9172417c6b33f5fcebbc1",
5
+ "dirty": false,
6
+ "branch": "HEAD",
7
+ "node_date": "2026-06-24"
8
+ }
@@ -12,6 +12,7 @@ import typer
12
12
  from gulp_cli.commands.ingest import (
13
13
  _build_zip_from_sources,
14
14
  _expand_source_patterns,
15
+ _safe_archive_name,
15
16
  ingest_zip_create,
16
17
  )
17
18
  from gulp_cli.config import set_runtime_config_dir
@@ -87,11 +88,53 @@ def test_build_zip_from_sources_preserves_path_when_requested(
87
88
  )
88
89
 
89
90
  assert archived_count == 1
90
- assert archived_entries == ["samples/nested/data.json"]
91
+ assert archived_entries == [_safe_archive_name(str(source_file.resolve()))]
91
92
  assert len(created_archives) == 1
92
93
 
93
94
  with zipfile.ZipFile(created_archives[0]) as archive:
94
- assert archive.namelist() == ["samples/nested/data.json"]
95
+ assert archive.namelist() == archived_entries
96
+
97
+
98
+ @pytest.mark.parametrize(
99
+ ("path", "expected"),
100
+ [
101
+ ("./samples/nested/data.json", "samples/nested/data.json"),
102
+ (".\\samples\\nested\\data.json", "samples/nested/data.json"),
103
+ ("../../../samples/nested/data.json", "samples/nested/data.json"),
104
+ ("C:\\samples\\nested\\data.json", "C/samples/nested/data.json"),
105
+ ("\\\\server\\share\\samples\\nested\\data.json", "server/share/samples/nested/data.json"),
106
+ ],
107
+ )
108
+ def test_safe_archive_name_strips_roots_and_dot_paths(
109
+ path: str, expected: str
110
+ ) -> None:
111
+ assert _safe_archive_name(path) == expected
112
+
113
+
114
+ def test_build_zip_from_sources_strips_parent_paths_when_preserving(
115
+ tmp_path: Path, monkeypatch
116
+ ) -> None:
117
+ source_dir = tmp_path / "samples" / "win_evtx"
118
+ source_dir.mkdir(parents=True)
119
+ source_file = source_dir / "2-system-Microsoft-Windows-LiveId%4Operational.evtx"
120
+ source_file.write_text("payload", encoding="utf-8")
121
+ cwd = tmp_path / "a" / "b" / "c"
122
+ cwd.mkdir(parents=True)
123
+ monkeypatch.chdir(cwd)
124
+
125
+ output_zip = tmp_path / "out.zip"
126
+ archived_count, archived_entries, created_archives = _build_zip_from_sources(
127
+ output_zip,
128
+ [(source_file, source_dir.parent)],
129
+ preserve_path=True,
130
+ )
131
+
132
+ expected = _safe_archive_name(str(source_file.resolve()))
133
+ assert archived_count == 1
134
+ assert archived_entries == [expected]
135
+
136
+ with zipfile.ZipFile(created_archives[0]) as archive:
137
+ assert archive.namelist() == [expected]
95
138
 
96
139
 
97
140
  def test_build_zip_from_sources_prints_file_progress(
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
File without changes
File without changes
File without changes
File without changes