Skip to content

Commit 0739892

Browse files
committed
chore(quality): automated quality improvement pass — security fixes, test coverage +~170 tests, quality scorecard
Security: - system: replace curl|bash with download→SHA256→verify→exec for Homebrew installer (mirrors OMZ pattern) - config/validate: add regex validation for macOS defaults domain/key (reject whitespace/metacharacters) - dotfiles: add regex guard on git branch names to prevent refspec injection - shell/state: tighten .zshrc and state.json write permissions 0644→0600 - macos: move dry-run output from os.Stderr to stdout - updater: replace sh -c dynamic string in execBrewUpgrade with sequential exec.Command calls - brew: route Install/InstallCask through brewInstallCmd to inherit HOMEBREW_NO_AUTO_UPDATE=1 Tests (+~170 new tests, all green): - internal/system: 39% → 66% (+27pp) - internal/macos: 51% → 84% (+33pp) - internal/npm: 55% → 93% (+38pp) - internal/shell: 55% → 74% (+19pp) - internal/brew: 65% → 74% (+9pp) - internal/sync: 28% → 55% (+27pp) - internal/cli: 19% → 35% (+16pp) - internal/installer: 40% → 44% (+4pp) Quality toolchain: - Add quality/scorecard.yaml with weighted scoring dimensions - Add scripts/quality-score.sh (deterministic score from golangci-lint + gosec + gocyclo + coverage) - Add make quality / quality-lint / quality-security / quality-diff targets - Update .golangci.yml with gosec, gocyclo (threshold 15), staticcheck, ineffassign - Baseline score: 5.4/10 → 6.8/10
1 parent 527ebe9 commit 0739892

27 files changed

Lines changed: 3741 additions & 25 deletions

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,9 @@ vendor/
4949
coverage.out
5050
coverage.html
5151
*.coverprofile
52+
53+
# Quality scorecard — ignore generated coverage artifact, track the rest
54+
quality/coverage.out
55+
# quality/score.json — tracked (committed score snapshots)
56+
# quality/scorecard.yaml — tracked (config)
57+
# quality/findings.md — tracked (human-readable report)

.golangci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
version: "2"
22

3+
run:
4+
timeout: 5m
5+
skip-dirs:
6+
- vendor
7+
- testutil
8+
39
formatters:
410
enable:
511
- gofmt
612
- goimports
13+
settings:
14+
goimports:
15+
local-prefixes:
16+
- github.com/openbootdotdev/openboot
717

818
linters:
919
default: none
1020
enable:
1121
- errcheck
1222
- govet
1323
- staticcheck
24+
- gosimple
25+
- ineffassign
1426
- unused
27+
- gocyclo
28+
- gosec
1529
- misspell
1630
- unconvert
1731
- exhaustive
@@ -25,8 +39,19 @@ linters:
2539
- (*encoding/json.Encoder).Encode
2640
- os.WriteFile
2741
- (*os.File).Close
42+
gocyclo:
43+
min-complexity: 15
44+
gosec:
45+
excludes:
46+
- G304 # File path provided as taint input — acceptable for CLI tools
2847
exclusions:
2948
rules:
3049
- path: "_test\\.go"
3150
linters:
3251
- errcheck
52+
- gosec
53+
- path: "testutil/"
54+
linters:
55+
- gosec
56+
- errcheck
57+
- unused

Makefile

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.PHONY: test-unit test-integration test-e2e test-destructive test-smoke test-smoke-prebuilt test-coverage test-all \
22
test-vm test-vm-short test-vm-run test-vm-quick test-vm-release test-vm-full \
3-
install-hooks uninstall-hooks
3+
install-hooks uninstall-hooks \
4+
quality quality-lint quality-security quality-diff
45

56
BINARY_NAME=openboot
67
BINARY_PATH=./$(BINARY_NAME)
@@ -113,3 +114,25 @@ uninstall-hooks:
113114
rm -f .git/hooks/$$hook; \
114115
echo "✓ removed .git/hooks/$$hook"; \
115116
done
117+
118+
# =============================================================================
119+
# Quality scorecard
120+
# =============================================================================
121+
122+
quality: ## Run full quality scorecard
123+
@bash scripts/quality-score.sh
124+
125+
quality-lint: ## Run golangci-lint only
126+
golangci-lint run ./...
127+
128+
quality-security: ## Run gosec only
129+
gosec ./...
130+
131+
quality-diff: ## Show score change vs last run then re-run scorecard
132+
@if [ -f quality/score.json ]; then \
133+
echo "Last recorded score:"; \
134+
python3 -c "import json,sys; d=json.load(open('quality/score.json')); print(' total_score:', d['total_score'], ' (', d['timestamp'], ' sha:', d['git_sha'], ')')" 2>/dev/null || \
135+
grep -E '"total_score"|"timestamp"|"git_sha"' quality/score.json | sed 's/^/ /'; \
136+
echo; \
137+
fi
138+
@bash scripts/quality-score.sh

internal/brew/brew.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func Install(packages []string, dryRun bool) error {
137137
ui.Info(fmt.Sprintf("Installing %d CLI packages...", len(packages)))
138138

139139
args := append([]string{"install"}, packages...)
140-
cmd := exec.Command("brew", args...)
140+
cmd := brewInstallCmd(args...)
141141
cmd.Stdout = os.Stdout
142142
cmd.Stderr = os.Stderr
143143
return cmd.Run()
@@ -182,7 +182,7 @@ func InstallCask(packages []string, dryRun bool) error {
182182
ui.Info(fmt.Sprintf("Installing %d GUI applications...", len(packages)))
183183

184184
args := append([]string{"install", "--cask"}, packages...)
185-
cmd := exec.Command("brew", args...)
185+
cmd := brewInstallCmd(args...)
186186
cmd.Stdout = os.Stdout
187187
cmd.Stderr = os.Stderr
188188
return cmd.Run()

0 commit comments

Comments
 (0)