From 37d6802815b60f3d0c2b2aa7401cc0d73b5f37a5 Mon Sep 17 00:00:00 2001 From: Florian Walther Date: Sat, 3 Oct 2026 16:58:50 +0200 Subject: [PATCH] add goreleaser configuration for binaries and deb/rpm packages - build static binaries for linux, darwin and freebsd - create deb and rpm packages that register gosh in /etc/shells - publish releases to Gitea - add --version flag, set at build time via ldflags Co-Authored-By: Claude Opus 5.5 --- .gitignore | 1 + .goreleaser.yaml | 103 +++++++++++++++++++++++++++++++ README.md | 17 +++++ main.go | 8 +++ packaging/scripts/postinstall.sh | 9 +++ packaging/scripts/postremove.sh | 14 +++++ 6 files changed, 152 insertions(+) create mode 100644 .goreleaser.yaml create mode 100755 packaging/scripts/postinstall.sh create mode 100755 packaging/scripts/postremove.sh diff --git a/.gitignore b/.gitignore index e547483..60e4762 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ gosh +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 0000000..9d2a454 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,103 @@ +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# Release: git tag -a v0.1.0 -m "v0.1.0" && git push origin v0.1.0 && goreleaser release --clean +# Local test (no publishing): goreleaser release --snapshot --clean +version: 2 + +project_name: gosh + +# GITHUB_TOKEN/GITLAB_TOKEN may also be set; always use Gitea. +force_token: gitea + +before: + hooks: + - go mod tidy + - go test ./... + +builds: + - id: gosh + binary: gosh + main: . + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -s -w -X main.version={{ .Version }} + goos: + - linux + - darwin + - freebsd + goarch: + - amd64 + - arm64 + - arm + - "386" + goarm: + - "7" + ignore: + - goos: darwin + goarch: "386" + - goos: darwin + goarch: arm + mod_timestamp: "{{ .CommitTimestamp }}" + +archives: + - id: gosh + formats: [tar.gz] + name_template: >- + {{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }} + files: + - src: README.md + info: + mode: 0644 + +nfpms: + - id: gosh + package_name: gosh + file_name_template: "{{ .ConventionalFileName }}" + ids: [gosh] + formats: + - deb + - rpm + vendor: Florian Walther + maintainer: Florian Walther + homepage: https://gitea.scu.si/Florian.Walther/gosh + description: |- + gosh - a simple shell written in Go + Proof of concept with history, tab completion, + tilde and environment variable expansion. + license: "" + section: shells + priority: optional + bindir: /usr/bin + contents: + - src: README.md + dst: /usr/share/doc/gosh/README.md + file_info: + mode: 0644 + scripts: + postinstall: packaging/scripts/postinstall.sh + postremove: packaging/scripts/postremove.sh + +checksum: + name_template: checksums.txt + +snapshot: + version_template: "{{ incpatch .Version }}-next" + +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" + +# Repository is hosted on Gitea; requires GITEA_TOKEN in the environment. +gitea_urls: + api: https://gitea.scu.si/api/v1 + download: https://gitea.scu.si + +release: + gitea: + owner: Florian.Walther + name: gosh diff --git a/README.md b/README.md index fd09689..2b6aba3 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,20 @@ _gosh is not meant for production use, it is just a proof of concept._ ```bash go build ./ ``` + +## Release + +Binaries sowie `.deb`- und `.rpm`-Pakete werden mit [GoReleaser](https://goreleaser.com) gebaut (Konfiguration: `.goreleaser.yaml`). + +```bash +# lokal testen, ohne etwas zu veröffentlichen (Ergebnis in dist/) +goreleaser release --snapshot --clean + +# Release auf Gitea veröffentlichen +export GITEA_TOKEN=... +git tag -a v0.1.0 -m "v0.1.0" +git push origin v0.1.0 +goreleaser release --clean +``` + +Das Paket installiert `/usr/bin/gosh` und trägt die Shell in `/etc/shells` ein, sodass sie mit `chsh -s /usr/bin/gosh` gesetzt werden kann. diff --git a/main.go b/main.go index 5906db7..34b7381 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,9 @@ import ( // ErrNoPath is returned when 'cd' was called without a second argument. var ErrNoPath = errors.New("path required") +// version is set at build time via -ldflags "-X main.version=..." +var version = "dev" + // previousDir tracks the previous working directory for 'cd -' support var previousDir string @@ -483,6 +486,11 @@ func completeFilePath(line, prefix string) []string { } func main() { + if len(os.Args) > 1 && (os.Args[1] == "--version" || os.Args[1] == "-V") { + fmt.Println("gosh", version) + return + } + // Ctrl+C sends SIGINT to the whole foreground process group. Catch it so // that it only stops the running command and not the shell. (signal.Ignore // would be inherited by the child processes.) diff --git a/packaging/scripts/postinstall.sh b/packaging/scripts/postinstall.sh new file mode 100755 index 0000000..6561ee5 --- /dev/null +++ b/packaging/scripts/postinstall.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# Register gosh as a login shell in /etc/shells. +set -e + +if command -v add-shell >/dev/null 2>&1; then + add-shell /usr/bin/gosh +elif ! grep -qx /usr/bin/gosh /etc/shells 2>/dev/null; then + echo /usr/bin/gosh >> /etc/shells +fi diff --git a/packaging/scripts/postremove.sh b/packaging/scripts/postremove.sh new file mode 100755 index 0000000..691c69c --- /dev/null +++ b/packaging/scripts/postremove.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Remove gosh from /etc/shells on uninstall (not on upgrade). +# deb passes "remove"/"purge", rpm passes "0" on final removal. +set -e + +case "$1" in + remove|purge|0) + if command -v remove-shell >/dev/null 2>&1; then + remove-shell /usr/bin/gosh + elif [ -f /etc/shells ]; then + sed -i '\|^/usr/bin/gosh$|d' /etc/shells + fi + ;; +esac