gulp-cli 1.0.9__tar.gz → 1.1.2__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 (56) hide show
  1. gulp_cli-1.1.2/.github/workflows/portable-bundles.yml +179 -0
  2. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/PKG-INFO +19 -2
  3. gulp_cli-1.0.9/src/gulp_cli.egg-info/PKG-INFO → gulp_cli-1.1.2/README.md +16 -13
  4. gulp_cli-1.1.2/docs/portable.md +76 -0
  5. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/troubleshooting-cli.md +91 -4
  6. gulp_cli-1.1.2/gulp-cli.spec +83 -0
  7. gulp_cli-1.1.2/portable/launch-linux.sh +8 -0
  8. gulp_cli-1.1.2/portable/launch-macos.sh +8 -0
  9. gulp_cli-1.1.2/portable/launch-windows.bat +9 -0
  10. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/pyproject.toml +4 -6
  11. gulp_cli-1.1.2/src/gulp_cli/__main__.py +28 -0
  12. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/_version.py +3 -3
  13. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/cli.py +18 -2
  14. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/context.py +2 -6
  15. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/ingest.py +161 -52
  16. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/source.py +56 -16
  17. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/config.py +78 -16
  18. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/extensions.py +5 -6
  19. gulp_cli-1.0.9/README.md → gulp_cli-1.1.2/src/gulp_cli.egg-info/PKG-INFO +30 -1
  20. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli.egg-info/SOURCES.txt +6 -0
  21. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli.egg-info/requires.txt +3 -0
  22. gulp_cli-1.0.9/src/gulp_cli/__main__.py +0 -11
  23. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/.github/workflows/python-package.yml +0 -0
  24. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/.gitignore +0 -0
  25. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/command-reference.md +0 -0
  26. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/examples.md +0 -0
  27. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/extensions.md +0 -0
  28. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/getting-started.md +0 -0
  29. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/docs/resource-management.md +0 -0
  30. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/setup.cfg +0 -0
  31. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/__init__.py +0 -0
  32. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/client.py +0 -0
  33. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/__init__.py +0 -0
  34. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/acl.py +0 -0
  35. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/auth.py +0 -0
  36. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/collab.py +0 -0
  37. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/db.py +0 -0
  38. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/enhance_map.py +0 -0
  39. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/glyph.py +0 -0
  40. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/mapping.py +0 -0
  41. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/operations.py +0 -0
  42. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/plugin.py +0 -0
  43. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/query.py +0 -0
  44. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/stats.py +0 -0
  45. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/storage.py +0 -0
  46. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/user_group.py +0 -0
  47. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/commands/users.py +0 -0
  48. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/extension/__init__.py +0 -0
  49. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/extension/query_sigma_zip.py +0 -0
  50. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/extension/story.py +0 -0
  51. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/extension_helpers.py +0 -0
  52. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/output.py +0 -0
  53. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli/utils.py +0 -0
  54. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli.egg-info/dependency_links.txt +0 -0
  55. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli.egg-info/entry_points.txt +0 -0
  56. {gulp_cli-1.0.9 → gulp_cli-1.1.2}/src/gulp_cli.egg-info/top_level.txt +0 -0
