ext4-cli 0.0.1__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.
@@ -0,0 +1,77 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+
20
+ - uses: dtolnay/rust-toolchain@stable
21
+ with:
22
+ components: rustfmt, clippy
23
+
24
+ - name: Run linting
25
+ run: make lint
26
+
27
+ test:
28
+ name: Test
29
+ runs-on: ubuntu-latest
30
+ steps:
31
+ - uses: actions/checkout@v4
32
+
33
+ - uses: dtolnay/rust-toolchain@stable
34
+
35
+ - uses: taiki-e/install-action@nextest
36
+
37
+ - name: Generate fixtures
38
+ run: make fixtures
39
+
40
+ - name: Run tests
41
+ run: make test
42
+
43
+ coverage:
44
+ name: Coverage
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+
49
+ - uses: dtolnay/rust-toolchain@stable
50
+
51
+ - uses: taiki-e/install-action@cargo-tarpaulin
52
+
53
+ - name: Generate fixtures
54
+ run: make fixtures
55
+
56
+ - name: Generate coverage
57
+ run: cargo tarpaulin --out xml
58
+
59
+ - name: Upload to Codecov
60
+ uses: codecov/codecov-action@v5
61
+ with:
62
+ files: cobertura.xml
63
+ token: ${{ secrets.CODECOV_TOKEN }}
64
+
65
+ all-checks-passed:
66
+ name: All checks passed
67
+ runs-on: ubuntu-latest
68
+ needs: [lint, test]
69
+ if: always()
70
+ steps:
71
+ - name: Verify all checks passed
72
+ run: |
73
+ if [ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]; then
74
+ echo "Some checks failed or were cancelled"
75
+ exit 1
76
+ fi
77
+ echo "All checks passed"
@@ -0,0 +1,286 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v[0-9]*.[0-9]*.[0-9]*'
7
+ workflow_dispatch:
8
+ inputs:
9
+ dry_run:
10
+ description: 'Dry run (skip publishing)'
11
+ required: false
12
+ default: true
13
+ type: boolean
14
+ skip_crates_io:
15
+ description: 'Skip crates.io publish (if already published)'
16
+ required: false
17
+ default: false
18
+ type: boolean
19
+ skip_pypi:
20
+ description: 'Skip PyPI publish (if already published)'
21
+ required: false
22
+ default: false
23
+ type: boolean
24
+ skip_github_release:
25
+ description: 'Skip GitHub release creation (if already exists)'
26
+ required: false
27
+ default: false
28
+ type: boolean
29
+
30
+ permissions:
31
+ contents: write
32
+
33
+ env:
34
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35
+
36
+ jobs:
37
+ test:
38
+ name: Run tests
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+
43
+ - uses: dtolnay/rust-toolchain@stable
44
+
45
+ - uses: taiki-e/install-action@nextest
46
+
47
+ - name: Verify Cargo.lock is up to date
48
+ run: cargo check --locked
49
+
50
+ - name: Generate fixtures
51
+ run: make fixtures
52
+
53
+ - name: Run tests
54
+ run: make test
55
+
56
+ build:
57
+ name: Build ${{ matrix.target }}
58
+ needs: test
59
+ strategy:
60
+ matrix:
61
+ include:
62
+ - target: x86_64-unknown-linux-gnu
63
+ os: ubuntu-latest
64
+ - target: aarch64-unknown-linux-gnu
65
+ os: ubuntu-latest
66
+ - target: x86_64-apple-darwin
67
+ os: macos-latest
68
+ - target: aarch64-apple-darwin
69
+ os: macos-latest
70
+ runs-on: ${{ matrix.os }}
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+
74
+ - uses: dtolnay/rust-toolchain@stable
75
+ with:
76
+ targets: ${{ matrix.target }}
77
+
78
+ - name: Install cross-compilation tools
79
+ if: matrix.target == 'aarch64-unknown-linux-gnu'
80
+ run: |
81
+ sudo apt-get update
82
+ sudo apt-get install -y gcc-aarch64-linux-gnu
83
+
84
+ - name: Install maturin and zig
85
+ run: pip install maturin ziglang
86
+
87
+ - name: Build wheel
88
+ shell: bash
89
+ run: |
90
+ case "${{ matrix.target }}" in
91
+ *-gnu)
92
+ maturin build --release --target ${{ matrix.target }} --zig
93
+ ;;
94
+ *)
95
+ maturin build --release --target ${{ matrix.target }}
96
+ ;;
97
+ esac
98
+
99
+ - name: Build binary
100
+ run: cargo build --release --target ${{ matrix.target }}
101
+ env:
102
+ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
103
+
104
+ - name: Package binary
105
+ shell: bash
106
+ run: |
107
+ ARCHIVE_NAME="ext4-${{ github.ref_name }}-${{ matrix.target }}"
108
+ mkdir -p "${ARCHIVE_NAME}"
109
+ cp "target/${{ matrix.target }}/release/ext4" "${ARCHIVE_NAME}/"
110
+ tar czf "${ARCHIVE_NAME}.tar.gz" "${ARCHIVE_NAME}"
111
+ if [[ "${{ runner.os }}" == "macOS" ]]; then
112
+ shasum -a 256 "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
113
+ else
114
+ sha256sum "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
115
+ fi
116
+
117
+ - uses: actions/upload-artifact@v4
118
+ with:
119
+ name: build-${{ matrix.target }}
120
+ path: |
121
+ ext4-*.tar.gz
122
+ ext4-*.tar.gz.sha256
123
+ target/wheels/*.whl
124
+
125
+ sdist:
126
+ name: Build source distribution
127
+ needs: test
128
+ runs-on: ubuntu-latest
129
+ steps:
130
+ - uses: actions/checkout@v4
131
+
132
+ - name: Install maturin
133
+ run: pip install maturin
134
+
135
+ - name: Build sdist
136
+ run: maturin sdist
137
+
138
+ - uses: actions/upload-artifact@v4
139
+ with:
140
+ name: sdist
141
+ path: target/wheels/*.tar.gz
142
+
143
+ release:
144
+ name: Release
145
+ needs: [build, sdist]
146
+ runs-on: ubuntu-latest
147
+ steps:
148
+ - uses: actions/checkout@v4
149
+
150
+ - uses: dtolnay/rust-toolchain@stable
151
+
152
+ - uses: actions/download-artifact@v4
153
+ with:
154
+ path: /tmp/artifacts
155
+
156
+ - name: Publish to crates.io
157
+ if: ${{ !inputs.dry_run && !inputs.skip_crates_io }}
158
+ run: cargo publish --locked
159
+ env:
160
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
161
+
162
+ - name: Test crates.io publish (dry run)
163
+ if: ${{ inputs.dry_run == true && !inputs.skip_crates_io }}
164
+ run: cargo publish --dry-run --locked
165
+
166
+ - name: Skip crates.io publishing
167
+ if: ${{ inputs.skip_crates_io == true }}
168
+ run: echo "Skipping crates.io publishing as requested"
169
+
170
+ - name: Install uv
171
+ uses: astral-sh/setup-uv@v6
172
+
173
+ - name: Publish to PyPI
174
+ if: ${{ !inputs.dry_run && !inputs.skip_pypi }}
175
+ run: uv publish /tmp/artifacts/build-*/*.whl /tmp/artifacts/sdist/*.tar.gz
176
+ env:
177
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
178
+
179
+ - name: Test PyPI publish (dry run)
180
+ if: ${{ inputs.dry_run == true && !inputs.skip_pypi }}
181
+ run: |
182
+ echo "DRY RUN: Would upload to PyPI:"
183
+ find /tmp/artifacts/build-* -name "*.whl" -type f | sort
184
+ find /tmp/artifacts/sdist -name "*.tar.gz" -type f | sort
185
+ uv tool run twine check /tmp/artifacts/build-*/*.whl /tmp/artifacts/sdist/*.tar.gz
186
+
187
+ - name: Skip PyPI publishing
188
+ if: ${{ inputs.skip_pypi == true }}
189
+ run: echo "Skipping PyPI publishing as requested"
190
+
191
+ - name: Create GitHub Release
192
+ if: ${{ !inputs.dry_run && !inputs.skip_github_release }}
193
+ run: |
194
+ gh release create ${{ github.ref_name }} \
195
+ --title "${{ github.ref_name }}" \
196
+ --generate-notes \
197
+ /tmp/artifacts/build-*/*.tar.gz \
198
+ /tmp/artifacts/build-*/*.sha256
199
+ env:
200
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
201
+
202
+ - name: Dry Run Summary
203
+ if: ${{ inputs.dry_run == true }}
204
+ run: |
205
+ echo "Dry run complete. Artifacts built but nothing published."
206
+ find /tmp/artifacts -type f | sort
207
+
208
+ update-homebrew:
209
+ name: Update Homebrew formula
210
+ needs: release
211
+ if: ${{ !inputs.dry_run && !inputs.skip_github_release }}
212
+ runs-on: ubuntu-latest
213
+ steps:
214
+ - uses: actions/download-artifact@v4
215
+ with:
216
+ path: /tmp/artifacts
217
+
218
+ - name: Compute SHA256 hashes
219
+ id: hashes
220
+ run: |
221
+ for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
222
+ sha=$(cat /tmp/artifacts/build-${target}/ext4-${{ github.ref_name }}-${target}.tar.gz.sha256 | awk '{print $1}')
223
+ key=$(echo "${target}" | tr '-' '_')
224
+ echo "${key}=${sha}" >> "$GITHUB_OUTPUT"
225
+ done
226
+
227
+ - name: Update Homebrew formula
228
+ env:
229
+ GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
230
+ run: |
231
+ VERSION="${{ github.ref_name }}"
232
+ VERSION_NUM="${VERSION#v}"
233
+
234
+ cat > /tmp/ext4.rb << 'FORMULA'
235
+ class Ext4 < Formula
236
+ desc "Read ext4 filesystems from image files and block devices"
237
+ homepage "https://github.com/rvben/ext4-cli"
238
+ version "VERSION_NUM"
239
+ license "MIT"
240
+
241
+ on_macos do
242
+ if Hardware::CPU.arm?
243
+ url "https://github.com/rvben/ext4-cli/releases/download/VERSION/ext4-VERSION-aarch64-apple-darwin.tar.gz"
244
+ sha256 "SHA_AARCH64_APPLE_DARWIN"
245
+ else
246
+ url "https://github.com/rvben/ext4-cli/releases/download/VERSION/ext4-VERSION-x86_64-apple-darwin.tar.gz"
247
+ sha256 "SHA_X86_64_APPLE_DARWIN"
248
+ end
249
+ end
250
+
251
+ on_linux do
252
+ if Hardware::CPU.arm?
253
+ url "https://github.com/rvben/ext4-cli/releases/download/VERSION/ext4-VERSION-aarch64-unknown-linux-gnu.tar.gz"
254
+ sha256 "SHA_AARCH64_UNKNOWN_LINUX_GNU"
255
+ else
256
+ url "https://github.com/rvben/ext4-cli/releases/download/VERSION/ext4-VERSION-x86_64-unknown-linux-gnu.tar.gz"
257
+ sha256 "SHA_X86_64_UNKNOWN_LINUX_GNU"
258
+ end
259
+ end
260
+
261
+ def install
262
+ bin.install "ext4"
263
+ end
264
+
265
+ test do
266
+ system "#{bin}/ext4", "--version"
267
+ end
268
+ end
269
+ FORMULA
270
+
271
+ sed -i "s/VERSION_NUM/${VERSION_NUM}/g" /tmp/ext4.rb
272
+ sed -i "s/VERSION/${VERSION}/g" /tmp/ext4.rb
273
+ sed -i "s/SHA_AARCH64_APPLE_DARWIN/${{ steps.hashes.outputs.aarch64_apple_darwin }}/g" /tmp/ext4.rb
274
+ sed -i "s/SHA_X86_64_APPLE_DARWIN/${{ steps.hashes.outputs.x86_64_apple_darwin }}/g" /tmp/ext4.rb
275
+ sed -i "s/SHA_AARCH64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.aarch64_unknown_linux_gnu }}/g" /tmp/ext4.rb
276
+ sed -i "s/SHA_X86_64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.x86_64_unknown_linux_gnu }}/g" /tmp/ext4.rb
277
+
278
+ git clone https://x-access-token:${GH_TOKEN}@github.com/rvben/homebrew-tap.git /tmp/tap
279
+ mkdir -p /tmp/tap/Formula
280
+ cp /tmp/ext4.rb /tmp/tap/Formula/ext4.rb
281
+ cd /tmp/tap
282
+ git config user.name "github-actions[bot]"
283
+ git config user.email "github-actions[bot]@users.noreply.github.com"
284
+ git add Formula/ext4.rb
285
+ git diff --cached --quiet || git commit -m "Update ext4 to ${VERSION}"
286
+ git push
@@ -0,0 +1 @@
1
+ /target
@@ -0,0 +1,26 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## [0.0.1] - 2026-04-13
8
+
9
+ ### Added
10
+
11
+ - **cp**: extract files and directories from ext4 filesystem ([6f1c1a0](https://github.com/rvben/ext4-cli/commit/6f1c1a0a0b77d4e573ce73323317912c6fa656fe))
12
+ - **cat**: stream file contents to stdout ([7331180](https://github.com/rvben/ext4-cli/commit/7331180d30af9ab8039cb6d53fc02bb239cd5405))
13
+ - **stat**: show inode metadata for files and directories ([544b10e](https://github.com/rvben/ext4-cli/commit/544b10e3c48e8872651d9601ae43f912cf84e602))
14
+ - **ls**: list ext4 directory contents with JSON support ([9a65503](https://github.com/rvben/ext4-cli/commit/9a655032fe0963f3e54243b2ae4bedb5b920d3d4))
15
+ - **info**: show filesystem info via superblock parsing ([b420404](https://github.com/rvben/ext4-cli/commit/b4204041844b7b690ad8310cdc5495a8b705df7b))
16
+ - **output**: mode formatting and JSON printer ([33a2497](https://github.com/rvben/ext4-cli/commit/33a24979f7ccd4d849b6b2721904da1c60c8ff78))
17
+ - **source**: open ext4 image files and block devices ([6913ee9](https://github.com/rvben/ext4-cli/commit/6913ee9586c93ef81c6221fe316be6bb70884b88))
18
+
19
+ ### Fixed
20
+
21
+ - **tests**: remove redundant serde_json import ([e41fb6e](https://github.com/rvben/ext4-cli/commit/e41fb6e7166472d26b1694a5ee3204031c6341e6))
22
+ - **main**: collapse nested if-let for permission denied check ([a89b255](https://github.com/rvben/ext4-cli/commit/a89b2556cf5cf508b68b2707c6d702fb4918ff0f))
23
+ - **source**: use sector-aligned reads for raw block device compatibility ([7183d50](https://github.com/rvben/ext4-cli/commit/7183d50dc3f29a0f02d4db253cf68899fbff99c7))
24
+ - **ls**: classify all FileType variants correctly, add --all flag tests ([607c742](https://github.com/rvben/ext4-cli/commit/607c7429801d4410e028300cf448bc5361274bad))
25
+ - **info**: correct metadata_csum bitmask, add gdt_csum/dir_nlink/extra_isize, safe block_size shift ([4d3b73d](https://github.com/rvben/ext4-cli/commit/4d3b73d4deb69e6c236ebe0e05c2e5a2fb071291))
26
+ - **fixtures**: clean up partial images on failure ([9375a46](https://github.com/rvben/ext4-cli/commit/9375a465d8b14669662c177af03594f0941eca85))