Compare commits

...

2 Commits

Author SHA1 Message Date
tommaso f70ea7f0f5 remove hard-coded layout names 2026-07-14 00:36:43 +02:00
tommaso 4a74cf04c8 block running make as sudo 2026-07-14 00:35:49 +02:00
3 changed files with 55 additions and 16 deletions
+36 -11
View File
@@ -1,46 +1,68 @@
# Makefile for phbar # Makefile for phbar
# #
# Usage: make <target> # Usage: make <target>
#
# NOTE: Never invoke this Makefile with `sudo` (e.g. `sudo make install`).
# Running `swift build` as root corrupts `.build/` with root-owned files that
# break subsequent non-root builds (you get "invalid access to …/DerivedSources").
# The `install`/`uninstall` targets elevate *only* the file copy, and only when
# the destination is not user-writable, so `sudo` is never needed from the user.
BIN_DIR := /usr/local/bin # Install directory. Override with: make install BIN_DIR=/opt/homebrew/bin
BIN_DIR ?= /usr/local/bin
BUILD_DIR := .build/release BUILD_DIR := .build/release
BINARIES := phbar BINARIES := phbar
.PHONY: all build install clean test run # Guard: any target that runs Swift must not run under sudo, otherwise it would
# sprinkle root-owned files across .build/. It fails fast with a helpful message
# instead of corrupting the build directory. Recursively-expanded (`=`) so that
# the `$@` automatic variable resolves per-target at recipe time.
guard_not_root = @if [ "$$(id -u)" = "0" ] && [ -n "$$SUDO_USER" ]; then \
echo "❌ 'make $@' must not run under sudo (it would corrupt .build/)." >&2; \
echo " Run 'make install' without sudo; it elevates only the copy step." >&2; \
exit 1; \
fi
.PHONY: all build install clean test run uninstall reinstall help
all: build all: build
# Build all targets in release mode # Build all targets in release mode
build: build:
$(guard_not_root)
swift build -c release swift build -c release
# Build and install binaries to /usr/local/bin # Build and install binaries. Elevates only the copy when BIN_DIR isn't writable.
install: build install: build
@mkdir -p $(BIN_DIR) @mkdir -p $(BIN_DIR)
@for bin in $(BINARIES); do \ @if [ -w "$(BIN_DIR)" ]; then CP="cp -f"; else CP="sudo cp -f"; fi; \
cp -f $(BUILD_DIR)/$$bin $(BIN_DIR)/; \ for bin in $(BINARIES); do \
$$CP $(BUILD_DIR)/$$bin $(BIN_DIR)/; \
done done
@echo "✅ Installed $(BINARIES) to $(BIN_DIR)" @echo "✅ Installed $(BINARIES) to $(BIN_DIR)"
# Clean build artifacts # Clean build artifacts
clean: clean:
$(guard_not_root)
swift package clean swift package clean
# Run tests # Run tests
test: test:
$(guard_not_root)
swift test swift test
# Quick test: build, install, and verify # Quick test: build, install, and verify
run: install run: install
@echo "Verifying installation..." @echo "Verifying installation..."
@for bin in $(BINARIES); do \ @for bin in $(BINARIES); do \
which $$bin > /dev/null && echo "$$bin: $(shell which $$bin)" || echo "$$bin: not found"; \ which $$bin > /dev/null && echo "$$bin: $$($$bin --version 2>/dev/null | head -1)" || echo "$$bin: not found"; \
done done
# Uninstall binaries from /usr/local/bin # Uninstall binaries. Elevates only the remove when BIN_DIR isn't writable.
uninstall: uninstall:
@for bin in $(BINARIES); do \ @if [ -w "$(BIN_DIR)" ]; then RM="rm -f"; else RM="sudo rm -f"; fi; \
rm -f $(BIN_DIR)/$$bin; \ for bin in $(BINARIES); do \
$$RM $(BIN_DIR)/$$bin; \
done done
@echo "✅ Uninstalled $(BINARIES) from $(BIN_DIR)" @echo "✅ Uninstalled $(BINARIES) from $(BIN_DIR)"
@@ -51,9 +73,12 @@ reinstall: clean install
help: help:
@echo "Available targets:" @echo "Available targets:"
@echo " make build - Build in release mode" @echo " make build - Build in release mode"
@echo " make install - Build and install to /usr/local/bin" @echo " make install - Build and install to $(BIN_DIR)"
@echo " make clean - Clean build artifacts" @echo " make clean - Clean build artifacts"
@echo " make test - Run tests" @echo " make test - Run tests"
@echo " make run - Build, install, and verify" @echo " make run - Build, install, and verify"
@echo " make uninstall - Remove binaries from /usr/local/bin" @echo " make uninstall - Remove binaries from $(BIN_DIR)"
@echo " make reinstall - Clean and reinstall" @echo " make reinstall - Clean and reinstall"
@echo ""
@echo "Override the install location with BIN_DIR, e.g.:"
@echo " make install BIN_DIR=$(HOME)/.local/bin"
+14
View File
@@ -8,4 +8,18 @@ struct PHConfig: Decodable {
case theme, window, layout case theme, window, layout
case monitors = "monitor" case monitors = "monitor"
} }
var layouts: Set<String> {
var layouts = Set<String>()
layouts.insert(layout)
guard let monitors else { return layouts }
for monitor in monitors.values {
if let layout = monitor.layout {
layouts.insert(layout)
}
}
return layouts
}
} }
@@ -4,7 +4,7 @@ import TOML
extension PHLayout { extension PHLayout {
/// Load the specified layouts from the resolved config directory (see `PHPaths`). /// Load the specified layouts from the resolved config directory (see `PHPaths`).
/// If any of theme doesn't exist or fails to parse, the execution is interrupted. /// If any of theme doesn't exist or fails to parse, the execution is interrupted.
static func load(_ layouts: [String]) throws -> [String: PHLayout] { static func load(_ layouts: Set<String>) throws -> [String: PHLayout] {
var dictionary = [String: PHLayout]() var dictionary = [String: PHLayout]()
for layout in layouts { for layout in layouts {
@@ -29,8 +29,8 @@ extension PHLayout {
Make sure to have a file named `\(layout)` inside the Make sure to have a file named `\(layout)` inside the
directory: `\(PHPaths.layoutsDirectory.relativePath)` directory: `\(PHPaths.layoutsDirectory.relativePath)`
Tip: If you've never used phbar before, run the `phbar install` command Tip: If you've never used phbar before, run `phbar generate config`
to automatically generate all the required configuration files. to automatically generate the required configuration files.
""" """
) )
} }