downstat 0.1.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.
- downstat-0.1.0/.github/workflows/ci.yml +47 -0
- downstat-0.1.0/.github/workflows/release.yml +266 -0
- downstat-0.1.0/.gitignore +4 -0
- downstat-0.1.0/CHANGELOG.md +11 -0
- downstat-0.1.0/Cargo.lock +1975 -0
- downstat-0.1.0/Cargo.toml +38 -0
- downstat-0.1.0/Makefile +44 -0
- downstat-0.1.0/PKG-INFO +107 -0
- downstat-0.1.0/README.md +85 -0
- downstat-0.1.0/pyproject.toml +35 -0
- downstat-0.1.0/schemas/clispec-v0.2.json +161 -0
- downstat-0.1.0/src/error.rs +71 -0
- downstat-0.1.0/src/http.rs +64 -0
- downstat-0.1.0/src/lib.rs +91 -0
- downstat-0.1.0/src/main.rs +208 -0
- downstat-0.1.0/src/model.rs +106 -0
- downstat-0.1.0/src/output.rs +103 -0
- downstat-0.1.0/src/registries.rs +175 -0
- downstat-0.1.0/src/schema.rs +82 -0
- downstat-0.1.0/tests/behavior.rs +158 -0
- downstat-0.1.0/tests/cli.rs +77 -0
- downstat-0.1.0/tests/conformance.rs +36 -0
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
20
|
+
with:
|
|
21
|
+
components: rustfmt, clippy
|
|
22
|
+
- name: Run linting
|
|
23
|
+
run: make lint
|
|
24
|
+
|
|
25
|
+
test:
|
|
26
|
+
name: Test
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/checkout@v4
|
|
30
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
31
|
+
- uses: taiki-e/install-action@nextest
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: make test
|
|
34
|
+
|
|
35
|
+
all-checks-passed:
|
|
36
|
+
name: All checks passed
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
needs: [lint, test]
|
|
39
|
+
if: always()
|
|
40
|
+
steps:
|
|
41
|
+
- name: Verify all checks passed
|
|
42
|
+
run: |
|
|
43
|
+
if [ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]; then
|
|
44
|
+
echo "Some checks failed or were cancelled"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
echo "All checks passed"
|
|
@@ -0,0 +1,266 @@
|
|
|
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 mode (skip actual publishing)'
|
|
11
|
+
required: false
|
|
12
|
+
default: true
|
|
13
|
+
type: boolean
|
|
14
|
+
skip_crates_io:
|
|
15
|
+
description: 'Skip publishing to crates.io (if already published)'
|
|
16
|
+
required: false
|
|
17
|
+
default: false
|
|
18
|
+
type: boolean
|
|
19
|
+
skip_pypi:
|
|
20
|
+
description: 'Skip publishing to PyPI (if already published)'
|
|
21
|
+
required: false
|
|
22
|
+
default: false
|
|
23
|
+
type: boolean
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: write
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
# Avoid the intermittent "HTTP2 framing layer" curl errors when cargo fetches
|
|
31
|
+
# from crates.io on GitHub-hosted runners.
|
|
32
|
+
CARGO_HTTP_MULTIPLEXING: "false"
|
|
33
|
+
|
|
34
|
+
jobs:
|
|
35
|
+
test:
|
|
36
|
+
name: Run tests
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
41
|
+
- uses: taiki-e/install-action@nextest
|
|
42
|
+
- name: Verify Cargo.lock is up to date
|
|
43
|
+
run: cargo check --locked
|
|
44
|
+
- name: Run tests
|
|
45
|
+
run: make test
|
|
46
|
+
|
|
47
|
+
build:
|
|
48
|
+
name: Build ${{ matrix.target }}
|
|
49
|
+
needs: test
|
|
50
|
+
timeout-minutes: 30
|
|
51
|
+
strategy:
|
|
52
|
+
fail-fast: false
|
|
53
|
+
matrix:
|
|
54
|
+
include:
|
|
55
|
+
- os: ubuntu-22.04
|
|
56
|
+
target: x86_64-unknown-linux-gnu
|
|
57
|
+
- os: ubuntu-22.04-arm
|
|
58
|
+
target: aarch64-unknown-linux-gnu
|
|
59
|
+
- os: macos-14
|
|
60
|
+
target: aarch64-apple-darwin
|
|
61
|
+
# Cross-compiled on Apple Silicon (Intel mac runners are scarce).
|
|
62
|
+
- os: macos-14
|
|
63
|
+
target: x86_64-apple-darwin
|
|
64
|
+
cross: true
|
|
65
|
+
runs-on: ${{ matrix.os }}
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v4
|
|
68
|
+
|
|
69
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
70
|
+
with:
|
|
71
|
+
targets: ${{ matrix.target }}
|
|
72
|
+
|
|
73
|
+
# Portable wheels: maturin-action builds linux wheels inside a manylinux
|
|
74
|
+
# container and macOS wheels natively.
|
|
75
|
+
- name: Build wheel
|
|
76
|
+
uses: PyO3/maturin-action@v1
|
|
77
|
+
with:
|
|
78
|
+
target: ${{ matrix.target }}
|
|
79
|
+
args: --release --out dist
|
|
80
|
+
manylinux: auto
|
|
81
|
+
|
|
82
|
+
- name: Build binary
|
|
83
|
+
run: cargo build --release --target ${{ matrix.target }}
|
|
84
|
+
|
|
85
|
+
- name: Verify binary
|
|
86
|
+
# Skip for cross-compiled targets the runner cannot execute.
|
|
87
|
+
if: ${{ !matrix.cross }}
|
|
88
|
+
run: ./target/${{ matrix.target }}/release/downstat --version
|
|
89
|
+
|
|
90
|
+
- name: Create release archive
|
|
91
|
+
shell: bash
|
|
92
|
+
run: |
|
|
93
|
+
# GITHUB_REF_NAME is the tag on a release (v1.2.3) and the branch on
|
|
94
|
+
# a workflow_dispatch dry run (main); both are free of slashes.
|
|
95
|
+
VERSION="${GITHUB_REF_NAME}"
|
|
96
|
+
ARCHIVE_NAME="downstat-${VERSION}-${{ matrix.target }}"
|
|
97
|
+
mkdir -p release-package
|
|
98
|
+
cp "target/${{ matrix.target }}/release/downstat" release-package/downstat
|
|
99
|
+
tar -czf "${ARCHIVE_NAME}.tar.gz" -C release-package downstat
|
|
100
|
+
if [[ "${{ runner.os }}" == "macOS" ]]; then
|
|
101
|
+
shasum -a 256 "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
|
|
102
|
+
else
|
|
103
|
+
sha256sum "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
|
|
104
|
+
fi
|
|
105
|
+
rm -rf release-package
|
|
106
|
+
|
|
107
|
+
- name: Upload wheel
|
|
108
|
+
uses: actions/upload-artifact@v4
|
|
109
|
+
with:
|
|
110
|
+
name: wheel-${{ matrix.target }}
|
|
111
|
+
path: dist/*.whl
|
|
112
|
+
|
|
113
|
+
- name: Upload release archives
|
|
114
|
+
uses: actions/upload-artifact@v4
|
|
115
|
+
with:
|
|
116
|
+
name: release-${{ matrix.target }}
|
|
117
|
+
path: |
|
|
118
|
+
downstat-*-${{ matrix.target }}.tar.gz*
|
|
119
|
+
|
|
120
|
+
sdist:
|
|
121
|
+
name: Build source distribution
|
|
122
|
+
needs: test
|
|
123
|
+
runs-on: ubuntu-latest
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v4
|
|
126
|
+
- uses: astral-sh/setup-uv@v6
|
|
127
|
+
- name: Build sdist
|
|
128
|
+
run: uvx maturin sdist --out dist
|
|
129
|
+
- uses: actions/upload-artifact@v4
|
|
130
|
+
with:
|
|
131
|
+
name: sdist
|
|
132
|
+
path: dist/*.tar.gz
|
|
133
|
+
|
|
134
|
+
release:
|
|
135
|
+
runs-on: ubuntu-latest
|
|
136
|
+
needs: [build, sdist]
|
|
137
|
+
steps:
|
|
138
|
+
- uses: actions/checkout@v4
|
|
139
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
140
|
+
|
|
141
|
+
- name: Publish to crates.io
|
|
142
|
+
if: ${{ inputs.dry_run != true && inputs.skip_crates_io != true }}
|
|
143
|
+
env:
|
|
144
|
+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
145
|
+
run: cargo publish --locked
|
|
146
|
+
|
|
147
|
+
- name: Test crates.io publish (dry run)
|
|
148
|
+
if: ${{ inputs.dry_run == true && inputs.skip_crates_io != true }}
|
|
149
|
+
run: cargo publish --dry-run --locked
|
|
150
|
+
|
|
151
|
+
- name: Skip crates.io publishing
|
|
152
|
+
if: ${{ inputs.skip_crates_io == true }}
|
|
153
|
+
run: echo "Skipping crates.io publishing as requested"
|
|
154
|
+
|
|
155
|
+
- name: Install uv
|
|
156
|
+
uses: astral-sh/setup-uv@v6
|
|
157
|
+
|
|
158
|
+
- name: Download all artifacts
|
|
159
|
+
uses: actions/download-artifact@v4
|
|
160
|
+
with:
|
|
161
|
+
path: artifacts
|
|
162
|
+
|
|
163
|
+
- name: Publish to PyPI
|
|
164
|
+
if: ${{ inputs.dry_run != true && inputs.skip_pypi != true }}
|
|
165
|
+
run: uv publish artifacts/wheel-*/*.whl artifacts/sdist/*.tar.gz
|
|
166
|
+
env:
|
|
167
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
168
|
+
|
|
169
|
+
- name: Create Release
|
|
170
|
+
if: ${{ inputs.dry_run != true }}
|
|
171
|
+
uses: softprops/action-gh-release@v2
|
|
172
|
+
with:
|
|
173
|
+
generate_release_notes: true
|
|
174
|
+
files: |
|
|
175
|
+
artifacts/release-*/downstat-*.tar.gz
|
|
176
|
+
artifacts/release-*/downstat-*.tar.gz.sha256
|
|
177
|
+
|
|
178
|
+
- name: Dry Run Summary
|
|
179
|
+
if: ${{ inputs.dry_run == true }}
|
|
180
|
+
run: |
|
|
181
|
+
echo "Dry run complete. Artifacts built but nothing published."
|
|
182
|
+
find artifacts/release-* artifacts/wheel-* artifacts/sdist -type f | sort
|
|
183
|
+
|
|
184
|
+
update-homebrew:
|
|
185
|
+
needs: release
|
|
186
|
+
if: ${{ !inputs.dry_run }}
|
|
187
|
+
runs-on: ubuntu-latest
|
|
188
|
+
steps:
|
|
189
|
+
- uses: actions/download-artifact@v4
|
|
190
|
+
with:
|
|
191
|
+
path: /tmp/artifacts
|
|
192
|
+
|
|
193
|
+
- name: Compute SHA256 hashes
|
|
194
|
+
id: hashes
|
|
195
|
+
run: |
|
|
196
|
+
for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
|
|
197
|
+
sha=$(cat /tmp/artifacts/release-${target}/downstat-${{ github.ref_name }}-${target}.tar.gz.sha256 | awk '{print $1}')
|
|
198
|
+
key=$(echo "${target}" | tr '-' '_')
|
|
199
|
+
echo "${key}=${sha}" >> "$GITHUB_OUTPUT"
|
|
200
|
+
done
|
|
201
|
+
|
|
202
|
+
- name: Update Homebrew formula
|
|
203
|
+
env:
|
|
204
|
+
HOMEBREW_TAP_DEPLOY_KEY: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }}
|
|
205
|
+
run: |
|
|
206
|
+
VERSION="${{ github.ref_name }}"
|
|
207
|
+
VERSION_NUM="${VERSION#v}"
|
|
208
|
+
|
|
209
|
+
cat > /tmp/downstat.rb << 'FORMULA'
|
|
210
|
+
class Downstat < Formula
|
|
211
|
+
desc "Downloads and latest version for your packages across crates.io, PyPI, npm and GitHub releases"
|
|
212
|
+
homepage "https://github.com/rvben/downstat"
|
|
213
|
+
version "VERSION_NUM"
|
|
214
|
+
license "MIT"
|
|
215
|
+
|
|
216
|
+
on_macos do
|
|
217
|
+
if Hardware::CPU.arm?
|
|
218
|
+
url "https://github.com/rvben/downstat/releases/download/VERSION/downstat-VERSION-aarch64-apple-darwin.tar.gz"
|
|
219
|
+
sha256 "SHA_AARCH64_APPLE_DARWIN"
|
|
220
|
+
else
|
|
221
|
+
url "https://github.com/rvben/downstat/releases/download/VERSION/downstat-VERSION-x86_64-apple-darwin.tar.gz"
|
|
222
|
+
sha256 "SHA_X86_64_APPLE_DARWIN"
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
on_linux do
|
|
227
|
+
if Hardware::CPU.arm?
|
|
228
|
+
url "https://github.com/rvben/downstat/releases/download/VERSION/downstat-VERSION-aarch64-unknown-linux-gnu.tar.gz"
|
|
229
|
+
sha256 "SHA_AARCH64_UNKNOWN_LINUX_GNU"
|
|
230
|
+
else
|
|
231
|
+
url "https://github.com/rvben/downstat/releases/download/VERSION/downstat-VERSION-x86_64-unknown-linux-gnu.tar.gz"
|
|
232
|
+
sha256 "SHA_X86_64_UNKNOWN_LINUX_GNU"
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def install
|
|
237
|
+
bin.install "downstat"
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
test do
|
|
241
|
+
system "#{bin}/downstat", "--version"
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
FORMULA
|
|
245
|
+
|
|
246
|
+
sed -i "s/VERSION_NUM/${VERSION_NUM}/g" /tmp/downstat.rb
|
|
247
|
+
sed -i "s/VERSION/${VERSION}/g" /tmp/downstat.rb
|
|
248
|
+
sed -i "s/SHA_AARCH64_APPLE_DARWIN/${{ steps.hashes.outputs.aarch64_apple_darwin }}/g" /tmp/downstat.rb
|
|
249
|
+
sed -i "s/SHA_X86_64_APPLE_DARWIN/${{ steps.hashes.outputs.x86_64_apple_darwin }}/g" /tmp/downstat.rb
|
|
250
|
+
sed -i "s/SHA_AARCH64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.aarch64_unknown_linux_gnu }}/g" /tmp/downstat.rb
|
|
251
|
+
sed -i "s/SHA_X86_64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.x86_64_unknown_linux_gnu }}/g" /tmp/downstat.rb
|
|
252
|
+
|
|
253
|
+
mkdir -p ~/.ssh
|
|
254
|
+
echo "$HOMEBREW_TAP_DEPLOY_KEY" > ~/.ssh/id_ed25519
|
|
255
|
+
chmod 600 ~/.ssh/id_ed25519
|
|
256
|
+
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
|
|
257
|
+
|
|
258
|
+
git clone git@github.com:rvben/homebrew-tap.git /tmp/tap
|
|
259
|
+
mkdir -p /tmp/tap/Formula
|
|
260
|
+
cp /tmp/downstat.rb /tmp/tap/Formula/downstat.rb
|
|
261
|
+
cd /tmp/tap
|
|
262
|
+
git config user.name "github-actions[bot]"
|
|
263
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
264
|
+
git add Formula/downstat.rb
|
|
265
|
+
git diff --cached --quiet || git commit -m "Update downstat to ${VERSION}"
|
|
266
|
+
git push
|
|
@@ -0,0 +1,11 @@
|
|
|
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.1.0] - 2026-06-20
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- downstat - downloads + version across registries in one view ([2c9bff2](https://github.com/rvben/downstat/commit/2c9bff29e309fc410147c454f9e12bbceb2c7db1))
|