Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions internal/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TokenPath() (string, error) {
func LoadToken() (*StoredAuth, error) {
path, err := TokenPath()
if err != nil {
return nil, err
return nil, fmt.Errorf("load token: %w", err)
}
data, err := os.ReadFile(path)
if err != nil {
Expand All @@ -51,7 +51,7 @@ func LoadToken() (*StoredAuth, error) {
func SaveToken(auth *StoredAuth) error {
path, err := TokenPath()
if err != nil {
return err
return fmt.Errorf("save token: %w", err)
}

dir := filepath.Dir(path)
Expand All @@ -74,7 +74,7 @@ func SaveToken(auth *StoredAuth) error {
func DeleteToken() error {
path, err := TokenPath()
if err != nil {
return err
return fmt.Errorf("delete token: %w", err)
}
err = os.Remove(path)
if err != nil && !os.IsNotExist(err) {
Expand Down
8 changes: 8 additions & 0 deletions internal/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ func TestDeleteToken_FileNotExist(t *testing.T) {
}

func TestDeleteToken_PermissionError(t *testing.T) {
if os.Geteuid() == 0 {
t.Skip("root bypasses filesystem permission checks")
}

tmpDir := t.TempDir()
authDir := filepath.Join(tmpDir, ".openboot")
authFile := filepath.Join(authDir, "auth.json")
Expand Down Expand Up @@ -378,6 +382,10 @@ func TestStoredAuth_JSONMarshaling(t *testing.T) {
}

func TestLoadToken_ReadPermissionError(t *testing.T) {
if os.Geteuid() == 0 {
t.Skip("root bypasses filesystem permission checks")
}

tmpDir := t.TempDir()
authDir := filepath.Join(tmpDir, ".openboot")
authFile := filepath.Join(authDir, "auth.json")
Expand Down
3 changes: 3 additions & 0 deletions internal/auth/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ func TestLoginInteractive_InvalidExpirationFormat(t *testing.T) {
}

func TestLoginInteractive_SaveTokenError(t *testing.T) {
if os.Geteuid() == 0 {
t.Skip("root bypasses filesystem permission checks")
}
withFastPoll(t)
withNoBrowser(t)
tmpDir := t.TempDir()
Expand Down
3 changes: 3 additions & 0 deletions internal/cli/login_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ func TestLogoutCmd_WhenNotAuthenticated(t *testing.T) {
}

func TestLogoutCmd_DeleteError(t *testing.T) {
if os.Geteuid() == 0 {
t.Skip("root bypasses filesystem permission checks")
}
tmpDir := setupTestAuth(t, true)
authDir := filepath.Join(tmpDir, ".openboot")

Expand Down
21 changes: 12 additions & 9 deletions internal/dotfiles/dotfiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,18 @@ func Clone(repoURL string, dryRun bool) error {

home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("clone dotfiles: %w", err)
}
dotfilesPath := filepath.Join(home, defaultDotfilesDir)

if _, err := os.Stat(dotfilesPath); err == nil {
// Dotfiles directory already exists — sync or re-clone as appropriate.
needsClone, err := handleExistingDotfiles(dotfilesPath, repoURL, dryRun)
if err != nil || !needsClone {
return err
if err != nil {
return fmt.Errorf("handle existing dotfiles: %w", err)
}
if !needsClone {
return nil
}
}

Expand Down Expand Up @@ -210,7 +213,7 @@ func confirmResetIfDirty(dotfilesPath, branch string) bool {
func Link(dryRun bool) error {
home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("link dotfiles: %w", err)
}
dotfilesPath := filepath.Join(home, defaultDotfilesDir)

Expand Down Expand Up @@ -332,17 +335,17 @@ func backupConflicts(pkgDir, targetDir string) ([][2]string, error) {

func linkWithStow(dotfilesPath string, dryRun bool) error {
if err := ensureStow(dryRun); err != nil {
return err
return fmt.Errorf("ensure stow: %w", err)
}

entries, err := os.ReadDir(dotfilesPath)
if err != nil {
return err
return fmt.Errorf("read dotfiles dir: %w", err)
}

home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("link with stow: %w", err)
}

var errs []error
Expand Down Expand Up @@ -399,12 +402,12 @@ func linkWithStow(dotfilesPath string, dryRun bool) error {
func linkDirect(dotfilesPath string, dryRun bool) error {
home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("link direct: %w", err)
}

entries, err := os.ReadDir(dotfilesPath)
if err != nil {
return err
return fmt.Errorf("read dotfiles dir: %w", err)
}

for _, entry := range entries {
Expand Down
2 changes: 1 addition & 1 deletion internal/npm/npm.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func Install(packages []string, dryRun bool) error {

failed, err := installBatch(toInstall)
if err != nil {
return err
return fmt.Errorf("install npm packages: %w", err)
}

if len(failed) > 0 {
Expand Down
13 changes: 8 additions & 5 deletions internal/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func EnsureBrewShellenv(dryRun bool) error {

home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("ensure brew shellenv: %w", err)
}
zshrcPath := filepath.Join(home, ".zshrc")

Expand All @@ -129,7 +129,10 @@ func EnsureBrewShellenv(dryRun bool) error {
fmt.Printf("[DRY-RUN] Would create %s with Homebrew shellenv\n", zshrcPath)
return nil
}
return os.WriteFile(zshrcPath, []byte(brewShellenvLine+"\n"), 0600)
if err := os.WriteFile(zshrcPath, []byte(brewShellenvLine+"\n"), 0600); err != nil {
return fmt.Errorf("create .zshrc: %w", err)
}
return nil
}

raw, err := os.ReadFile(zshrcPath)
Expand Down Expand Up @@ -262,7 +265,7 @@ func RestoreFromSnapshot(ohMyZsh bool, theme string, plugins []string, dryRun bo

home, err := system.HomeDir()
if err != nil {
return err
return fmt.Errorf("configure zshrc: %w", err)
}
zshrcPath := filepath.Join(home, ".zshrc")

Expand All @@ -272,11 +275,11 @@ func RestoreFromSnapshot(ohMyZsh bool, theme string, plugins []string, dryRun bo
return nil
}
if err := validateShellIdentifier(theme, "ZSH_THEME"); err != nil {
return err
return fmt.Errorf("validate theme: %w", err)
}
for _, p := range plugins {
if err := validateShellIdentifier(p, "plugin"); err != nil {
return err
return fmt.Errorf("validate plugin: %w", err)
}
}
template := fmt.Sprintf(`export ZSH="$HOME/.oh-my-zsh"
Expand Down
3 changes: 3 additions & 0 deletions internal/state/reminder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ func TestRoundTrip_DefaultState(t *testing.T) {
}

func TestLoadState_ReadError(t *testing.T) {
if os.Geteuid() == 0 {
t.Skip("root bypasses filesystem permission checks")
}
tmpDir := t.TempDir()
statePath := filepath.Join(tmpDir, "state.json")

Expand Down
3 changes: 1 addition & 2 deletions internal/system/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ func RunCommandOutput(name string, args ...string) (string, error) {
// curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | sha256sum
const knownBrewInstallHash = "dfd5145fe2aa5956a600e35848765273f5798ce6def01bd08ecec088a1268d91"

// brewInstallURL is a var so tests can redirect it without a real server.
var brewInstallURL = "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh"
const brewInstallURL = "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh"

// brewHTTPClient is a var so tests can inject a mock transport.
var brewHTTPClient *http.Client = http.DefaultClient
Expand Down
Loading