@@ -0,0 +1,179 @@
1
+ name: Portable bundles
2
+
3
+ "on":
4
+ push:
5
+ tags: ['v*', 'test-v*']
6
+ release:
7
+ types: [published]
8
+ workflow_dispatch: {}
9
+
10
+ permissions:
11
+ contents: write
12
+
13
+ jobs:
14
+ build-portable:
15
+ name: Build portable bundle (${{ matrix.bundle_name }})
16
+ runs-on: ${{ matrix.os }}
17
+ timeout-minutes: 90
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ include:
22
+ - os: ubuntu-latest
23
+ bundle_name: gulp-cli-portable-linux-x64
24
+ launcher_path: portable/launch-linux.sh
25
+ - os: windows-latest
26
+ bundle_name: gulp-cli-portable-windows-x64
27
+ launcher_path: portable/launch-windows.bat
28
+ - os: macos-14
29
+ bundle_name: gulp-cli-portable-macos-arm64
30
+ launcher_path: portable/launch-macos.sh
31
+
32
+ steps:
33
+ - name: Checkout repository
34
+ uses: actions/checkout@v4
35
+
36
+ - name: Set up Python
37
+ uses: actions/setup-python@v5
38
+ with:
39
+ python-version: '3.13'
40
+
41
+ - name: Install dependencies
42
+ run: |
43
+ python -m pip install --upgrade pip
44
+ python -m pip install . pyinstaller
45
+
46
+ - name: Build executable
47
+ run: |
48
+ pyinstaller --noconfirm --clean gulp-cli.spec
49
+
50
+ - name: Assemble portable layout
51
+ shell: python
52
+ env:
53
+ BUNDLE_NAME: ${{ matrix.bundle_name }}
54
+ LAUNCHER_PATH: ${{ matrix.launcher_path }}
55
+ run: |
56
+ import os
57
+ import shutil
58
+ from pathlib import Path
59
+
60
+ dist_dir = Path("dist")
61
+ source_dir = dist_dir / "gulp-cli"
62
+ bundle_dir = dist_dir / os.environ["BUNDLE_NAME"]
63
+ launcher_path = Path(os.environ["LAUNCHER_PATH"])
64
+
65
+ if bundle_dir.exists():
66
+ shutil.rmtree(bundle_dir)
67
+
68
+ shutil.copytree(source_dir, bundle_dir)
69
+ (bundle_dir / "data" / "extension").mkdir(parents=True, exist_ok=True)
70
+ shutil.copy2(launcher_path, bundle_dir / launcher_path.name)
71
+ shutil.copy2("README.md", bundle_dir / "README.md")
72
+
73
+ - name: Upload portable artifact
74
+ uses: actions/upload-artifact@v4
75
+ with:
76
+ name: ${{ matrix.bundle_name }}
77
+ path: dist/${{ matrix.bundle_name }}
78
+ if-no-files-found: error
79
+
80
+ - name: Create release archive
81
+ shell: python
82
+ env:
83
+ BUNDLE_NAME: ${{ matrix.bundle_name }}
84
+ run: |
85
+ import os
86
+ import shutil
87
+ from pathlib import Path
88
+
89
+ dist_dir = Path("dist")
90
+ bundle_name = os.environ["BUNDLE_NAME"]
91
+ bundle_dir = dist_dir / bundle_name
92
+ archive_base = dist_dir / bundle_name
93
+ shutil.make_archive(str(archive_base), "zip", root_dir=bundle_dir.parent, base_dir=bundle_dir.name)
94
+
95
+ - name: Upload release asset
96
+ if: github.event_name == 'release'
97
+ uses: softprops/action-gh-release@v2
98
+ with:
99
+ tag_name: ${{ github.event.release.tag_name }}
100
+ files: dist/${{ matrix.bundle_name }}.zip
101
+ fail_on_unmatched_files: true
102
+
103
+ build-portable-macos-x64:
104
+ name: Build portable bundle (gulp-cli-portable-macos-x64)
105
+ if: github.event_name == 'workflow_dispatch' || github.event_name == 'release'
106
+ continue-on-error: ${{ github.event_name == 'release' }}
107
+ runs-on: macos-15-intel
108
+ timeout-minutes: 90
109
+
110
+ steps:
111
+ - name: Checkout repository
112
+ uses: actions/checkout@v4
113
+
114
+ - name: Set up Python
115
+ uses: actions/setup-python@v5
116
+ with:
117
+ python-version: '3.13'
118
+
119
+ - name: Install dependencies
120
+ run: |
121
+ python -m pip install --upgrade pip
122
+ python -m pip install . pyinstaller
123
+
124
+ - name: Build executable
125
+ run: |
126
+ pyinstaller --noconfirm --clean gulp-cli.spec
127
+
128
+ - name: Assemble portable layout
129
+ shell: python
130
+ env:
131
+ BUNDLE_NAME: gulp-cli-portable-macos-x64
132
+ LAUNCHER_PATH: portable/launch-macos.sh
133
+ run: |
134
+ import os
135
+ import shutil
136
+ from pathlib import Path
137
+
138
+ dist_dir = Path("dist")
139
+ source_dir = dist_dir / "gulp-cli"
140
+ bundle_dir = dist_dir / os.environ["BUNDLE_NAME"]
141
+ launcher_path = Path(os.environ["LAUNCHER_PATH"])
142
+
143
+ if bundle_dir.exists():
144
+ shutil.rmtree(bundle_dir)
145
+
146
+ shutil.copytree(source_dir, bundle_dir)
147
+ (bundle_dir / "data" / "extension").mkdir(parents=True, exist_ok=True)
148
+ shutil.copy2(launcher_path, bundle_dir / launcher_path.name)
149
+ shutil.copy2("README.md", bundle_dir / "README.md")
150
+
151
+ - name: Upload portable artifact
152
+ uses: actions/upload-artifact@v4
153
+ with:
154
+ name: gulp-cli-portable-macos-x64
155
+ path: dist/gulp-cli-portable-macos-x64
156
+ if-no-files-found: error
157
+
158
+ - name: Create release archive
159
+ shell: python
160
+ env:
161
+ BUNDLE_NAME: gulp-cli-portable-macos-x64
162
+ run: |
163
+ import os
164
+ import shutil
165
+ from pathlib import Path
166
+
167
+ dist_dir = Path("dist")
168
+ bundle_name = os.environ["BUNDLE_NAME"]
169
+ bundle_dir = dist_dir / bundle_name
170
+ archive_base = dist_dir / bundle_name
171
+ shutil.make_archive(str(archive_base), "zip", root_dir=bundle_dir.parent, base_dir=bundle_dir.name)
172
+
173
+ - name: Upload release asset
174
+ if: github.event_name == 'release'
175
+ uses: softprops/action-gh-release@v2
176
+ with:
177
+ tag_name: ${{ github.event.release.tag_name }}
178
+ files: dist/gulp-cli-portable-macos-x64.zip
179
+ fail_on_unmatched_files: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gulp-cli
3
- Version: 1.0.9
3
+ Version: 1.1.2
4
4
  Summary: Command-line client for gULP
