From 1387e5206496de77741125d585c1af79ec213c41 Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Fri, 2 Oct 2026 09:46:13 +0100 Subject: [PATCH] Release 1.0.0 Declare the snapshot format (v1) stable, bump the version, ship the man page in release archives and deb/rpm/apk/Arch packages, add a Homebrew formula template with make brew-formula, and update the changelog, roadmap, README and development notes. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 28 +++++++++++++++++++++++++++- DEVELOPMENT.md | 30 ++++++++++++++++++++++++++++++ Makefile | 16 ++++++++++++++-- README.md | 12 ++++++++---- ROADMAP.md | 13 ++++++++++--- docs/mapsize.1 | 2 +- internal/brand/brand.go | 2 +- nfpm.yaml | 4 ++++ packaging/homebrew/mapsize.rb.in | 25 +++++++++++++++++++++++++ 9 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 packaging/homebrew/mapsize.rb.in diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ff893e..6b89432 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,18 @@ # Changelog -## Unreleased +## 1.0.0 — 2026-10-02 + +First stable release. The snapshot format (version 1) is now stable: later +1.x releases will keep reading version 1 snapshots. + +### Engine - Bounded concurrent scanner with incremental aggregation, cancellation, hard-link and symlink-loop handling, error accounting. - Non-interactive reports: `--top`, `--largest-files`, `--json`, `--csv`, `--duplicates`, `--no-ui`. - Versioned, checksummed snapshot format; `--compare`. + +### Interface - Interactive TUI (Bubble Tea v2): live squarified treemap with nested previews and level-of-detail grouping, spatial arrow navigation, zoom, breadcrumbs, responsive layouts, info/help/confirm/save modals, mouse. @@ -16,3 +23,22 @@ perceptual 256-colour quantizer, NO_COLOR support. - Move to trash (freedesktop / macOS / Windows), `--read-only`. - `treegen` synthetic tree generator; benchmarks in PERFORMANCE.md. + +### Packaging and documentation +- `mapsize(1)` manual page; `make install` installs binary and man page. +- `make release`: archives for Linux, macOS, Windows and the BSDs, plus + .deb, .rpm, .apk and Arch packages (with the man page) and SHA256SUMS. +- Version stamped into release builds. +- Homebrew formula template and `make brew-formula`. + +### Hardening +- Snapshot loader rejects over-deep trees, decompression bombs and + out-of-range sizes; aggregates saturate instead of overflowing. +- Exclusion patterns from snapshot metadata are sanitised in reports. +- Duplicate, trash and filter results belonging to a replaced tree (after + a rescan) are discarded. +- Linux trash refuses symlinked or foreign trash directories on shared + filesystems and never overwrites an earlier trashed item. +- Symlinks are not followed on platforms without inode identity; the + unscanned-directory count and post-cancel errors are reported correctly. +- Path filters evaluate incrementally (2× faster on 1M entries). diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 7609ed5..1b70d6b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -12,6 +12,36 @@ make fuzz # short fuzz runs of snapshot / treemap / filter make release # cross-compiled binaries in bin/release ``` +## Releasing + +```sh +git tag -a v1.0.0 -m "mapsize 1.0.0" +make release # bin/release: archives, .deb/.rpm/.apk/Arch, SHA256SUMS +``` + +The version comes from `git describe` and is stamped into +`brand.Version`; untagged builds report the fallback in +`internal/brand/brand.go`. Packages need network access the first time +(`nfpm` is fetched with `go run`). Bump the version in `docs/mapsize.1` and +`brand.go` and add a CHANGELOG section before tagging. + +### Homebrew + +After pushing the tag: + +```sh +make brew-formula # → bin/homebrew/mapsize.rb with the tarball's sha256 +``` + +Copy the result to `Formula/mapsize.rb` in the tap repository +`github.com/andydixon/homebrew-tap`; users then run +`brew install andydixon/tap/mapsize`. The formula builds from source with +Go, stamps the version and installs the man page. Template: +`packaging/homebrew/mapsize.rb.in`. + +The snapshot format is stable at version 1: a format change must bump +`snapshot.Version` and keep the reader for version 1. + ## Test data `treegen` creates synthetic trees: diff --git a/Makefile b/Makefile index af122f3..b634876 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev) LDFLAGS := -s -w PREFIX ?= /usr/local -.PHONY: build install man test race vet fmt fmt-check benchmark fuzz release clean treegen +.PHONY: build install man brew-formula test race vet fmt fmt-check benchmark fuzz release clean treegen build: go build -trimpath -ldflags '$(LDFLAGS)' -o $(BIN)/mapsize ./cmd/mapsize @@ -53,7 +53,7 @@ release: 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 $$d/; \ + cp README.md CHANGELOG.md 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/; \ @@ -64,5 +64,17 @@ release: done; \ cd $(REL) && sha256sum * > SHA256SUMS +# Homebrew formula for the tagged release. The tag must already be pushed: +# the checksum is of GitHub's source tarball for that tag. +BREW_REPO := https://github.com/andydixon/mapsize +brew-formula: + @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; \ + sum=$$(curl -fsSL "$$url" | sha256sum | cut -d' ' -f1) || { echo "cannot fetch $$url (tag pushed?)"; exit 1; }; \ + mkdir -p $(BIN)/homebrew; \ + sed -e "s/@VERSION@/$$v/g" -e "s/@SHA256@/$$sum/" packaging/homebrew/mapsize.rb.in > $(BIN)/homebrew/mapsize.rb; \ + echo "wrote $(BIN)/homebrew/mapsize.rb (v$$v, sha256 $$sum)" + clean: rm -rf $(BIN) diff --git a/README.md b/README.md index 5f17fbd..332f3a9 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,10 @@ runs over SSH. ## Status -Milestones 0.1–0.8 are implemented; 0.9 (hardening) is in progress. See -[ROADMAP.md](ROADMAP.md) for detail and [PERFORMANCE.md](PERFORMANCE.md) for -measured numbers. +Version 1.0. See [CHANGELOG.md](CHANGELOG.md), [ROADMAP.md](ROADMAP.md) for +what comes next, and [PERFORMANCE.md](PERFORMANCE.md) for measured numbers. +Tested on Linux; macOS and Windows builds are produced but trash and +file-manager integration have not yet been tested there. ## What it does @@ -69,10 +70,13 @@ the map or scrolls lists. Everything works without a mouse (`--no-mouse`). ## Install ```sh -go install github.com/andydixon/mapsize/cmd/mapsize@latest +go install github.com/andydixon/mapsize/cmd/mapsize@v1.0.0 # or make build # → bin/mapsize sudo make install # binary + man page under /usr/local (PREFIX=… to change) + +# Homebrew (macOS and Linux), once the tap is published +brew install andydixon/tap/mapsize ``` Full reference: `man mapsize` after installing, or `make man` / diff --git a/ROADMAP.md b/ROADMAP.md index 5457a73..796637c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -37,7 +37,7 @@ Status markers: `[x]` done, `[~]` partial, `[ ]` not started. - [x] read-only mode, JSON/CSV export - [x] move-to-trash: freedesktop trash (tested on Linux); macOS ~/.Trash and Windows Recycle Bin implemented but not yet tested on those systems -## 0.9 — hardening (ongoing) +## 0.9 — hardening - [~] profiling & benchmarks (warm-cache only so far) (see PERFORMANCE.md) - [ ] memory reduction (name arena) if profiles justify it - [ ] Windows allocated-size via GetCompressedFileSizeW (opt-in) @@ -46,5 +46,12 @@ Status markers: `[x]` done, `[~]` partial, `[ ]` not started. - [x] incremental path-predicate evaluation for filters - [ ] permanent deletion (deliberately not offered yet; trash only) -## 1.0 -- [ ] stable snapshot format v1 guarantee, packaged releases +## 1.0 (released 2026-10-02) +- [x] stable snapshot format v1 guarantee +- [x] packaged releases (`make release`: archives, deb/rpm/apk/Arch, checksums) +- [x] manual page + +## After 1.0 +Unchecked items above carry over; candidates for 1.1 are cold-cache +benchmarks, configurable keybindings and testing trash/reveal on macOS and +Windows. diff --git a/docs/mapsize.1 b/docs/mapsize.1 index 1ac89a9..487095a 100644 --- a/docs/mapsize.1 +++ b/docs/mapsize.1 @@ -1,5 +1,5 @@ .\" Manual page for mapsize. View with: man -l docs/mapsize.1 -.TH MAPSIZE 1 "October 2026" "mapsize 0.9.0-dev" "User Commands" +.TH MAPSIZE 1 "October 2026" "mapsize 1.0.0" "User Commands" .SH NAME mapsize \- interactive terminal disk usage analyser with a navigable treemap .SH SYNOPSIS diff --git a/internal/brand/brand.go b/internal/brand/brand.go index f298680..08a1891 100644 --- a/internal/brand/brand.go +++ b/internal/brand/brand.go @@ -8,4 +8,4 @@ const ( ) // Version is stamped at release time via -ldflags -X. -var Version = "0.9.0-dev" +var Version = "1.0.0" diff --git a/nfpm.yaml b/nfpm.yaml index da43ac8..9b6310b 100644 --- a/nfpm.yaml +++ b/nfpm.yaml @@ -7,3 +7,7 @@ homepage: https://github.com/andydixon/mapsize 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 diff --git a/packaging/homebrew/mapsize.rb.in b/packaging/homebrew/mapsize.rb.in new file mode 100644 index 0000000..bf7a8e7 --- /dev/null +++ b/packaging/homebrew/mapsize.rb.in @@ -0,0 +1,25 @@ +# Homebrew formula template for mapsize. `make brew-formula` fills in the +# version and the checksum of the GitHub source tarball and writes the +# result to bin/homebrew/mapsize.rb; copy that into your tap +# (github.com/andydixon/homebrew-tap, Formula/mapsize.rb). +class Mapsize < Formula + desc "Interactive terminal disk usage analyser with a navigable treemap" + homepage "https://dixon.cx" + url "https://github.com/andydixon/mapsize/archive/refs/tags/v@VERSION@.tar.gz" + sha256 "@SHA256@" + head "https://github.com/andydixon/mapsize.git", branch: "master" + + depends_on "go" => :build + + def install + ldflags = "-s -w -X github.com/andydixon/mapsize/internal/brand.Version=#{version}" + system "go", "build", *std_go_args(ldflags:), "./cmd/mapsize" + man1.install "docs/mapsize.1" + end + + test do + assert_match version.to_s, shell_output("#{bin}/mapsize --version") + (testpath/"data/file.txt").write "hello" + assert_match "Files", shell_output("#{bin}/mapsize --no-ui #{testpath}/data") + end +end