gulp-cli 1.1.7__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 (69) hide show
  1. {gulp_cli-1.1.7/src/gulp_cli.egg-info → gulp_cli-1.1.8}/PKG-INFO +1 -1
  2. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/_version.py +3 -3
  3. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/ingest.py +24 -13
  4. {gulp_cli-1.1.7 → gulp_cli-1.1.8/src/gulp_cli.egg-info}/PKG-INFO +1 -1
  5. gulp_cli-1.1.8/src/gulp_cli.egg-info/scm_version.json +8 -0
  6. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/tests/test_zip_create.py +15 -27
  7. gulp_cli-1.1.7/src/gulp_cli.egg-info/scm_version.json +0 -8
  8. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/.github/workflows/portable-bundles.yml +0 -0
  9. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/.github/workflows/python-package.yml +0 -0
  10. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/.gitignore +0 -0
  11. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/GULP_DUAL_LICENSE.txt +0 -0
  12. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/LICENSE.AGPL-3.0.txt +0 -0
  13. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/LICENSE.md +0 -0
  14. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/README.md +0 -0
  15. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/command-reference.md +0 -0
  16. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/examples.md +0 -0
  17. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/extensions.md +0 -0
  18. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/getting-started.md +0 -0
  19. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/portable.md +0 -0
  20. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/resource-management.md +0 -0
  21. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/docs/troubleshooting-cli.md +0 -0
  22. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/gulp-cli.spec +0 -0
  23. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/portable/launch-linux.sh +0 -0
  24. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/portable/launch-macos.sh +0 -0
  25. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/portable/launch-windows.bat +0 -0
  26. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/pyproject.toml +0 -0
  27. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/setup.cfg +0 -0
  28. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/__init__.py +0 -0
  29. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/__main__.py +0 -0
  30. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/cli.py +0 -0
  31. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/client.py +0 -0
  32. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/__init__.py +0 -0
  33. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/acl.py +0 -0
  34. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/auth.py +0 -0
  35. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/collab.py +0 -0
  36. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/context.py +0 -0
  37. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/db.py +0 -0
  38. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/enhance_map.py +0 -0
  39. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/enrich.py +0 -0
  40. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/glyph.py +0 -0
  41. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/mapping.py +0 -0
  42. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/operations.py +0 -0
  43. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/plugin.py +0 -0
  44. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/query.py +0 -0
  45. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/source.py +0 -0
  46. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/stats.py +0 -0
  47. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/storage.py +0 -0
  48. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/user_group.py +0 -0
  49. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/users.py +0 -0
  50. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/commands/utility.py +0 -0
  51. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/config.py +0 -0
  52. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/extension/__init__.py +0 -0
  53. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/extension/query_sigma_zip.py +0 -0
  54. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/extension/story.py +0 -0
  55. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/extension_helpers.py +0 -0
  56. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/extensions.py +0 -0
  57. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/output.py +0 -0
  58. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/utils.py +0 -0
  59. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli/version.py +0 -0
  60. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/SOURCES.txt +0 -0
  61. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/dependency_links.txt +0 -0
  62. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/entry_points.txt +0 -0
  63. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/requires.txt +0 -0
  64. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/scm_file_list.json +0 -0
  65. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/src/gulp_cli.egg-info/top_level.txt +0 -0
  66. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/tests/test_enrich_live.py +0 -0
  67. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/tests/test_ingest_paths_file.py +0 -0
  68. {gulp_cli-1.1.7 → gulp_cli-1.1.8}/tests/test_ingest_wait_log.py +0 -0
  69. {gulp_cli-1.1.7 → 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.7
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.7'
22
- __version_tuple__ = version_tuple = (1, 1, 7)
21
+ __version__ = version = '1.1.8'
22
+ __version_tuple__ = version_tuple = (1, 1, 8)
23
23
 
24
- __commit_id__ = commit_id = 'g5f188bb2b'
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]],
@@ -297,21 +320,9 @@ def _build_zip_from_sources(
297
320
  total_entries = 0
298
321
  entries_added = 0
299
322
 
300
- def _safe_archive_name(path: str) -> str:
301
- """Return a ZIP entry path without dot-directory components."""
302
- return "/".join(
303
- part
304
- for part in path.replace("\\", "/").split("/")
305
- if part not in ("", ".", "..")
306
- )
307
-
308
323
  def _archive_name_for_path(source_path: Path, base_dir: Path) -> str:
309
324
  if preserve_path:
310
- try:
311
- rel_path = os.path.relpath(source_path, Path.cwd())
312
- except ValueError:
313
- rel_path = source_path.name
314
- return _safe_archive_name(rel_path)
325
+ return _preserved_archive_name(source_path)
315
326
  try:
316
327
  rel_path = source_path.relative_to(base_dir)
317
328
  except ValueError:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gulp-cli
3
- Version: 1.1.7
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
@@ -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,40 +88,27 @@ 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
95
96
 
96
97
 
97
98
  @pytest.mark.parametrize(
98
- "rel_path",
99
- ["./samples/nested/data.json", ".\\samples\\nested\\data.json"],
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
+ ],
100
107
  )
101
- def test_build_zip_from_sources_strips_current_dir_paths_when_preserving(
102
- tmp_path: Path, monkeypatch, rel_path: str
108
+ def test_safe_archive_name_strips_roots_and_dot_paths(
109
+ path: str, expected: str
103
110
  ) -> None:
104
- source_file = tmp_path / "data.json"
105
- source_file.write_text('{"value": 1}', encoding="utf-8")
106
- monkeypatch.setattr(
107
- "gulp_cli.commands.ingest.os.path.relpath",
108
- lambda _source_path, _cwd: rel_path,
109
- )
110
-
111
- output_zip = tmp_path / "out.zip"
112
- archived_count, archived_entries, created_archives = _build_zip_from_sources(
113
- output_zip,
114
- [(source_file, tmp_path)],
115
- preserve_path=True,
116
- )
117
-
118
- expected = "samples/nested/data.json"
119
- assert archived_count == 1
120
- assert archived_entries == [expected]
121
-
122
- with zipfile.ZipFile(created_archives[0]) as archive:
123
- assert archive.namelist() == [expected]
111
+ assert _safe_archive_name(path) == expected
124
112
 
125
113
 
126
114
  def test_build_zip_from_sources_strips_parent_paths_when_preserving(
@@ -141,7 +129,7 @@ def test_build_zip_from_sources_strips_parent_paths_when_preserving(
141
129
  preserve_path=True,
142
130
  )
143
131
 
144
- expected = "samples/win_evtx/2-system-Microsoft-Windows-LiveId%4Operational.evtx"
132
+ expected = _safe_archive_name(str(source_file.resolve()))
145
133
  assert archived_count == 1
146
134
  assert archived_entries == [expected]
147
135
 
@@ -1,8 +0,0 @@
1
- {
2
- "tag": "1.1.7",
3
- "distance": 0,
4
- "node": "g5f188bb2b8862aa3c0a6ca011bef91125feed6a5",
5
- "dirty": false,
6
- "branch": "HEAD",
7
- "node_date": "2026-06-23"
8
- }
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