5
5
  Author-email: Mentat <info@mentat.is>
6
6
  Requires-Python: >=3.12
@@ -9,6 +9,8 @@ Requires-Dist: typer==0.23.1
9
9
  Requires-Dist: rich==15.0.0
10
10
  Requires-Dist: click==8.3.3
11
11
  Requires-Dist: gulp-sdk
12
+ Provides-Extra: portable
13
+ Requires-Dist: pyinstaller<7,>=6.11; extra == "portable"
12
14
 
13
15
  # 🚀 gulp-cli
14
16
 
@@ -41,6 +43,9 @@ All with **beautiful terminal output**, **automatic tab completion**, and **asyn
41
43
  # from pip
42
44
  pip install gulp-cli
43
45
 
46
+ # or install local portable-build tooling
47
+ pip install 'gulp-cli[portable]'
48
+
44
49
  # or, for the latest development version:
45
50
  python3 -m venv ./.venv
46
51
  source ./.venv/bin/activate
@@ -51,10 +56,20 @@ cd gulp-cli && pip install -e .
51
56
  gulp-cli --help
52
57
  ```
53
58
 
59
+ ### Portable Bundles
60
+
61
+ For offline use from a USB stick, prefer the OS-specific portable bundles built with PyInstaller instead of `pip install`.
62
+
63
+ - Each target OS needs its own bundle: Linux, Windows, macOS Intel, macOS Apple Silicon.
64
+ - Portable bundles keep config and external extensions in a local `data/` directory next to the executable.
65
+ - You can override that location with `GULP_CLI_HOME` or `--config-dir`.
66
+
67
+ See **[Portable Usage](./docs/portable.md)** for the layout, local build command, and CI artifact details.
68
+
54
69
  ### Basic Usage
55
70
 
56
71
  > for the cli to work, set `"ws_ignore_missing": true` (should be default in the v1.6.51 backend, though ...) in your `gulp_cfg.json` to prevent the backend from halting operations when the CLI disconnects its websocket after sending an async request!
57
-
72
+
58
73
  ```bash
