feat(packaging): Arch package with a display-manager session and vendored dist tarball
- commit
- 7abacfb5501e2b2e164b58e204e8855bd41236a7
- author
- brice · · 2026-09-26 05:48 UTC
- committer
- brice · · 2026-09-26 05:50 UTC
- parent
- 0b45e97
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
9 files · +113 -9
M .gitignore +1 -0
| @@ -4,3 +4,4 @@ | |||
| 4 | 4 | *.out | |
| 5 | 5 | coverage/ | |
| 6 | 6 | .worktrees/ | |
| 7 | + | /dist/ | |
| @@ -4,3 +4,4 @@ | |||||
| 4 | *.out | 4 | *.out | ||
| 5 | coverage/ | 5 | coverage/ | ||
| 6 | .worktrees/ | 6 | .worktrees/ | ||
| 7 | + | /dist/ | |||
M Makefile +25 -1
| @@ -1,4 +1,4 @@ | |||
| 1 | - | .PHONY: build test vet race mocks mocks-check fakes-check arch check bin tty logs | |
| 1 | + | .PHONY: build test vet race mocks mocks-check fakes-check arch check bin tty logs dist pkg | |
| 2 | 2 | ||
| 3 | 3 | # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net. | |
| 4 | 4 | TTY_TIMEOUT ?= 0 | |
| @@ -45,3 +45,27 @@ fakes-check: | |||
| 45 | 45 | arch: | |
| 46 | 46 | $(HOME)/go/bin/hexcheck -hexcheck.config .hexcheck.yaml -hexcheck.root . ./... | |
| 47 | 47 | check: vet test arch fakes-check | |
| 48 | + | ||
| 49 | + | # Self-contained source tarball for packaging (packaging/arch/PKGBUILD): the | |
| 50 | + | # sibling purego-* modules are vendored, so the package builds offline. | |
| 51 | + | # pacman-ordered: 0.0.0.r<commits>.g<hash>, a tag replaces 0.0.0 once there is one. | |
| 52 | + | VERSION ?= $(shell t=$$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//'); \ | |
| 53 | + | echo "$${t:-0.0.0}.r$$(git rev-list --count HEAD).g$$(git rev-parse --short HEAD)") | |
| 54 | + | DIST := dist/nefertty-$(VERSION) | |
| 55 | + | SIBLINGS := github.com/bnema/purego-libwayland github.com/bnema/purego-vulkan | |
| 56 | + | dist: | |
| 57 | + | @rm -rf $(DIST) && mkdir -p $(DIST) | |
| 58 | + | git archive $$(git stash create || echo HEAD) | tar -x -C $(DIST) | |
| 59 | + | cd $(DIST) && go mod edit $$(cd $(CURDIR) && go list -m -f '-replace={{.Path}}={{.Dir}}' $(SIBLINGS)) && go mod vendor && \ | |
| 60 | + | for m in $(SIBLINGS); do d=$$(cd $(CURDIR) && go list -m -f '{{.Dir}}' $$m); \ | |
| 61 | + | sed -i "s#=> $$d\$$#=> ../$${m##*/}#" go.mod vendor/modules.txt; done && \ | |
| 62 | + | ! grep -rq "$(HOME)" go.mod vendor/modules.txt && echo '$(VERSION)' > VERSION | |
| 63 | + | tar -C dist -czf $(DIST).tar.gz nefertty-$(VERSION) | |
| 64 | + | @rm -rf $(DIST) && echo $(DIST).tar.gz | |
| 65 | + | ||
| 66 | + | # Arch package from the dist tarball; install it with `sudo pacman -U` on | |
| 67 | + | # the printed file. | |
| 68 | + | pkg: dist | |
| 69 | + | rm -rf dist/pkg && mkdir -p dist/pkg && cp packaging/arch/PKGBUILD $(DIST).tar.gz dist/pkg/ | |
| 70 | + | cd dist/pkg && sed -i "s/^pkgver=.*/pkgver=$(VERSION)/" PKGBUILD && makepkg -f --noconfirm | |
| 71 | + | @ls dist/pkg/*.pkg.tar.zst | |
| @@ -1,4 +1,4 @@ | |||||
| 1 | - | .PHONY: build test vet race mocks mocks-check fakes-check arch check bin tty logs | 1 | + | .PHONY: build test vet race mocks mocks-check fakes-check arch check bin tty logs dist pkg |
| 2 | 2 | ||||
| 3 | # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net. | 3 | # 0 runs until quit; set e.g. TTY_TIMEOUT=60s for a safety net. | ||
| 4 | TTY_TIMEOUT ?= 0 | 4 | TTY_TIMEOUT ?= 0 | ||
| @@ -45,3 +45,27 @@ fakes-check: | |||||
| 45 | arch: | 45 | arch: | ||
| 46 | $(HOME)/go/bin/hexcheck -hexcheck.config .hexcheck.yaml -hexcheck.root . ./... | 46 | $(HOME)/go/bin/hexcheck -hexcheck.config .hexcheck.yaml -hexcheck.root . ./... | ||
| 47 | check: vet test arch fakes-check | 47 | check: vet test arch fakes-check | ||
| 48 | + | ||||
| 49 | + | # Self-contained source tarball for packaging (packaging/arch/PKGBUILD): the | |||
| 50 | + | # sibling purego-* modules are vendored, so the package builds offline. | |||
| 51 | + | # pacman-ordered: 0.0.0.r<commits>.g<hash>, a tag replaces 0.0.0 once there is one. | |||
| 52 | + | VERSION ?= $(shell t=$$(git describe --tags --abbrev=0 2>/dev/null | sed 's/^v//'); \ | |||
| 53 | + | echo "$${t:-0.0.0}.r$$(git rev-list --count HEAD).g$$(git rev-parse --short HEAD)") | |||
| 54 | + | DIST := dist/nefertty-$(VERSION) | |||
| 55 | + | SIBLINGS := github.com/bnema/purego-libwayland github.com/bnema/purego-vulkan | |||
| 56 | + | dist: | |||
| 57 | + | @rm -rf $(DIST) && mkdir -p $(DIST) | |||
| 58 | + | git archive $$(git stash create || echo HEAD) | tar -x -C $(DIST) | |||
| 59 | + | cd $(DIST) && go mod edit $$(cd $(CURDIR) && go list -m -f '-replace={{.Path}}={{.Dir}}' $(SIBLINGS)) && go mod vendor && \ | |||
| 60 | + | for m in $(SIBLINGS); do d=$$(cd $(CURDIR) && go list -m -f '{{.Dir}}' $$m); \ | |||
| 61 | + | sed -i "s#=> $$d\$$#=> ../$${m##*/}#" go.mod vendor/modules.txt; done && \ | |||
| 62 | + | ! grep -rq "$(HOME)" go.mod vendor/modules.txt && echo '$(VERSION)' > VERSION | |||
| 63 | + | tar -C dist -czf $(DIST).tar.gz nefertty-$(VERSION) | |||
| 64 | + | @rm -rf $(DIST) && echo $(DIST).tar.gz | |||
| 65 | + | ||||
| 66 | + | # Arch package from the dist tarball; install it with `sudo pacman -U` on | |||
| 67 | + | # the printed file. | |||
| 68 | + | pkg: dist | |||
| 69 | + | rm -rf dist/pkg && mkdir -p dist/pkg && cp packaging/arch/PKGBUILD $(DIST).tar.gz dist/pkg/ | |||
| 70 | + | cd dist/pkg && sed -i "s/^pkgver=.*/pkgver=$(VERSION)/" PKGBUILD && makepkg -f --noconfirm | |||
| 71 | + | @ls dist/pkg/*.pkg.tar.zst | |||
M README.md +9 -0
| @@ -14,6 +14,15 @@ Build: `make build` (requires sibling checkouts of purego-libwayland and purego- | |||
| 14 | 14 | ||
| 15 | 15 | Run: `nefertty --backend=headless --timeout 5s` | |
| 16 | 16 | ||
| 17 | + | ## Install (Arch Linux) | |
| 18 | + | ||
| 19 | + | ```sh | |
| 20 | + | make pkg # builds dist/pkg/nefertty-*.pkg.tar.zst | |
| 21 | + | sudo pacman -U dist/pkg/nefertty-*.pkg.tar.zst | |
| 22 | + | ``` | |
| 23 | + | ||
| 24 | + | The package installs `nefertty` and a **NeferTTY** session for display managers (Ly, GDM, SDDM). The session runs `nefertty --session`, which shares `WAYLAND_DISPLAY` and `DISPLAY` with D-Bus and systemd user services, so portals and notification daemons reach it. `make dist` alone builds the self-contained source tarball (Go modules vendored) that the package uses. | |
| 25 | + | ||
| 17 | 26 | ## Configuration | |
| 18 | 27 | ||
| 19 | 28 | Configuration lives at `$XDG_CONFIG_HOME/nefertty/config` (or `~/.config/nefertty/config`). Use `nefertty --config path` to select another file; `nefertty validate-config [path]` checks it without starting the compositor. | |
| @@ -14,6 +14,15 @@ Build: `make build` (requires sibling checkouts of purego-libwayland and purego- | |||||
| 14 | 14 | ||||
| 15 | Run: `nefertty --backend=headless --timeout 5s` | 15 | Run: `nefertty --backend=headless --timeout 5s` | ||
| 16 | 16 | ||||
| 17 | + | ## Install (Arch Linux) | |||
| 18 | + | ||||
| 19 | + | ```sh | |||
| 20 | + | make pkg # builds dist/pkg/nefertty-*.pkg.tar.zst | |||
| 21 | + | sudo pacman -U dist/pkg/nefertty-*.pkg.tar.zst | |||
| 22 | + | ``` | |||
| 23 | + | ||||
| 24 | + | The package installs `nefertty` and a **NeferTTY** session for display managers (Ly, GDM, SDDM). The session runs `nefertty --session`, which shares `WAYLAND_DISPLAY` and `DISPLAY` with D-Bus and systemd user services, so portals and notification daemons reach it. `make dist` alone builds the self-contained source tarball (Go modules vendored) that the package uses. | |||
| 25 | + | ||||
| 17 | ## Configuration | 26 | ## Configuration | ||
| 18 | 27 | ||||
| 19 | Configuration lives at `$XDG_CONFIG_HOME/nefertty/config` (or `~/.config/nefertty/config`). Use `nefertty --config path` to select another file; `nefertty validate-config [path]` checks it without starting the compositor. | 28 | Configuration lives at `$XDG_CONFIG_HOME/nefertty/config` (or `~/.config/nefertty/config`). Use `nefertty --config path` to select another file; `nefertty validate-config [path]` checks it without starting the compositor. | ||
M cmd/nefertty/main.go +19 -4
| @@ -23,6 +23,13 @@ import ( | |||
| 23 | 23 | ||
| 24 | 24 | type usageError struct{ error } | |
| 25 | 25 | ||
| 26 | + | // sessionEnvCommand exports the session environment to D-Bus and systemd | |
| 27 | + | // user services (--session). | |
| 28 | + | var sessionEnvCommand = []string{"dbus-update-activation-environment", "--systemd", "WAYLAND_DISPLAY", "DISPLAY", "XDG_CURRENT_DESKTOP", "XDG_SESSION_TYPE"} | |
| 29 | + | ||
| 30 | + | // version is set with -ldflags "-X main.version=..." by packaged builds. | |
| 31 | + | var version string | |
| 32 | + | ||
| 26 | 33 | func main() { | |
| 27 | 34 | tuneGC() | |
| 28 | 35 | os.Exit(runCode()) | |
| @@ -99,11 +106,13 @@ func run() error { | |||
| 99 | 106 | fmt.Println("unknown") | |
| 100 | 107 | return nil | |
| 101 | 108 | } | |
| 102 | - | version := info.Main.Version | |
| 103 | - | if version == "" { | |
| 104 | - | version = "(devel)" | |
| 109 | + | v := info.Main.Version | |
| 110 | + | if version != "" { | |
| 111 | + | v = version // set by release builds (make dist) | |
| 112 | + | } else if v == "" { | |
| 113 | + | v = "(devel)" | |
| 105 | 114 | } | |
| 106 | - | fmt.Println(version) | |
| 115 | + | fmt.Println(v) | |
| 107 | 116 | return nil | |
| 108 | 117 | } | |
| 109 | 118 | flags := flag.NewFlagSet("nefertty", flag.ContinueOnError) | |
| @@ -116,6 +125,7 @@ func run() error { | |||
| 116 | 125 | timeout := flags.Duration("timeout", 0, "duration before exit (0 disables timeout)") | |
| 117 | 126 | debugFlag := flags.String("debug", "", "debug components (comma-separated or all)") | |
| 118 | 127 | configFlag := flags.String("config", "", "config path (empty uses XDG default)") | |
| 128 | + | session := flags.Bool("session", false, "run as the login session: share WAYLAND_DISPLAY and DISPLAY with systemd and D-Bus user services") | |
| 119 | 129 | if err := flags.Parse(os.Args[1:]); err != nil { | |
| 120 | 130 | if errors.Is(err, flag.ErrHelp) { | |
| 121 | 131 | return err | |
| @@ -180,6 +190,11 @@ func run() error { | |||
| 180 | 190 | fmt.Fprintln(os.Stderr, cfgErr) | |
| 181 | 191 | return cfgErr | |
| 182 | 192 | } | |
| 193 | + | if *session { | |
| 194 | + | // First startup command: portals and other D-Bus or systemd user | |
| 195 | + | // services started later find the session's displays. | |
| 196 | + | cfg.Startup = append([][]string{sessionEnvCommand}, cfg.Startup...) | |
| 197 | + | } | |
| 183 | 198 | var script *os.File | |
| 184 | 199 | if *inputPath != "" { | |
| 185 | 200 | if *inputPath == "-" { | |
| @@ -23,6 +23,13 @@ import ( | |||||
| 23 | 23 | ||||
| 24 | type usageError struct{ error } | 24 | type usageError struct{ error } | ||
| 25 | 25 | ||||
| 26 | + | // sessionEnvCommand exports the session environment to D-Bus and systemd | |||
| 27 | + | // user services (--session). | |||
| 28 | + | var sessionEnvCommand = []string{"dbus-update-activation-environment", "--systemd", "WAYLAND_DISPLAY", "DISPLAY", "XDG_CURRENT_DESKTOP", "XDG_SESSION_TYPE"} | |||
| 29 | + | ||||
| 30 | + | // version is set with -ldflags "-X main.version=..." by packaged builds. | |||
| 31 | + | var version string | |||
| 32 | + | ||||
| 26 | func main() { | 33 | func main() { | ||
| 27 | tuneGC() | 34 | tuneGC() | ||
| 28 | os.Exit(runCode()) | 35 | os.Exit(runCode()) | ||
| @@ -99,11 +106,13 @@ func run() error { | |||||
| 99 | fmt.Println("unknown") | 106 | fmt.Println("unknown") | ||
| 100 | return nil | 107 | return nil | ||
| 101 | } | 108 | } | ||
| 102 | - | version := info.Main.Version | 109 | + | v := info.Main.Version |
| 103 | - | if version == "" { | 110 | + | if version != "" { |
| 104 | - | version = "(devel)" | 111 | + | v = version // set by release builds (make dist) |
| 112 | + | } else if v == "" { | |||
| 113 | + | v = "(devel)" | |||
| 105 | } | 114 | } | ||
| 106 | - | fmt.Println(version) | 115 | + | fmt.Println(v) |
| 107 | return nil | 116 | return nil | ||
| 108 | } | 117 | } | ||
| 109 | flags := flag.NewFlagSet("nefertty", flag.ContinueOnError) | 118 | flags := flag.NewFlagSet("nefertty", flag.ContinueOnError) | ||
| @@ -116,6 +125,7 @@ func run() error { | |||||
| 116 | timeout := flags.Duration("timeout", 0, "duration before exit (0 disables timeout)") | 125 | timeout := flags.Duration("timeout", 0, "duration before exit (0 disables timeout)") | ||
| 117 | debugFlag := flags.String("debug", "", "debug components (comma-separated or all)") | 126 | debugFlag := flags.String("debug", "", "debug components (comma-separated or all)") | ||
| 118 | configFlag := flags.String("config", "", "config path (empty uses XDG default)") | 127 | configFlag := flags.String("config", "", "config path (empty uses XDG default)") | ||
| 128 | + | session := flags.Bool("session", false, "run as the login session: share WAYLAND_DISPLAY and DISPLAY with systemd and D-Bus user services") | |||
| 119 | if err := flags.Parse(os.Args[1:]); err != nil { | 129 | if err := flags.Parse(os.Args[1:]); err != nil { | ||
| 120 | if errors.Is(err, flag.ErrHelp) { | 130 | if errors.Is(err, flag.ErrHelp) { | ||
| 121 | return err | 131 | return err | ||
| @@ -180,6 +190,11 @@ func run() error { | |||||
| 180 | fmt.Fprintln(os.Stderr, cfgErr) | 190 | fmt.Fprintln(os.Stderr, cfgErr) | ||
| 181 | return cfgErr | 191 | return cfgErr | ||
| 182 | } | 192 | } | ||
| 193 | + | if *session { | |||
| 194 | + | // First startup command: portals and other D-Bus or systemd user | |||
| 195 | + | // services started later find the session's displays. | |||
| 196 | + | cfg.Startup = append([][]string{sessionEnvCommand}, cfg.Startup...) | |||
| 197 | + | } | |||
| 183 | var script *os.File | 198 | var script *os.File | ||
| 184 | if *inputPath != "" { | 199 | if *inputPath != "" { | ||
| 185 | if *inputPath == "-" { | 200 | if *inputPath == "-" { | ||
M internal/adapters/launcher/launcher.go +1 -1
| @@ -32,7 +32,7 @@ func ChildEnv(base []string, waylandDisplay, runtimeDir string, cursorSize int) | |||
| 32 | 32 | continue | |
| 33 | 33 | } | |
| 34 | 34 | switch { | |
| 35 | - | case key == "HOME", key == "USER", key == "LOGNAME", key == "SHELL", key == "PATH", key == "LANG", strings.HasPrefix(key, "LC_"), strings.HasPrefix(key, "XDG_"), strings.HasPrefix(key, "XCURSOR_"): | |
| 35 | + | case key == "HOME", key == "USER", key == "LOGNAME", key == "SHELL", key == "PATH", key == "LANG", key == "DBUS_SESSION_BUS_ADDRESS", strings.HasPrefix(key, "LC_"), strings.HasPrefix(key, "XDG_"), strings.HasPrefix(key, "XCURSOR_"): | |
| 36 | 36 | values[key] = value | |
| 37 | 37 | } | |
| 38 | 38 | } | |
| @@ -32,7 +32,7 @@ func ChildEnv(base []string, waylandDisplay, runtimeDir string, cursorSize int) | |||||
| 32 | continue | 32 | continue | ||
| 33 | } | 33 | } | ||
| 34 | switch { | 34 | switch { | ||
| 35 | - | case key == "HOME", key == "USER", key == "LOGNAME", key == "SHELL", key == "PATH", key == "LANG", strings.HasPrefix(key, "LC_"), strings.HasPrefix(key, "XDG_"), strings.HasPrefix(key, "XCURSOR_"): | 35 | + | case key == "HOME", key == "USER", key == "LOGNAME", key == "SHELL", key == "PATH", key == "LANG", key == "DBUS_SESSION_BUS_ADDRESS", strings.HasPrefix(key, "LC_"), strings.HasPrefix(key, "XDG_"), strings.HasPrefix(key, "XCURSOR_"): |
| 36 | values[key] = value | 36 | values[key] = value | ||
| 37 | } | 37 | } | ||
| 38 | } | 38 | } | ||
M internal/adapters/launcher/launcher_test.go +2 -2
| @@ -14,8 +14,8 @@ import ( | |||
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | 16 | func TestChildEnv(t *testing.T) { | |
| 17 | - | got := ChildEnv([]string{"TERM=x", "DISPLAY=:0", "WAYLAND_SOCKET=4", "WAYLAND_DISPLAY=old", "HOME=/home/me", "PATH=/bin", "LC_ALL=C", "XDG_RUNTIME_DIR=old", "XCURSOR_THEME=Adwaita", "XCURSOR_PATH=/icons", "SECRET=bad"}, "wayland-7", "/run/me", 24) | |
| 18 | - | want := []string{"HOME=/home/me", "LC_ALL=C", "PATH=/bin", "WAYLAND_DISPLAY=wayland-7", "XCURSOR_PATH=/icons", "XCURSOR_SIZE=24", "XCURSOR_THEME=Adwaita", "XDG_CURRENT_DESKTOP=nefertty", "XDG_RUNTIME_DIR=/run/me", "XDG_SESSION_TYPE=wayland"} | |
| 17 | + | got := ChildEnv([]string{"TERM=x", "DISPLAY=:0", "WAYLAND_SOCKET=4", "WAYLAND_DISPLAY=old", "HOME=/home/me", "PATH=/bin", "LC_ALL=C", "XDG_RUNTIME_DIR=old", "XCURSOR_THEME=Adwaita", "XCURSOR_PATH=/icons", "SECRET=bad", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/me/bus"}, "wayland-7", "/run/me", 24) | |
| 18 | + | want := []string{"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/me/bus", "HOME=/home/me", "LC_ALL=C", "PATH=/bin", "WAYLAND_DISPLAY=wayland-7", "XCURSOR_PATH=/icons", "XCURSOR_SIZE=24", "XCURSOR_THEME=Adwaita", "XDG_CURRENT_DESKTOP=nefertty", "XDG_RUNTIME_DIR=/run/me", "XDG_SESSION_TYPE=wayland"} | |
| 19 | 19 | if !reflect.DeepEqual(got, want) { | |
| 20 | 20 | t.Fatalf("got %v want %v", got, want) | |
| 21 | 21 | } | |
| @@ -14,8 +14,8 @@ import ( | |||||
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | func TestChildEnv(t *testing.T) { | 16 | func TestChildEnv(t *testing.T) { | ||
| 17 | - | got := ChildEnv([]string{"TERM=x", "DISPLAY=:0", "WAYLAND_SOCKET=4", "WAYLAND_DISPLAY=old", "HOME=/home/me", "PATH=/bin", "LC_ALL=C", "XDG_RUNTIME_DIR=old", "XCURSOR_THEME=Adwaita", "XCURSOR_PATH=/icons", "SECRET=bad"}, "wayland-7", "/run/me", 24) | 17 | + | got := ChildEnv([]string{"TERM=x", "DISPLAY=:0", "WAYLAND_SOCKET=4", "WAYLAND_DISPLAY=old", "HOME=/home/me", "PATH=/bin", "LC_ALL=C", "XDG_RUNTIME_DIR=old", "XCURSOR_THEME=Adwaita", "XCURSOR_PATH=/icons", "SECRET=bad", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/me/bus"}, "wayland-7", "/run/me", 24) |
| 18 | - | want := []string{"HOME=/home/me", "LC_ALL=C", "PATH=/bin", "WAYLAND_DISPLAY=wayland-7", "XCURSOR_PATH=/icons", "XCURSOR_SIZE=24", "XCURSOR_THEME=Adwaita", "XDG_CURRENT_DESKTOP=nefertty", "XDG_RUNTIME_DIR=/run/me", "XDG_SESSION_TYPE=wayland"} | 18 | + | want := []string{"DBUS_SESSION_BUS_ADDRESS=unix:path=/run/me/bus", "HOME=/home/me", "LC_ALL=C", "PATH=/bin", "WAYLAND_DISPLAY=wayland-7", "XCURSOR_PATH=/icons", "XCURSOR_SIZE=24", "XCURSOR_THEME=Adwaita", "XDG_CURRENT_DESKTOP=nefertty", "XDG_RUNTIME_DIR=/run/me", "XDG_SESSION_TYPE=wayland"} |
| 19 | if !reflect.DeepEqual(got, want) { | 19 | if !reflect.DeepEqual(got, want) { | ||
| 20 | t.Fatalf("got %v want %v", got, want) | 20 | t.Fatalf("got %v want %v", got, want) | ||
| 21 | } | 21 | } | ||
M internal/adapters/wayland/layer_test.go +10 -1
| @@ -128,7 +128,16 @@ func TestWaybarLayer(t *testing.T) { | |||
| 128 | 128 | if err = os.WriteFile(style, nil, 0600); err != nil { | |
| 129 | 129 | t.Fatal(err) | |
| 130 | 130 | } | |
| 131 | - | _, done, output := lifecycleClient(t, tool, s, dir, []string{"HOME=" + home}, "-c", config, "-s", style) | |
| 131 | + | // waybar (gio) aborts without a session bus; the user bus is the default. | |
| 132 | + | bus := os.Getenv("DBUS_SESSION_BUS_ADDRESS") | |
| 133 | + | if bus == "" { | |
| 134 | + | sock := os.Getenv("XDG_RUNTIME_DIR") + "/bus" | |
| 135 | + | if _, err := os.Stat(sock); err != nil { | |
| 136 | + | t.Skip("no D-Bus session bus") | |
| 137 | + | } | |
| 138 | + | bus = "unix:path=" + sock | |
| 139 | + | } | |
| 140 | + | _, done, output := lifecycleClient(t, tool, s, dir, []string{"HOME=" + home, "DBUS_SESSION_BUS_ADDRESS=" + bus}, "-c", config, "-s", style) | |
| 132 | 141 | select { | |
| 133 | 142 | case ev := <-events: | |
| 134 | 143 | v, ok := ev.(ports.LayerChanged) | |
| @@ -128,7 +128,16 @@ func TestWaybarLayer(t *testing.T) { | |||||
| 128 | if err = os.WriteFile(style, nil, 0600); err != nil { | 128 | if err = os.WriteFile(style, nil, 0600); err != nil { | ||
| 129 | t.Fatal(err) | 129 | t.Fatal(err) | ||
| 130 | } | 130 | } | ||
| 131 | - | _, done, output := lifecycleClient(t, tool, s, dir, []string{"HOME=" + home}, "-c", config, "-s", style) | 131 | + | // waybar (gio) aborts without a session bus; the user bus is the default. |
| 132 | + | bus := os.Getenv("DBUS_SESSION_BUS_ADDRESS") | |||
| 133 | + | if bus == "" { | |||
| 134 | + | sock := os.Getenv("XDG_RUNTIME_DIR") + "/bus" | |||
| 135 | + | if _, err := os.Stat(sock); err != nil { | |||
| 136 | + | t.Skip("no D-Bus session bus") | |||
| 137 | + | } | |||
| 138 | + | bus = "unix:path=" + sock | |||
| 139 | + | } | |||
| 140 | + | _, done, output := lifecycleClient(t, tool, s, dir, []string{"HOME=" + home, "DBUS_SESSION_BUS_ADDRESS=" + bus}, "-c", config, "-s", style) | |||
| 132 | select { | 141 | select { | ||
| 133 | case ev := <-events: | 142 | case ev := <-events: | ||
| 134 | v, ok := ev.(ports.LayerChanged) | 143 | v, ok := ev.(ports.LayerChanged) | ||
A packaging/arch/PKGBUILD +40 -0
| @@ -0,0 +1,40 @@ | |||
| 1 | + | # Built by `make pkg` at the repo root, from the `make dist` tarball. | |
| 2 | + | pkgname=nefertty | |
| 3 | + | pkgver=0.0.0 | |
| 4 | + | pkgrel=1 | |
| 5 | + | pkgdesc='Minimal Wayland compositor with scrollable columns, for the TTY' | |
| 6 | + | arch=('x86_64') | |
| 7 | + | url='https://github.com/bnema/nefertty' | |
| 8 | + | license=('MIT') | |
| 9 | + | # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan. | |
| 10 | + | depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader' | |
| 11 | + | 'vulkan-driver') | |
| 12 | + | makedepends=('go') | |
| 13 | + | optdepends=('xwayland-satellite: X11 apps' | |
| 14 | + | 'foot: default terminal' | |
| 15 | + | 'fuzzel: launcher' | |
| 16 | + | 'xdg-desktop-portal-gtk: file pickers and settings for apps') | |
| 17 | + | options=('!debug') | |
| 18 | + | source=("$pkgname-$pkgver.tar.gz") | |
| 19 | + | sha256sums=('SKIP') | |
| 20 | + | ||
| 21 | + | build() { | |
| 22 | + | cd "$pkgname-$pkgver" | |
| 23 | + | export CGO_ENABLED=0 GOFLAGS='-mod=vendor -trimpath -buildvcs=false' GOPROXY=off | |
| 24 | + | go build -ldflags "-s -w -X main.version=$pkgver" -o nefertty ./cmd/nefertty | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | check() { | |
| 28 | + | cd "$pkgname-$pkgver" | |
| 29 | + | ./nefertty version | |
| 30 | + | ./nefertty validate-config examples/config | |
| 31 | + | } | |
| 32 | + | ||
| 33 | + | package() { | |
| 34 | + | cd "$pkgname-$pkgver" | |
| 35 | + | install -Dm755 nefertty "$pkgdir/usr/bin/nefertty" | |
| 36 | + | install -Dm644 packaging/nefertty.desktop "$pkgdir/usr/share/wayland-sessions/nefertty.desktop" | |
| 37 | + | install -Dm644 examples/config "$pkgdir/usr/share/doc/nefertty/config.example" | |
| 38 | + | install -Dm644 README.md "$pkgdir/usr/share/doc/nefertty/README.md" | |
| 39 | + | install -Dm644 LICENSE "$pkgdir/usr/share/licenses/nefertty/LICENSE" | |
| 40 | + | } | |
| @@ -0,0 +1,40 @@ | |||||
| 1 | + | # Built by `make pkg` at the repo root, from the `make dist` tarball. | |||
| 2 | + | pkgname=nefertty | |||
| 3 | + | pkgver=0.0.0 | |||
| 4 | + | pkgrel=1 | |||
| 5 | + | pkgdesc='Minimal Wayland compositor with scrollable columns, for the TTY' | |||
| 6 | + | arch=('x86_64') | |||
| 7 | + | url='https://github.com/bnema/nefertty' | |||
| 8 | + | license=('MIT') | |||
| 9 | + | # Loaded at runtime (purego, no cgo): not seen by makepkg's library scan. | |||
| 10 | + | depends=('glibc' 'libinput' 'libxkbcommon' 'seatd' 'systemd-libs' 'vulkan-icd-loader' | |||
| 11 | + | 'vulkan-driver') | |||
| 12 | + | makedepends=('go') | |||
| 13 | + | optdepends=('xwayland-satellite: X11 apps' | |||
| 14 | + | 'foot: default terminal' | |||
| 15 | + | 'fuzzel: launcher' | |||
| 16 | + | 'xdg-desktop-portal-gtk: file pickers and settings for apps') | |||
| 17 | + | options=('!debug') | |||
| 18 | + | source=("$pkgname-$pkgver.tar.gz") | |||
| 19 | + | sha256sums=('SKIP') | |||
| 20 | + | ||||
| 21 | + | build() { | |||
| 22 | + | cd "$pkgname-$pkgver" | |||
| 23 | + | export CGO_ENABLED=0 GOFLAGS='-mod=vendor -trimpath -buildvcs=false' GOPROXY=off | |||
| 24 | + | go build -ldflags "-s -w -X main.version=$pkgver" -o nefertty ./cmd/nefertty | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | check() { | |||
| 28 | + | cd "$pkgname-$pkgver" | |||
| 29 | + | ./nefertty version | |||
| 30 | + | ./nefertty validate-config examples/config | |||
| 31 | + | } | |||
| 32 | + | ||||
| 33 | + | package() { | |||
| 34 | + | cd "$pkgname-$pkgver" | |||
| 35 | + | install -Dm755 nefertty "$pkgdir/usr/bin/nefertty" | |||
| 36 | + | install -Dm644 packaging/nefertty.desktop "$pkgdir/usr/share/wayland-sessions/nefertty.desktop" | |||
| 37 | + | install -Dm644 examples/config "$pkgdir/usr/share/doc/nefertty/config.example" | |||
| 38 | + | install -Dm644 README.md "$pkgdir/usr/share/doc/nefertty/README.md" | |||
| 39 | + | install -Dm644 LICENSE "$pkgdir/usr/share/licenses/nefertty/LICENSE" | |||
| 40 | + | } | |||
A packaging/nefertty.desktop +6 -0
| @@ -0,0 +1,6 @@ | |||
| 1 | + | [Desktop Entry] | |
| 2 | + | Name=NeferTTY | |
| 3 | + | Comment=Minimal Wayland compositor with scrollable columns | |
| 4 | + | Exec=nefertty --session | |
| 5 | + | Type=Application | |
| 6 | + | DesktopNames=nefertty | |
| @@ -0,0 +1,6 @@ | |||||
| 1 | + | [Desktop Entry] | |||
| 2 | + | Name=NeferTTY | |||
| 3 | + | Comment=Minimal Wayland compositor with scrollable columns | |||
| 4 | + | Exec=nefertty --session | |||
| 5 | + | Type=Application | |||
| 6 | + | DesktopNames=nefertty | |||