Build, test and release with cargo: CI, release workflow, cross-build and packaging scripts, Homebrew
This commit is contained in:
@@ -0,0 +1,16 @@
|
|||||||
|
name: cross-tools
|
||||||
|
description: Rust targets, zig, cargo-zigbuild and cross for scripts/build.sh
|
||||||
|
runs:
|
||||||
|
using: composite
|
||||||
|
steps:
|
||||||
|
- shell: bash
|
||||||
|
run: |
|
||||||
|
rustup target add x86_64-unknown-linux-musl aarch64-unknown-linux-musl i686-unknown-linux-musl \
|
||||||
|
armv7-unknown-linux-musleabihf riscv64gc-unknown-linux-musl x86_64-pc-windows-gnu \
|
||||||
|
aarch64-pc-windows-gnullvm x86_64-unknown-freebsd x86_64-unknown-netbsd
|
||||||
|
curl -sSLo zig.tar.xz https://ziglang.org/download/0.16.0/zig-x86_64-linux-0.16.0.tar.xz
|
||||||
|
echo "70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00 zig.tar.xz" | sha256sum -c
|
||||||
|
mkdir -p "$HOME/zig" && tar -xJf zig.tar.xz -C "$HOME/zig" --strip-components=1 && rm zig.tar.xz
|
||||||
|
echo "$HOME/zig" >>"$GITHUB_PATH"
|
||||||
|
cargo install cargo-zigbuild --version 0.23.4 --locked
|
||||||
|
cargo install cross --version 0.2.5 --locked
|
||||||
+26
-17
@@ -4,29 +4,38 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
jobs:
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- run: rustup component add rustfmt clippy
|
||||||
|
- run: cargo fmt --check
|
||||||
|
- run: cargo clippy --locked --all-targets -- -D warnings
|
||||||
|
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-24.04, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-2025]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v5
|
||||||
- uses: actions/setup-go@v5
|
- run: cargo test --release --locked --all-targets
|
||||||
with:
|
- run: cargo run --release --locked -- --no-ui .
|
||||||
go-version-file: go.mod
|
|
||||||
- name: format
|
cross:
|
||||||
if: runner.os == 'Linux'
|
runs-on: ubuntu-24.04
|
||||||
run: test -z "$(gofmt -l .)"
|
steps:
|
||||||
- run: go vet ./...
|
- uses: actions/checkout@v5
|
||||||
- run: go test ./...
|
- uses: ./.github/actions/cross-tools
|
||||||
- name: race
|
- name: every target but macOS (built natively by the test job)
|
||||||
if: runner.os != 'Windows'
|
run: TARGETS="linux/amd64 linux/arm64 linux/386 linux/arm linux/riscv64 windows/amd64 windows/arm64 freebsd/amd64 netbsd/amd64" scripts/build.sh
|
||||||
run: go test -race ./...
|
- name: static binaries run under qemu
|
||||||
- name: cross-build
|
|
||||||
if: runner.os == 'Linux'
|
|
||||||
run: |
|
run: |
|
||||||
for t in linux/arm64 linux/386 darwin/arm64 windows/amd64 freebsd/amd64; do
|
sudo apt-get update -q && sudo apt-get install -yq qemu-user
|
||||||
GOOS=${t%/*} GOARCH=${t#*/} CGO_ENABLED=0 go build -o /dev/null ./cmd/mapsize
|
for t in "arm64 qemu-aarch64" "arm qemu-arm" "riscv64 qemu-riscv64"; do
|
||||||
|
${t#* } dist/mapsize-linux-${t%% *} --no-ui src >/dev/null
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# On a version tag: build every target, package, and publish a GitHub
|
||||||
|
# release whose notes are the tag's CHANGELOG.md section.
|
||||||
|
name: release
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ["v*"]
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
jobs:
|
||||||
|
build-cross:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- uses: ./.github/actions/cross-tools
|
||||||
|
- run: TARGETS="linux/amd64 linux/arm64 linux/386 linux/arm linux/riscv64 windows/amd64 windows/arm64 freebsd/amd64 netbsd/amd64" scripts/build.sh
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with: {name: bin-cross, path: dist/mapsize-*}
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-15
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- run: rustup target add x86_64-apple-darwin aarch64-apple-darwin
|
||||||
|
- run: TARGETS="darwin/amd64 darwin/arm64" scripts/build.sh
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with: {name: bin-macos, path: dist/mapsize-*}
|
||||||
|
|
||||||
|
publish:
|
||||||
|
needs: [build-cross, build-macos]
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v5
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with: {path: dist, merge-multiple: true}
|
||||||
|
- run: scripts/release.sh "$GITHUB_REF_NAME" dist dist/release
|
||||||
|
- name: release
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
v=${GITHUB_REF_NAME#v}
|
||||||
|
awk -v h="## $v" 'index($0, h) == 1 {f=1; next} /^## /{f=0} f' CHANGELOG.md >notes.md
|
||||||
|
gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --notes-file notes.md dist/release/*
|
||||||
@@ -1,5 +1,27 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Rewritten in Rust. Flags, keys, views, themes, the configuration file and
|
||||||
|
the snapshot format are unchanged: snapshots from earlier releases open as
|
||||||
|
before, and older releases open new ones. Measured against 1.2.0 on the
|
||||||
|
same machine, scans are about 1.3× faster with a third less memory, cold
|
||||||
|
treemap frames about 3× faster, and filters up to 1.8× faster (see
|
||||||
|
PERFORMANCE.md).
|
||||||
|
- Release builds: Linux (x86-64, ARM64, 32-bit x86, ARMv7, RISC-V 64),
|
||||||
|
macOS (Intel, Apple silicon), Windows (x86-64, ARM64), FreeBSD and NetBSD
|
||||||
|
(x86-64), built and published by CI. OpenBSD and FreeBSD/ARM64 builds are
|
||||||
|
no longer produced.
|
||||||
|
- `--log` and `--log-level` are accepted but no log is written yet;
|
||||||
|
`--cpuprofile` and `--memprofile` are removed.
|
||||||
|
- Install from source with `cargo install`; the Homebrew formula builds with
|
||||||
|
Rust.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- A search containing certain non-ASCII text (for example `voilà`) no longer
|
||||||
|
hangs.
|
||||||
|
|
||||||
## 1.2.0 — 2026-10-03
|
## 1.2.0 — 2026-10-03
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -1,80 +1,54 @@
|
|||||||
BIN := bin
|
|
||||||
PKG := ./...
|
|
||||||
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
|
|
||||||
LDFLAGS := -s -w
|
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
|
VERSION ?= $(shell sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
|
||||||
|
|
||||||
.PHONY: build install man brew-formula test race vet fmt fmt-check benchmark fuzz release clean treegen
|
.PHONY: build install man test lint fmt fmt-check benchmark treegen release brew-formula clean
|
||||||
|
|
||||||
build:
|
build:
|
||||||
go build -trimpath -ldflags '$(LDFLAGS)' -o $(BIN)/mapsize ./cmd/mapsize
|
cargo build --release --locked
|
||||||
go build -trimpath -ldflags '$(LDFLAGS)' -o $(BIN)/treegen ./cmd/treegen
|
|
||||||
|
|
||||||
install: build
|
install: build
|
||||||
install -Dm755 $(BIN)/mapsize $(DESTDIR)$(PREFIX)/bin/mapsize
|
install -Dm755 target/release/mapsize $(DESTDIR)$(PREFIX)/bin/mapsize
|
||||||
install -Dm644 docs/mapsize.1 $(DESTDIR)$(PREFIX)/share/man/man1/mapsize.1
|
install -Dm644 docs/mapsize.1 $(DESTDIR)$(PREFIX)/share/man/man1/mapsize.1
|
||||||
|
|
||||||
man:
|
man:
|
||||||
man -l docs/mapsize.1
|
man -l docs/mapsize.1
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test $(PKG)
|
cargo test --release --locked
|
||||||
|
|
||||||
race:
|
lint:
|
||||||
go test -race $(PKG)
|
cargo clippy --locked --all-targets -- -D warnings
|
||||||
|
|
||||||
vet:
|
|
||||||
go vet $(PKG)
|
|
||||||
|
|
||||||
fmt:
|
fmt:
|
||||||
gofmt -w .
|
cargo fmt
|
||||||
|
|
||||||
fmt-check:
|
fmt-check:
|
||||||
@test -z "$$(gofmt -l .)" || (gofmt -l . && echo 'run make fmt' && exit 1)
|
cargo fmt --check
|
||||||
|
|
||||||
benchmark:
|
benchmark:
|
||||||
go test -run=NONE -bench=. -benchmem $(PKG)
|
cargo run --release --locked --example bench
|
||||||
|
|
||||||
fuzz:
|
treegen:
|
||||||
go test -run=NONE -fuzz=FuzzLoad -fuzztime=30s ./internal/snapshot
|
cargo build --release --locked --example treegen
|
||||||
go test -run=NONE -fuzz=FuzzSquarify -fuzztime=30s ./internal/treemap
|
|
||||||
go test -run=NONE -fuzz=FuzzParse -fuzztime=30s ./internal/filter
|
|
||||||
|
|
||||||
# Cross-built archives plus .deb/.rpm/.apk/Arch packages in $(BIN)/release.
|
# Binaries for every target this host can build (see scripts/build.sh), then
|
||||||
REL := $(BIN)/release
|
# archives, Linux packages and SHA256SUMS in dist/release. Tagged releases are
|
||||||
NFPM := go run github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.41.1
|
# built on GitHub's runners by .github/workflows/release.yml instead.
|
||||||
release:
|
release:
|
||||||
rm -rf $(REL) && mkdir -p $(REL)
|
scripts/build.sh || true
|
||||||
@set -e; v=$(VERSION); v=$${v#v}; \
|
scripts/release.sh $(VERSION) dist dist/release
|
||||||
for t in linux/amd64 linux/arm64 linux/386 linux/arm darwin/amd64 darwin/arm64 \
|
|
||||||
windows/amd64 windows/arm64 freebsd/amd64 freebsd/arm64 openbsd/amd64 netbsd/amd64; do \
|
|
||||||
os=$${t%/*}; arch=$${t#*/}; ext=; [ $$os = windows ] && ext=.exe; \
|
|
||||||
name=mapsize-$$v-$$os-$$arch; d=$(REL)/$$name; echo "$$os/$$arch"; mkdir -p $$d; \
|
|
||||||
CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch GOARM=7 go build -trimpath \
|
|
||||||
-ldflags '$(LDFLAGS) -X github.com/andydixon/mapsize/internal/brand.Version='$$v \
|
|
||||||
-o $$d/mapsize$$ext ./cmd/mapsize; \
|
|
||||||
cp README.md CHANGELOG.md LICENSE docs/mapsize.1 $$d/; \
|
|
||||||
if [ $$os = windows ]; then (cd $(REL) && zip -qr $$name.zip $$name); \
|
|
||||||
else tar -C $(REL) -czf $(REL)/$$name.tar.gz $$name; fi; \
|
|
||||||
if [ $$os = linux ]; then mkdir -p $(REL)/pkg && cp $$d/mapsize $(REL)/pkg/; \
|
|
||||||
a=$$arch; [ $$a = arm ] && a=arm7; \
|
|
||||||
for f in deb rpm apk archlinux; do \
|
|
||||||
VERSION=$$v ARCH=$$a $(NFPM) pkg -f nfpm.yaml -p $$f -t $(REL)/; done; rm -rf $(REL)/pkg; fi; \
|
|
||||||
rm -rf $$d; \
|
|
||||||
done; \
|
|
||||||
cd $(REL) && sha256sum * > SHA256SUMS
|
|
||||||
|
|
||||||
# Homebrew formula for the tagged release. The tag must already be pushed:
|
# Homebrew formula for the tagged release. The tag must already be pushed:
|
||||||
# the checksum is of GitHub's source tarball for that tag.
|
# the checksum is of GitHub's source tarball for that tag.
|
||||||
BREW_REPO := https://github.com/andydixon/mapsize
|
BREW_REPO := https://github.com/andydixon/mapsize
|
||||||
brew-formula:
|
brew-formula:
|
||||||
@set -e; v=$(VERSION); v=$${v#v}; \
|
@set -e; v=$(VERSION); v=$${v#v}; \
|
||||||
case $$v in *-*) echo "brew-formula: HEAD is not exactly a release tag ($$v)"; exit 1;; esac; \
|
|
||||||
url=$(BREW_REPO)/archive/refs/tags/v$$v.tar.gz; \
|
url=$(BREW_REPO)/archive/refs/tags/v$$v.tar.gz; \
|
||||||
sum=$$(curl -fsSL "$$url" | sha256sum | cut -d' ' -f1) || { echo "cannot fetch $$url (tag pushed?)"; exit 1; }; \
|
sum=$$(curl -fsSL "$$url" | sha256sum | cut -d' ' -f1) || { echo "cannot fetch $$url (tag pushed?)"; exit 1; }; \
|
||||||
mkdir -p $(BIN)/homebrew; \
|
mkdir -p dist/homebrew; \
|
||||||
sed -e '/^#/d' -e "s/@VERSION@/$$v/g" -e "s/@SHA256@/$$sum/" packaging/homebrew/mapsize.rb.in > $(BIN)/homebrew/mapsize.rb; \
|
sed -e '/^#/d' -e "s/@VERSION@/$$v/g" -e "s/@SHA256@/$$sum/" packaging/homebrew/mapsize.rb.in > dist/homebrew/mapsize.rb; \
|
||||||
echo "wrote $(BIN)/homebrew/mapsize.rb (v$$v, sha256 $$sum)"
|
echo "wrote dist/homebrew/mapsize.rb (v$$v, sha256 $$sum)"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BIN)
|
cargo clean
|
||||||
|
rm -rf dist
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
# mapsize
|
# mapsize
|
||||||
|
|
||||||
An interactive, full-terminal disk usage analyser built around a live,
|
An interactive, full-terminal disk usage analyser built around a live,
|
||||||
navigable treemap. Think WinDirStat + ncdu + WizTree, in one Go binary that
|
navigable treemap. Think WinDirStat + ncdu + WizTree, in one Rust binary
|
||||||
runs over SSH.
|
that runs over SSH.
|
||||||
|
|
||||||
> `mapsize` is a working name; branding lives in `internal/brand`.
|
> `mapsize` is a working name; branding lives in `src/brand.rs`.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Version 1.0. See [CHANGELOG.md](CHANGELOG.md), [ROADMAP.md](ROADMAP.md) for
|
Version 1.2. See [CHANGELOG.md](CHANGELOG.md), [ROADMAP.md](ROADMAP.md) for
|
||||||
what comes next, and [PERFORMANCE.md](PERFORMANCE.md) for measured numbers.
|
what comes next, and [PERFORMANCE.md](PERFORMANCE.md) for measured numbers.
|
||||||
Tested on Linux; macOS and Windows builds are produced but trash and
|
Releases cover Linux, macOS, Windows, FreeBSD and NetBSD. It is tested on
|
||||||
file-manager integration have not yet been tested there.
|
Linux; CI also runs the test suite on macOS and Windows, but trash and
|
||||||
|
file-manager integration have not yet been tried by hand there.
|
||||||
|
|
||||||
## What it does
|
## What it does
|
||||||
|
|
||||||
@@ -70,9 +71,9 @@ the map or scrolls lists. Everything works without a mouse (`--no-mouse`).
|
|||||||
## Install
|
## Install
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go install github.com/andydixon/mapsize/cmd/mapsize@v1.0.0
|
cargo install --locked --git https://github.com/andydixon/mapsize
|
||||||
# or
|
# or, from a checkout
|
||||||
make build # → bin/mapsize
|
make build # → target/release/mapsize
|
||||||
sudo make install # binary + man page under /usr/local (PREFIX=… to change)
|
sudo make install # binary + man page under /usr/local (PREFIX=… to change)
|
||||||
|
|
||||||
# Homebrew (macOS and Linux)
|
# Homebrew (macOS and Linux)
|
||||||
|
|||||||
+2
-2
@@ -3,14 +3,14 @@
|
|||||||
Status markers: `[x]` done, `[~]` partial, `[ ]` not started.
|
Status markers: `[x]` done, `[~]` partial, `[ ]` not started.
|
||||||
|
|
||||||
## 0.1 — inventory engine
|
## 0.1 — inventory engine
|
||||||
- [x] Go project skeleton, Makefile, CI
|
- [x] project skeleton, Makefile, CI
|
||||||
- [x] portable filesystem scanner, bounded worker pool, no-deadlock scheduler
|
- [x] portable filesystem scanner, bounded worker pool, no-deadlock scheduler
|
||||||
- [x] inventory node model, incremental aggregation
|
- [x] inventory node model, incremental aggregation
|
||||||
- [x] cancellation, progress counters, error accounting
|
- [x] cancellation, progress counters, error accounting
|
||||||
- [x] CLI: `--top`, `--json`, `--csv`, `--no-ui`
|
- [x] CLI: `--top`, `--json`, `--csv`, `--no-ui`
|
||||||
|
|
||||||
## 0.2 — TUI shell
|
## 0.2 — TUI shell
|
||||||
- [x] full-screen Bubble Tea v2 app, canvas renderer, frame cache
|
- [x] full-screen terminal app, canvas renderer, frame cache
|
||||||
- [x] responsive layout (large / medium / small / too-small)
|
- [x] responsive layout (large / medium / small / too-small)
|
||||||
- [x] resize handling, status bar, progressive display, directory list
|
- [x] resize handling, status bar, progressive display, directory list
|
||||||
|
|
||||||
|
|||||||
+4
-12
@@ -142,18 +142,10 @@ colouring, or prints the most significant changes with \fB\-\-no\-ui\fR
|
|||||||
(\fB\-\-top\fR sets how many; default 30).
|
(\fB\-\-top\fR sets how many; default 30).
|
||||||
.SS Diagnostics
|
.SS Diagnostics
|
||||||
.TP
|
.TP
|
||||||
.BI \-\-log " FILE"
|
.BI \-\-log " FILE" "\fR, \fP\-\-log\-level " LEVEL
|
||||||
Append a log to \fIFILE\fR without disturbing the interface. Full paths are
|
Accepted for compatibility with earlier releases; currently no log is
|
||||||
logged only at \fBdebug\fR level and above.
|
written. \fILEVEL\fR must still be one of
|
||||||
.TP
|
.BR error ", " warn ", " info ", " debug " or " trace .
|
||||||
.BI \-\-log\-level " LEVEL"
|
|
||||||
.BR error ", " warn ", " info " (default), " debug " or " trace .
|
|
||||||
.TP
|
|
||||||
.BI \-\-cpuprofile " FILE"
|
|
||||||
Write a Go CPU profile.
|
|
||||||
.TP
|
|
||||||
.BI \-\-memprofile " FILE"
|
|
||||||
Write a Go heap profile on exit.
|
|
||||||
.TP
|
.TP
|
||||||
.B \-\-version
|
.B \-\-version
|
||||||
Print the version and exit.
|
Print the version and exit.
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
name: mapsize
|
|
||||||
arch: ${ARCH}
|
|
||||||
version: ${VERSION}
|
|
||||||
maintainer: Andy Dixon <andy@dixon.cx>
|
|
||||||
description: Interactive full-terminal disk usage analyser with a live treemap.
|
|
||||||
homepage: https://github.com/andydixon/mapsize
|
|
||||||
license: GPL-3.0-or-later
|
|
||||||
contents:
|
|
||||||
- src: bin/release/pkg/mapsize
|
|
||||||
dst: /usr/bin/mapsize
|
|
||||||
- src: docs/mapsize.1
|
|
||||||
dst: /usr/share/man/man1/mapsize.1
|
|
||||||
file_info:
|
|
||||||
mode: 0644
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Homebrew formula template for mapsize. `make brew-formula` fills in the
|
# Homebrew formula template for mapsize. `make brew-formula` fills in the
|
||||||
# version and the checksum of the GitHub source tarball and writes the
|
# version and the checksum of the GitHub source tarball and writes the
|
||||||
# result to bin/homebrew/mapsize.rb; copy that into your tap
|
# result to dist/homebrew/mapsize.rb; copy that into your tap
|
||||||
# (github.com/andydixon/homebrew-tap, Formula/mapsize.rb).
|
# (github.com/andydixon/homebrew-tap, Formula/mapsize.rb).
|
||||||
class Mapsize < Formula
|
class Mapsize < Formula
|
||||||
desc "Interactive terminal disk usage analyser with a navigable treemap"
|
desc "Interactive terminal disk usage analyser with a navigable treemap"
|
||||||
@@ -10,11 +10,10 @@ class Mapsize < Formula
|
|||||||
license "GPL-3.0-or-later"
|
license "GPL-3.0-or-later"
|
||||||
head "https://github.com/andydixon/mapsize.git", branch: "master"
|
head "https://github.com/andydixon/mapsize.git", branch: "master"
|
||||||
|
|
||||||
depends_on "go" => :build
|
depends_on "rust" => :build
|
||||||
|
|
||||||
def install
|
def install
|
||||||
ldflags = "-X github.com/andydixon/mapsize/internal/brand.Version=#{version}"
|
system "cargo", "install", *std_cargo_args
|
||||||
system "go", "build", *std_go_args(ldflags:), "./cmd/mapsize"
|
|
||||||
man1.install "docs/mapsize.1"
|
man1.install "docs/mapsize.1"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+24
-12
@@ -10,10 +10,11 @@
|
|||||||
# Every index is rebuilt over all the packages in the repository, so other
|
# Every index is rebuilt over all the packages in the repository, so other
|
||||||
# projects publishing there with their copy of this script are kept.
|
# projects publishing there with their copy of this script are kept.
|
||||||
#
|
#
|
||||||
# Needs: go, docker, gpg, apt-ftparchive (apt-utils), flock.
|
# Needs: cargo with cargo-zigbuild and zig (static musl cross-builds), curl
|
||||||
|
# (to fetch the pinned nfpm), docker, gpg, apt-ftparchive (apt-utils), flock.
|
||||||
# REPO_DIR where the repository lives (default below)
|
# REPO_DIR where the repository lives (default below)
|
||||||
# REPO_GNUPGHOME GnuPG home holding the signing key (default below)
|
# REPO_GNUPGHOME GnuPG home holding the signing key (default below)
|
||||||
# ARCHS Go architectures to package (default below)
|
# ARCHS package architectures (default below)
|
||||||
#
|
#
|
||||||
# The same script, with its own project block, is in ../vault/packaging.
|
# The same script, with its own project block, is in ../vault/packaging.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
@@ -27,19 +28,30 @@ HOMEPAGE=https://github.com/andydixon/mapsize
|
|||||||
LICENSE=GPL-3.0-or-later
|
LICENSE=GPL-3.0-or-later
|
||||||
MANPAGES=docs/*.1
|
MANPAGES=docs/*.1
|
||||||
DOCS="README.md CHANGELOG.md LICENSE"
|
DOCS="README.md CHANGELOG.md LICENSE"
|
||||||
# build OUT: build the binary to OUT, in the source tree, with GOOS, GOARCH
|
# Package architecture -> Rust target (static musl binaries).
|
||||||
# and GOARM set and VERSION the release.
|
triple() {
|
||||||
|
case $1 in
|
||||||
|
amd64) echo x86_64-unknown-linux-musl ;;
|
||||||
|
arm64) echo aarch64-unknown-linux-musl ;;
|
||||||
|
arm) echo armv7-unknown-linux-musleabihf ;;
|
||||||
|
386) echo i686-unknown-linux-musl ;;
|
||||||
|
riscv64) echo riscv64gc-unknown-linux-musl ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
# build ARCH OUT: build the binary for ARCH to OUT, in the source tree.
|
||||||
build() {
|
build() {
|
||||||
CGO_ENABLED=0 go build -trimpath \
|
local t
|
||||||
-ldflags "-s -w -X github.com/andydixon/mapsize/internal/brand.Version=$VERSION" \
|
t=$(triple "$1") || die "no Rust target for $1"
|
||||||
-o "$1" ./cmd/mapsize
|
RUSTFLAGS="--remap-path-prefix=$PWD=$NAME" cargo zigbuild --quiet --release --locked --target "$t"
|
||||||
|
install -D -m 0755 "target/$t/release/$NAME" "$2"
|
||||||
}
|
}
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
REPO_DIR=${REPO_DIR:-/home/andy/domains/repo.dixon.cx/public_html}
|
REPO_DIR=${REPO_DIR:-/home/andy/domains/repo.dixon.cx/public_html}
|
||||||
REPO_GNUPGHOME=${REPO_GNUPGHOME:-$HOME/.config/repo.dixon.cx/gnupg}
|
REPO_GNUPGHOME=${REPO_GNUPGHOME:-$HOME/.config/repo.dixon.cx/gnupg}
|
||||||
ARCHS=${ARCHS:-"amd64 arm64 arm 386 riscv64"}
|
ARCHS=${ARCHS:-"amd64 arm64 arm 386 riscv64"}
|
||||||
NFPM="go run github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.41.1"
|
NFPM="$(cd "$(dirname "$0")/.." && pwd)/scripts/nfpm.sh"
|
||||||
SUITE=stable
|
SUITE=stable
|
||||||
COMPONENT=main
|
COMPONENT=main
|
||||||
ARCH_REPO=dixon # the pacman repository name: [dixon]
|
ARCH_REPO=dixon # the pacman repository name: [dixon]
|
||||||
@@ -47,7 +59,7 @@ ARCH_REPO=dixon # the pacman repository name: [dixon]
|
|||||||
say() { echo "repo: $*" >&2; }
|
say() { echo "repo: $*" >&2; }
|
||||||
die() { say "$*"; exit 1; }
|
die() { say "$*"; exit 1; }
|
||||||
|
|
||||||
for tool in go docker gpg apt-ftparchive flock; do
|
for tool in cargo cargo-zigbuild zig curl docker gpg apt-ftparchive flock; do
|
||||||
command -v $tool >/dev/null || die "needs $tool"
|
command -v $tool >/dev/null || die "needs $tool"
|
||||||
done
|
done
|
||||||
[[ -d $REPO_DIR ]] || die "$REPO_DIR does not exist"
|
[[ -d $REPO_DIR ]] || die "$REPO_DIR does not exist"
|
||||||
@@ -70,9 +82,9 @@ gpg --batch --armor --export-secret-keys "$KEY" >"$WORK/signing.asc"
|
|||||||
say "building $PACKAGE $VERSION for $ARCHS"
|
say "building $PACKAGE $VERSION for $ARCHS"
|
||||||
mkdir -p "$WORK/out"
|
mkdir -p "$WORK/out"
|
||||||
for arch in $ARCHS; do
|
for arch in $ARCHS; do
|
||||||
goarm= nfarch=$arch
|
nfarch=$arch
|
||||||
[[ $arch == arm ]] && goarm=7 nfarch=arm7
|
[[ $arch == arm ]] && nfarch=arm7
|
||||||
(cd "$WORK/src" && GOOS=linux GOARCH=$arch GOARM=$goarm build "$WORK/bin-$arch/$NAME")
|
(cd "$WORK/src" && build "$arch" "$WORK/bin-$arch/$NAME")
|
||||||
{
|
{
|
||||||
cat <<-EOF
|
cat <<-EOF
|
||||||
name: $PACKAGE
|
name: $PACKAGE
|
||||||
|
|||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Build mapsize release binaries for the supported operating systems and
|
||||||
|
# CPU architectures.
|
||||||
|
#
|
||||||
|
# scripts/build.sh # every target this host can build, into dist/
|
||||||
|
# TARGETS="linux/amd64 darwin/arm64" scripts/build.sh
|
||||||
|
# OUT=/tmp/bins scripts/build.sh
|
||||||
|
#
|
||||||
|
# Binaries are named mapsize-OS-ARCH[.exe]: stripped release builds from the
|
||||||
|
# locked dependencies (Cargo.lock), with build paths remapped so the output
|
||||||
|
# does not depend on where the tree lives. Linux binaries are static (musl).
|
||||||
|
#
|
||||||
|
# How each target is built, and what the host needs:
|
||||||
|
# zig cargo-zigbuild and zig on PATH (Linux, Windows)
|
||||||
|
# mac a Mac, or cargo-zigbuild and zig (macOS)
|
||||||
|
# cross `cross` and Docker (FreeBSD, NetBSD)
|
||||||
|
# A requested target the host cannot build is reported, the others are still
|
||||||
|
# built, and the script exits non-zero. The release workflow
|
||||||
|
# (.github/workflows/release.yml) builds every target on GitHub's runners.
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
root=$PWD
|
||||||
|
|
||||||
|
table() {
|
||||||
|
# os/arch Rust target method
|
||||||
|
cat <<-'EOF2'
|
||||||
|
linux/amd64 x86_64-unknown-linux-musl zig
|
||||||
|
linux/arm64 aarch64-unknown-linux-musl zig
|
||||||
|
linux/386 i686-unknown-linux-musl zig
|
||||||
|
linux/arm armv7-unknown-linux-musleabihf zig
|
||||||
|
linux/riscv64 riscv64gc-unknown-linux-musl zig
|
||||||
|
windows/amd64 x86_64-pc-windows-gnu zig
|
||||||
|
windows/arm64 aarch64-pc-windows-gnullvm zig
|
||||||
|
darwin/amd64 x86_64-apple-darwin mac
|
||||||
|
darwin/arm64 aarch64-apple-darwin mac
|
||||||
|
freebsd/amd64 x86_64-unknown-freebsd cross
|
||||||
|
netbsd/amd64 x86_64-unknown-netbsd cross
|
||||||
|
EOF2
|
||||||
|
}
|
||||||
|
|
||||||
|
out=${OUT:-dist}
|
||||||
|
targets=${TARGETS:-$(table | awk '{print $1}')}
|
||||||
|
mkdir -p -- "$out"
|
||||||
|
out=$(cd -- "$out" && pwd -P)
|
||||||
|
case $out in
|
||||||
|
/ | "$(cd ~ && pwd -P)" | "$root") echo "refusing OUT=$out: use a dedicated directory" >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
export RUSTFLAGS="${RUSTFLAGS:-} --remap-path-prefix=$root=mapsize --remap-path-prefix=${CARGO_HOME:-$HOME/.cargo}=cargo"
|
||||||
|
have() { command -v "$1" >/dev/null; }
|
||||||
|
|
||||||
|
status=0
|
||||||
|
for want in $targets; do
|
||||||
|
row=$(table | awk -v t="$want" '$1 == t')
|
||||||
|
[[ -n $row ]] || { echo "UNKNOWN $want" >&2; status=1; continue; }
|
||||||
|
read -r _ triple method <<<"$row"
|
||||||
|
ext=; [[ $want == windows/* ]] && ext=.exe
|
||||||
|
name=mapsize-${want/\//-}$ext
|
||||||
|
case $method in
|
||||||
|
zig) have cargo-zigbuild && have zig && cmd=(cargo zigbuild) ||
|
||||||
|
{ echo "SKIPPED $want: needs cargo-zigbuild and zig" >&2; status=1; continue; } ;;
|
||||||
|
mac)
|
||||||
|
if [[ $(uname -s) == Darwin ]]; then cmd=(cargo build)
|
||||||
|
elif have cargo-zigbuild && have zig; then cmd=(cargo zigbuild)
|
||||||
|
else echo "SKIPPED $want: needs a Mac, or cargo-zigbuild and zig" >&2; status=1; continue; fi ;;
|
||||||
|
cross) have cross && have docker && cmd=(cross build) ||
|
||||||
|
{ echo "SKIPPED $want: needs cross and docker" >&2; status=1; continue; } ;;
|
||||||
|
esac
|
||||||
|
if ! "${cmd[@]}" --quiet --release --locked --target "$triple"; then
|
||||||
|
echo "FAILED $want ($triple)" >&2; status=1; continue
|
||||||
|
fi
|
||||||
|
cp -- "target/$triple/release/mapsize$ext" "$out/$name"
|
||||||
|
if [[ $triple == *-musl* ]] && have file; then
|
||||||
|
file -L "$out/$name" | grep -q 'static' || { echo "FAILED $want: not statically linked" >&2; status=1; continue; }
|
||||||
|
fi
|
||||||
|
echo "built $name ($triple)"
|
||||||
|
done
|
||||||
|
exit $status
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Run the pinned nfpm packager, downloading and checksumming it on first use
|
||||||
|
# (into target/tools). Linux x86-64 and ARM64 hosts only.
|
||||||
|
set -euo pipefail
|
||||||
|
version=2.41.1
|
||||||
|
case $(uname -m) in
|
||||||
|
x86_64) arch=x86_64 sum=b3cf95aa6dabed836d09ad7f0c190a13c74c5b1304db60846f0f702ee407f430 ;;
|
||||||
|
aarch64) arch=arm64 sum=17350a838c8e2c422c6e573ed379b18424565d2de8a2b1cb1b20211976124eb5 ;;
|
||||||
|
*) echo "nfpm.sh: unsupported host $(uname -m)" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
dir=$(cd "$(dirname "$0")/.." && pwd)/target/tools/nfpm-$version
|
||||||
|
if [[ ! -x $dir/nfpm ]]; then
|
||||||
|
mkdir -p "$dir"
|
||||||
|
tgz=$dir/nfpm.tar.gz
|
||||||
|
curl -fsSL -o "$tgz" "https://github.com/goreleaser/nfpm/releases/download/v$version/nfpm_${version}_Linux_$arch.tar.gz"
|
||||||
|
echo "$sum $tgz" | sha256sum -c --quiet
|
||||||
|
tar -xzf "$tgz" -C "$dir" nfpm
|
||||||
|
rm -f "$tgz"
|
||||||
|
fi
|
||||||
|
exec "$dir/nfpm" "$@"
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Turn the binaries from scripts/build.sh into release assets: one archive
|
||||||
|
# per binary (with README, CHANGELOG, LICENSE and the manual page), .deb,
|
||||||
|
# .rpm, .apk and Arch packages for the Linux binaries, and SHA256SUMS.
|
||||||
|
#
|
||||||
|
# scripts/release.sh VERSION [BIN_DIR [OUT_DIR]] # defaults: dist, dist/release
|
||||||
|
#
|
||||||
|
# VERSION (e.g. 1.3.0 or v1.3.0) must match Cargo.toml, which is what the
|
||||||
|
# binaries report.
|
||||||
|
set -euo pipefail
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
root=$PWD
|
||||||
|
version=${1:?usage: scripts/release.sh VERSION [BIN_DIR [OUT_DIR]]}
|
||||||
|
version=${version#v}
|
||||||
|
bins=$(cd "${2:-dist}" && pwd)
|
||||||
|
out=${3:-dist/release}
|
||||||
|
cargo_version=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
|
||||||
|
[[ $version == "$cargo_version" ]] || { echo "release: VERSION $version does not match Cargo.toml ($cargo_version)" >&2; exit 1; }
|
||||||
|
rm -rf -- "$out" && mkdir -p -- "$out"
|
||||||
|
out=$(cd "$out" && pwd)
|
||||||
|
work=$(mktemp -d)
|
||||||
|
trap 'rm -rf -- "$work"' EXIT
|
||||||
|
|
||||||
|
shopt -s nullglob
|
||||||
|
for bin in "$bins"/mapsize-*; do
|
||||||
|
b=$(basename "$bin")
|
||||||
|
osarch=${b#mapsize-}
|
||||||
|
osarch=${osarch%.exe}
|
||||||
|
os=${osarch%-*} arch=${osarch#*-}
|
||||||
|
ext=; [[ $os == windows ]] && ext=.exe
|
||||||
|
name=mapsize-$version-$os-$arch
|
||||||
|
mkdir -p "$work/$name"
|
||||||
|
install -m 0755 "$bin" "$work/$name/mapsize$ext"
|
||||||
|
cp README.md CHANGELOG.md LICENSE docs/mapsize.1 "$work/$name/"
|
||||||
|
if [[ $os == windows ]]; then (cd "$work" && zip -qr "$out/$name.zip" "$name")
|
||||||
|
else tar -C "$work" -czf "$out/$name.tar.gz" "$name"; fi
|
||||||
|
if [[ $os == linux ]]; then
|
||||||
|
nfarch=$arch; [[ $arch == arm ]] && nfarch=arm7
|
||||||
|
cat >"$work/nfpm-$arch.yaml" <<-EOF2
|
||||||
|
name: mapsize
|
||||||
|
arch: $nfarch
|
||||||
|
platform: linux
|
||||||
|
version: $version
|
||||||
|
release: 1
|
||||||
|
maintainer: Andy Dixon <andy@dixon.cx>
|
||||||
|
description: Interactive full-terminal disk usage analyser with a live treemap.
|
||||||
|
homepage: https://github.com/andydixon/mapsize
|
||||||
|
license: GPL-3.0-or-later
|
||||||
|
contents:
|
||||||
|
- src: $work/$name/mapsize
|
||||||
|
dst: /usr/bin/mapsize
|
||||||
|
file_info: {mode: 0755}
|
||||||
|
- src: $root/docs/mapsize.1
|
||||||
|
dst: /usr/share/man/man1/mapsize.1
|
||||||
|
file_info: {mode: 0644}
|
||||||
|
EOF2
|
||||||
|
for fmt in deb rpm apk archlinux; do
|
||||||
|
scripts/nfpm.sh pkg -f "$work/nfpm-$arch.yaml" -p $fmt -t "$out/" >/dev/null
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
(cd "$out" && sha256sum -- * >SHA256SUMS)
|
||||||
|
echo "$(($(ls "$out" | wc -l) - 1)) assets and SHA256SUMS in $out"
|
||||||
Reference in New Issue
Block a user