59
74
  # Login to your gULP instance
60
75
  gulp-cli auth login --url http://localhost:8080 --username admin --password admin
@@ -71,6 +86,7 @@ gulp-cli ingest file my_operation win_evtx 'samples/win_evtx/*.evtx'
71
86
  # Query documents
72
87
  gulp-cli query raw my_operation --q '{"query":{"match_all":{}}}'
73
88
  ```
89
+
74
90
  ---
75
91
 
76
92
  ## 📚 Documentation
@@ -78,6 +94,7 @@ gulp-cli query raw my_operation --q '{"query":{"match_all":{}}}'
78
94
  - **[Getting Started Guide](./docs/getting-started.md)** — auth, first operation, first ingest
79
95
  - **[Command Reference](./docs/command-reference.md)** — all available commands and options
80
96
  - **[Extensions Guide](./docs/extensions.md)** — dynamic extension loading and custom command contract
97
+ - **[Portable Usage](./docs/portable.md)** — offline bundles and USB-friendly layout
81
98
  - **[Resource Management Commands](./docs/resource-management.md)** — context, source, plugin, mapping, enhance-map, glyph
82
99
  - **[Practical Examples](./docs/examples.md)** — real-world workflows and recipes
83
100
  - **[Troubleshooting](./docs/troubleshooting-cli.md)** — common issues and solutions
@@ -1,15 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: gulp-cli
3
- Version: 1.0.9
4
- Summary: Command-line client for gULP
5
- Author-email: Mentat <info@mentat.is>
6
- Requires-Python: >=3.12
7
- Description-Content-Type: text/markdown
8
- Requires-Dist: typer==0.23.1
9
- Requires-Dist: rich==15.0.0
10
- Requires-Dist: click==8.3.3
11
- Requires-Dist: gulp-sdk
12
-
13
1
  # 🚀 gulp-cli
14
2
 
15
3
  **A modern, powerful command-line interface for gULP** — manage forensic document ingestion, querying, enrichment, and collaboration entirely from your terminal.
@@ -41,6 +29,9 @@ All with **beautiful terminal output**, **automatic tab completion**, and **asyn
41
29
  # from pip
42
30
  pip install gulp-cli
43
31
 
32
+ # or install local portable-build tooling
33
+ pip install 'gulp-cli[portable]'
34
+
44
35
  # or, for the latest development version:
45
36
  python3 -m venv ./.venv
46
37
  source ./.venv/bin/activate
@@ -51,10 +42,20 @@ cd gulp-cli && pip install -e .
51
42
  gulp-cli --help
52
43
  ```
53
44
 
45
+ ### Portable Bundles
46
+
47
+ For offline use from a USB stick, prefer the OS-specific portable bundles built with PyInstaller instead of `pip install`.
48
+
49
+ - Each target OS needs its own bundle: Linux, Windows, macOS Intel, macOS Apple Silicon.
50
+ - Portable bundles keep config and external extensions in a local `data/` directory next to the executable.
51
+ - You can override that location with `GULP_CLI_HOME` or `--config-dir`.
52
+
53
+ See **[Portable Usage](./docs/portable.md)** for the layout, local build command, and CI artifact details.
54
+
54
55
  ### Basic Usage
55
56
 
56
57
  > for the cli to work, set `"ws_ignore_missing": true` (should be default in the v1.6.51 backend, though ...) in your `gulp_cfg.json` to prevent the backend from halting operations when the CLI disconnects its websocket after sending an async request!
