Scaffold ipswap: tray-driven Windows IP preset switcher
Implements the design in claude.md as a building skeleton: pure Go, no cgo, cross-compiles to a single Windows .exe from Linux. Architecture follows the spec's deliberate split. The fast path is native — tray icon, grouped submenus, a Win32 MessageBox showing a live before/after diff, then netsh. The slow path is an embedded web editor served on a random loopback port and opened in the default browser. Two decisions worth recording: Reads use GetAdaptersAddresses, writes use netsh. The spec left the enumeration mechanism open; parsing `netsh show config` breaks on a non-English Windows because the output is localised. DNS static-vs-DHCP origin is not exposed by that API, so it comes from one registry read. The netsh command plan is built in portable code. That puts the delete-every- existing-address step — the one that stops secondary addresses leaking across switches — under test without needing a Windows box. The editor requires the session token in a header for mutations, not just the cookie: any page in the browser can make it POST to 127.0.0.1 with the cookie attached, but it cannot set a header. The updater refuses to install a release that publishes no SHA256. Not yet done: no group picker for export (the API supports it), no single-instance guard, and internal/server/web/app.css is reconstructed from the description in claude.md rather than the canonical apointless.css. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
VERSION ?= 0.1.0
|
||||
|
||||
# -H windowsgui suppresses the console window that would otherwise sit behind
|
||||
# the tray icon. -s -w strips the symbol table and DWARF; nothing here needs a
|
||||
# Go stack trace off a customer's laptop, and it roughly halves the binary.
|
||||
LDFLAGS := -s -w -H windowsgui -X main.version=$(VERSION)
|
||||
|
||||
# Go is installed at ~/.local/go on this box and deliberately kept off PATH, so
|
||||
# prefer that toolchain and fall back to whatever `go` is in PATH elsewhere.
|
||||
GO ?= $(shell test -x $(HOME)/.local/go/bin/go && echo $(HOME)/.local/go/bin/go || echo go)
|
||||
|
||||
# Pinned and run through `go run` so CI needs no separate install step.
|
||||
GOVERSIONINFO ?= $(GO) run github.com/josephspurrier/goversioninfo/cmd/goversioninfo@v1.4.1
|
||||
|
||||
SYSO := cmd/ipswap/resource_windows.syso
|
||||
|
||||
.PHONY: build syso test vet check dist sums clean help
|
||||
|
||||
help: ## List targets
|
||||
@grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | awk 'BEGIN{FS=":.*?## "}{printf " %-14s %s\n", $$1, $$2}'
|
||||
|
||||
# ipswap is pure Go with no cgo anywhere, which is the whole reason the tray is
|
||||
# fyne.io/systray and the dialogs are raw user32 rather than a GUI toolkit:
|
||||
# `GOOS=windows go build` cross-compiles straight from Linux, no Wine, no
|
||||
# mingw, no fyne-cross.
|
||||
build: syso ## Cross-compile bin/ipswap.exe from any host
|
||||
@mkdir -p bin
|
||||
GOOS=windows GOARCH=amd64 $(GO) build -trimpath -ldflags "$(LDFLAGS)" -o bin/ipswap.exe ./cmd/ipswap
|
||||
|
||||
# The .syso carries the icon, the version resource and — the part that matters
|
||||
# — the manifest that asks for asInvoker and per-monitor DPI. A plain `go
|
||||
# build` with no .syso produces a binary with the generic executable icon and
|
||||
# the default (unaware, asInvoker-by-omission) manifest.
|
||||
#
|
||||
# -64 is not optional: goversioninfo emits a 386 object by default, and linking
|
||||
# that into an amd64 build fails with "unknown relocation type 7".
|
||||
syso: ## Generate the Windows resource object
|
||||
cd cmd/ipswap && $(GOVERSIONINFO) \
|
||||
-64 \
|
||||
-o resource_windows.syso \
|
||||
-platform-specific=false \
|
||||
versioninfo.json
|
||||
|
||||
test: ## Run tests
|
||||
$(GO) test ./...
|
||||
|
||||
vet: ## Run go vet for both targets
|
||||
$(GO) vet ./...
|
||||
GOOS=windows GOARCH=amd64 $(GO) vet ./...
|
||||
|
||||
# The Windows-only files (netsh, user32, the registry) are the bulk of the
|
||||
# risk, and a Linux `go build` never looks at them. This is the cheap way to
|
||||
# keep them compiling.
|
||||
check: test vet ## Typecheck both targets and run tests
|
||||
GOOS=windows GOARCH=amd64 $(GO) build ./...
|
||||
|
||||
dist: build sums ## Build the release artifacts into dist/
|
||||
@echo "dist/ contains:" && ls -1 dist
|
||||
|
||||
sums: ## Write dist/SHA256SUMS for the built binary
|
||||
@mkdir -p dist
|
||||
@cp bin/ipswap.exe dist/ipswap.exe
|
||||
cd dist && sha256sum ipswap.exe > SHA256SUMS
|
||||
@cat dist/SHA256SUMS
|
||||
|
||||
clean: ## Remove build artifacts
|
||||
rm -rf bin dist $(SYSO)
|
||||
Reference in New Issue
Block a user