Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
155 lines (135 loc) · 6.59 KB
/
Copy pathMakefile
File metadata and controls
155 lines (135 loc) · 6.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
GO ?= go
BINARY := tmux-popup-control
GOCACHE := $(CURDIR)/.gocache
GOMODCACHE := $(CURDIR)/.gomodcache
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
# Path to a markdown file with release notes; falls back to gh's generated notes.
RELEASE_NOTES ?=
LDFLAGS := -ldflags="-X main.Version=$(VERSION)"
# Base env for offline builds. GOTMUXCC_TRACE is intentionally NOT set here:
# enabling it makes every gotmuxcc call write a trace line to disk and slows
# integration tests by ~4x (6s → 24s for `make test`). Use `make test-trace`
# (or set GOTMUXCC_TRACE=1 manually) when you actually want the trace log.
GO_ENV := GOCACHE=$(GOCACHE) GOMODCACHE=$(GOMODCACHE) GOFLAGS=-modcacherw GOPROXY=off
GO_ENV_TRACED := GOTMUXCC_TRACE=1 GOTMUXCC_TRACE_FILE=$(CURDIR)/gotmuxcc_trace.log $(GO_ENV)
# Tests must never reach the tmux server `make` was started from: code under
# test treats an empty socket as "the current server" ($TMUX, else the default
# socket under $TMUX_TMPDIR — the user's own server either way), and a test
# that once fell through to a real `tmux kill-session` destroyed live user
# sessions. ISOLATED_TEST runs a command with $TMUX/$TMUX_PANE removed and
# TMUX_TMPDIR pointing at a fresh empty directory, so a stray socketless tmux
# call finds no server at all. Every test package's TestMain applies the same
# isolation (testutil.IsolateFromUserServer); this is the second, independent
# layer.
define ISOLATED_TEST
tmpdir=$$(mktemp -d /tmp/tmux-popup-control-noserver.XXXXXX) && \
env -u TMUX -u TMUX_PANE TMUX_TMPDIR=$$tmpdir $(1); \
rc=$$?; rm -rf $$tmpdir; exit $$rc
endef
.SILENT:
.PHONY: build run tidy fmt test test-trace clean-cache ensure-dirs cover update-gotmuxcc update-deps release codesign-darwin notarize-darwin
ensure-dirs:
mkdir -p $(GOCACHE) $(GOMODCACHE)
build: ensure-dirs
$(GO_ENV) go build $(LDFLAGS) -o $(BINARY) .
run: ensure-dirs
$(GO_ENV) go run .
fmt:
$(GO_ENV) gofmt -w .
tidy: ensure-dirs
$(GO_ENV) go mod tidy
test: ensure-dirs
# -p 4 caps concurrent package execution at 4. The default
# (GOMAXPROCS=16 on this machine) runs every package in parallel,
# which means the 4 integration test binaries (resurrect, testutil,
# tmux, ui) each fire their tests at full thread pressure
# simultaneously — every tmux operation then queues behind every
# other test's tmux operations and a clean run stretches from ~7s
# to ~24s. With -p 4 the integration packages still run
# concurrently with each other but the rest of the suite fills
# remaining slots one-at-a-time, keeping per-test contention low.
# Cold cache: ~7s. Warm cache (no source changes): <1s.
$(call ISOLATED_TEST,$(GO_ENV) go test -p 4 ./...)
test-trace: ensure-dirs
# Same as `make test` but with gotmuxcc command tracing enabled.
# Trace lines land in $(CURDIR)/gotmuxcc_trace.log. Roughly 4x
# slower than `make test`; use only when you need the trace.
$(call ISOLATED_TEST,$(GO_ENV_TRACED) go test -p 4 ./...)
GO_ENV_ONLINE := GOCACHE=$(GOCACHE) GOMODCACHE=$(GOMODCACHE) GOFLAGS=-modcacherw GOPROXY=direct
update-gotmuxcc: ensure-dirs
$(GO_ENV_ONLINE) go get github.com/atomicstack/gotmuxcc@latest
$(GO_ENV_ONLINE) go mod tidy
$(GO_ENV_ONLINE) go mod vendor
update-deps: ensure-dirs
$(GO_ENV_ONLINE) go get -u ./...
$(GO_ENV_ONLINE) go mod tidy
$(GO_ENV_ONLINE) go mod vendor
clean-cache:
rm -rf $(GOCACHE) $(GOMODCACHE)
cover:
@echo "==> Generating coverage report"
$(call ISOLATED_TEST,$(GO) test ./... -coverprofile=coverage.out)
@echo "Coverage summary:"
$(GO) tool cover -func=coverage.out
RELEASE_DIR := dist
PLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64
RELEASE_SUPPORT_FILES := README.md main.sh main.tmux
# --- macOS signing / notarisation (opt-in) ---------------------------------
# SIGN_IDENTITY must name a "Developer ID Application" identity. An "Apple
# Development" certificate signs fine locally but the notary service rejects
# it, so the check that matters is:
# security find-identity -v -p codesigning | grep "Developer ID Application"
#
# NOTARY_PROFILE names a notarytool keychain profile, stored once with:
# xcrun notarytool store-credentials <profile> --apple-id <apple-id> \
# --team-id <TEAMID> --password <app-specific-password>
#
# Apple can only staple a ticket to a .app/.dmg/.pkg, never to a bare
# executable, so the binaries ship unstapled and Gatekeeper resolves the
# ticket online on first run. Both variables are optional: with neither set,
# `make release` ships unsigned binaries exactly as it did before.
SIGN_IDENTITY ?=
NOTARY_PROFILE ?=
DARWIN_BINARIES := $(RELEASE_DIR)/$(BINARY)-darwin-amd64 $(RELEASE_DIR)/$(BINARY)-darwin-arm64
codesign-darwin:
test -n "$(SIGN_IDENTITY)" || { echo "codesign-darwin: SIGN_IDENTITY is not set"; exit 1; }
for f in $(DARWIN_BINARIES); do \
echo "Signing $$f..."; \
codesign --force --options runtime --timestamp \
--sign "$(SIGN_IDENTITY)" "$$f" || exit 1; \
codesign --verify --strict "$$f" || exit 1; \
done
notarize-darwin:
test -n "$(NOTARY_PROFILE)" || { echo "notarize-darwin: NOTARY_PROFILE is not set"; exit 1; }
rm -rf $(RELEASE_DIR)/notarize $(RELEASE_DIR)/notarize.zip
mkdir -p $(RELEASE_DIR)/notarize
cp $(DARWIN_BINARIES) $(RELEASE_DIR)/notarize/
ditto -c -k $(RELEASE_DIR)/notarize $(RELEASE_DIR)/notarize.zip
xcrun notarytool submit $(RELEASE_DIR)/notarize.zip \
--keychain-profile "$(NOTARY_PROFILE)" --wait
rm -rf $(RELEASE_DIR)/notarize $(RELEASE_DIR)/notarize.zip
release: ensure-dirs
rm -rf $(RELEASE_DIR)
mkdir -p $(RELEASE_DIR)
$(foreach platform,$(PLATFORMS),\
$(eval GOOS := $(word 1,$(subst /, ,$(platform))))\
$(eval GOARCH := $(word 2,$(subst /, ,$(platform))))\
echo "Building $(GOOS)/$(GOARCH)..." && \
$(GO_ENV) GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=0 \
go build $(LDFLAGS) -o $(RELEASE_DIR)/$(BINARY)-$(GOOS)-$(GOARCH) . && \
) true
chmod +x $(RELEASE_DIR)/$(BINARY)-*
$(if $(SIGN_IDENTITY),$(MAKE) codesign-darwin SIGN_IDENTITY="$(SIGN_IDENTITY)",true)
$(if $(NOTARY_PROFILE),$(MAKE) notarize-darwin NOTARY_PROFILE="$(NOTARY_PROFILE)",true)
cd $(RELEASE_DIR) && for f in $(BINARY)-*; do \
stage_dir="$$(mktemp -d ./release.XXXXXX)"; \
cp "$$f" "$$stage_dir/$(BINARY)"; \
cp $(addprefix ../,$(RELEASE_SUPPORT_FILES)) "$$stage_dir/"; \
chmod +x "$$stage_dir/$(BINARY)" "$$stage_dir/main.sh" "$$stage_dir/main.tmux"; \
COPYFILE_DISABLE=1 tar --no-xattrs --no-mac-metadata -czf "$$f.tar.gz" -C "$$stage_dir" .; \
rm -rf "$$stage_dir" "$$f"; \
done
cd $(RELEASE_DIR) && shasum -a 256 *.tar.gz > checksums.txt
gh release create v$(VERSION) $(RELEASE_DIR)/* \
--title "v$(VERSION)" \
$(if $(RELEASE_NOTES),--notes-file $(RELEASE_NOTES),--generate-notes)