57
-
58
+
58
59
  ```bash
59
60
  # Login to your gULP instance
60
61
  gulp-cli auth login --url http://localhost:8080 --username admin --password admin
@@ -71,6 +72,7 @@ gulp-cli ingest file my_operation win_evtx 'samples/win_evtx/*.evtx'
71
72
  # Query documents
72
73
  gulp-cli query raw my_operation --q '{"query":{"match_all":{}}}'
73
74
  ```
75
+
74
76
  ---
75
77
 
76
78
  ## 📚 Documentation
@@ -78,6 +80,7 @@ gulp-cli query raw my_operation --q '{"query":{"match_all":{}}}'
78
80
  - **[Getting Started Guide](./docs/getting-started.md)** — auth, first operation, first ingest
79
81
  - **[Command Reference](./docs/command-reference.md)** — all available commands and options
80
82
  - **[Extensions Guide](./docs/extensions.md)** — dynamic extension loading and custom command contract
83
+ - **[Portable Usage](./docs/portable.md)** — offline bundles and USB-friendly layout
81
84
  - **[Resource Management Commands](./docs/resource-management.md)** — context, source, plugin, mapping, enhance-map, glyph
82
85
  - **[Practical Examples](./docs/examples.md)** — real-world workflows and recipes
83
86
  - **[Troubleshooting](./docs/troubleshooting-cli.md)** — common issues and solutions
@@ -0,0 +1,76 @@
1
+ # Portable gulp-cli
2
+
3
+ Portable bundles are the recommended way to run `gulp-cli` from removable media or on machines without internet access.
4
+
5
+ ## What portable means here
6
+
7
+ - You build one bundle per target OS and architecture.
8
+ - The bundle already contains Python, `gulp-cli`, `gulp-sdk`, and runtime dependencies.
9
+ - User state lives in a local `data/` folder instead of the user profile.
10
+
11
+ There is no single executable that runs unchanged on Linux, Windows, and macOS. Build and ship one artifact for each platform:
12
+
13
+ - Linux `x86_64`
14
+ - Windows `x86_64`
15
+ - macOS `x86_64`
16
+ - macOS `arm64`
17
+
18
+ ## Portable layout
19
+
20
+ The CI workflow produces a directory like this:
21
+
22
+ ```text
23
+ gulp-cli-portable-<platform>/
24
+ gulp-cli[.exe]
25
+ _internal/
26
+ launch-linux.sh | launch-macos.sh | launch-windows.bat
27
+ data/
28
+ extension/
29
+ README.md
30
+ ```
31
+
32
+ `gulp-cli` automatically uses `./data` when running from a frozen bundle and that directory exists.
33
+
34
+ ## Runtime overrides
35
+
36
+ The CLI supports both of these overrides:
37
+
38
+ ```bash
39
+ GULP_CLI_HOME=/path/to/portable-data gulp-cli auth whoami
40
+ gulp-cli --config-dir /path/to/portable-data auth whoami
41
+ ```
42
+
43
+ The overridden directory stores:
44
+
45
+ - `config.json`
46
+ - `extension/`
47
+
48
+ ## Local build
49
+
50
+ Build a portable bundle locally from the repo root:
51
+
52
+ ```bash
53
+ python -m pip install --upgrade pip
54
+ python -m pip install '.[portable]'
55
+ pyinstaller --noconfirm --clean gulp-cli.spec
56
+ ```
57
+
58
+ The output is written under `dist/gulp-cli/`.
59
+
60
+ ## Notes for offline USB use
61
+
62
+ - Build bundles on CI or on a machine with internet access first.
63
+ - Copy the resulting platform-specific bundle folders to the USB stick.
64
+ - The target machine does not need Python or internet access.
65
+ - The target machine still needs network connectivity to the gULP server unless that server is local.
66
+
67
+ ## GitHub Actions
68
+
69
+ The repository includes a matrix workflow that builds portable artifacts for:
70
+
71
+ - Linux `x86_64`
72
+ - Windows `x86_64`
73
+ - macOS `x86_64`
74
+ - macOS `arm64`
75
+
76
+ Artifacts are uploaded from `.github/workflows/portable-bundles.yml`.