Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer $HOME on all platforms #3000

Merged
merged 2 commits into from
Sep 17, 2024
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 clicommand/agent_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import (
"github.com/buildkite/agent/v3/internal/experiments"
"github.com/buildkite/agent/v3/internal/job/hook"
"github.com/buildkite/agent/v3/internal/job/shell"
"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
"github.com/buildkite/agent/v3/logger"
"github.com/buildkite/agent/v3/metrics"
"github.com/buildkite/agent/v3/process"
Expand Down Expand Up @@ -1133,7 +1133,7 @@ var AgentStartCommand = cli.Command{

// confirm the BuildPath is exists. The bootstrap is going to write to it when a job executes,
// so we may as well check that'll work now and fail early if it's a problem
if !utils.FileExists(agentConf.BuildPath) {
if !osutil.FileExists(agentConf.BuildPath) {
l.Info("Build Path doesn't exist, creating it (%s)", agentConf.BuildPath)
// Actual file permissions will be reduced by umask, and won't be 0777 unless the user has manually changed the umask to 000
if err := os.MkdirAll(agentConf.BuildPath, 0o777); err != nil {
Expand Down Expand Up @@ -1383,7 +1383,7 @@ func agentLifecycleHook(hookName string, log logger.Logger, cfg AgentStartConfig
}

func defaultSocketsPath() string {
home, err := os.UserHomeDir()
home, err := osutil.UserHomeDir()
if err != nil {
return filepath.Join(os.TempDir(), "buildkite-sockets")
}
Expand Down
4 changes: 2 additions & 2 deletions cliconfig/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"os"
"strings"

"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
)

type File struct {
Expand Down Expand Up @@ -60,7 +60,7 @@ func (f *File) Load() error {
}

func (f File) AbsolutePath() (string, error) {
return utils.NormalizeFilePath(f.Path)
return osutil.NormalizeFilePath(f.Path)
}

func (f File) Exists() bool {
Expand Down
6 changes: 3 additions & 3 deletions cliconfig/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"strings"
"time"

"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
"github.com/buildkite/agent/v3/logger"
"github.com/oleiade/reflections"
"github.com/urfave/cli"
Expand Down Expand Up @@ -372,7 +372,7 @@ func (l Loader) normalizeField(fieldName string, normalization string) error {

// Normalize the field to be a filepath
if valueAsString, ok := value.(string); ok {
normalizedPath, err := utils.NormalizeFilePath(valueAsString)
normalizedPath, err := osutil.NormalizeFilePath(valueAsString)
if err != nil {
return err
}
Expand All @@ -392,7 +392,7 @@ func (l Loader) normalizeField(fieldName string, normalization string) error {

// Normalize the field to be a command
if valueAsString, ok := value.(string); ok {
normalizedCommandPath, err := utils.NormalizeCommand(valueAsString)
normalizedCommandPath, err := osutil.NormalizeCommand(valueAsString)
if err != nil {
return err
}
Expand Down
16 changes: 8 additions & 8 deletions internal/job/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

"github.com/buildkite/agent/v3/internal/experiments"
"github.com/buildkite/agent/v3/internal/job/shell"
"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
"github.com/buildkite/agent/v3/tracetools"
"github.com/buildkite/roko"
)
Expand Down Expand Up @@ -80,7 +80,7 @@ func (e *Executor) removeCheckoutDir() error {
func (e *Executor) createCheckoutDir() error {
checkoutPath, _ := e.shell.Env.Get("BUILDKITE_BUILD_CHECKOUT_PATH")

if !utils.FileExists(checkoutPath) {
if !osutil.FileExists(checkoutPath) {
e.shell.Commentf("Creating \"%s\"", checkoutPath)
// Actual file permissions will be reduced by umask, and won't be 0777 unless the user has manually changed the umask to 000
if err := os.MkdirAll(checkoutPath, 0777); err != nil {
Expand Down Expand Up @@ -258,7 +258,7 @@ func (e *Executor) CheckoutPhase(ctx context.Context) error {
}

func hasGitSubmodules(sh *shell.Shell) bool {
return utils.FileExists(filepath.Join(sh.Getwd(), ".gitmodules"))
return osutil.FileExists(filepath.Join(sh.Getwd(), ".gitmodules"))
}

func hasGitCommit(ctx context.Context, sh *shell.Shell, gitDir string, commit string) bool {
Expand All @@ -283,7 +283,7 @@ func (e *Executor) updateGitMirror(ctx context.Context, repository string) (stri
isMainRepository := repository == e.Repository

// Create the mirrors path if it doesn't exist
if baseDir := filepath.Dir(mirrorDir); !utils.FileExists(baseDir) {
if baseDir := filepath.Dir(mirrorDir); !osutil.FileExists(baseDir) {
e.shell.Commentf("Creating \"%s\"", baseDir)
// Actual file permissions will be reduced by umask, and won't be 0777 unless the user has manually changed the umask to 000
if err := os.MkdirAll(baseDir, 0777); err != nil {
Expand All @@ -309,7 +309,7 @@ func (e *Executor) updateGitMirror(ctx context.Context, repository string) (stri
defer mirrorCloneLock.Unlock()

// If we don't have a mirror, we need to clone it
if !utils.FileExists(mirrorDir) {
if !osutil.FileExists(mirrorDir) {
e.shell.Commentf("Cloning a mirror of the repository to %q", mirrorDir)
flags := "--mirror " + e.GitCloneMirrorFlags
if err := gitClone(ctx, e.shell, flags, repository, mirrorDir); err != nil {
Expand Down Expand Up @@ -455,7 +455,7 @@ func (e *Executor) getOrUpdateMirrorDir(ctx context.Context, repository string)
e.shell.Commentf("Skipping update and using existing mirror for repository %s at %s.", repository, mirrorDir)

// Check if specified mirrorDir exists, otherwise the clone will fail.
if !utils.FileExists(mirrorDir) {
if !osutil.FileExists(mirrorDir) {
// Fall back to a clean clone, rather than failing the clone and therefore the build
e.shell.Commentf("No existing mirror found for repository %s at %s.", repository, mirrorDir)
mirrorDir = ""
Expand Down Expand Up @@ -507,7 +507,7 @@ func (e *Executor) defaultCheckoutPhase(ctx context.Context) error {

// Does the git directory exist?
existingGitDir := filepath.Join(e.shell.Getwd(), ".git")
if utils.FileExists(existingGitDir) {
if osutil.FileExists(existingGitDir) {
// Update the origin of the repository so we can gracefully handle
// repository renames
if _, err := e.updateRemoteURL(ctx, "", e.Repository); err != nil {
Expand Down Expand Up @@ -647,7 +647,7 @@ func (e *Executor) defaultCheckoutPhase(ctx context.Context) error {

// Tests use a local temp path for the repository, real repositories don't. Handle both.
var repositoryPath string
if !utils.FileExists(repository) {
if !osutil.FileExists(repository) {
repositoryPath = filepath.Join(e.ExecutorConfig.GitMirrorsPath, dirForRepository(repository))
} else {
repositoryPath = repository
Expand Down
12 changes: 6 additions & 6 deletions internal/job/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ import (
"github.com/buildkite/agent/v3/internal/file"
"github.com/buildkite/agent/v3/internal/job/hook"
"github.com/buildkite/agent/v3/internal/job/shell"
"github.com/buildkite/agent/v3/internal/osutil"
"github.com/buildkite/agent/v3/internal/redact"
"github.com/buildkite/agent/v3/internal/replacer"
"github.com/buildkite/agent/v3/internal/shellscript"
"github.com/buildkite/agent/v3/internal/tempfile"
"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/kubernetes"
"github.com/buildkite/agent/v3/process"
"github.com/buildkite/agent/v3/tracetools"
Expand Down Expand Up @@ -338,7 +338,7 @@ func (e *Executor) executeHook(ctx context.Context, hookCfg HookConfig) error {
}
hookName += " " + hookCfg.Name

if !utils.FileExists(hookCfg.Path) {
if !osutil.FileExists(hookCfg.Path) {
if e.Debug {
e.shell.Commentf("Skipping %s hook, no script at \"%s\"", hookName, hookCfg.Path)
}
Expand Down Expand Up @@ -420,7 +420,7 @@ func logOpenedHookInfo(l shell.Logger, debug bool, hookName, path string) {
} else {
l.Errorf("The %s hook failed to run the %s process has the hook file open", hookName, procPath)
}
case utils.FileExists("/dev/fd"):
case osutil.FileExists("/dev/fd"):
isOpened, err := file.IsOpened(l, debug, path)
if err == nil {
if isOpened {
Expand Down Expand Up @@ -715,7 +715,7 @@ func dirForRepository(repository string) string {

// Given a repository, it will add the host to the set of SSH known_hosts on the machine
func addRepositoryHostToSSHKnownHosts(ctx context.Context, sh *shell.Shell, repository string) {
if utils.FileExists(repository) {
if osutil.FileExists(repository) {
return
}

Expand Down Expand Up @@ -965,7 +965,7 @@ func (e *Executor) defaultCommandPhase(ctx context.Context) error {

scriptFileName := strings.Replace(e.Command, "\n", "", -1)
pathToCommand, err := filepath.Abs(filepath.Join(e.shell.Getwd(), scriptFileName))
commandIsScript := err == nil && utils.FileExists(pathToCommand)
commandIsScript := err == nil && osutil.FileExists(pathToCommand)
span.AddAttributes(map[string]string{"hook.command": pathToCommand})

// If the command isn't a script, then it's something we need
Expand Down Expand Up @@ -1039,7 +1039,7 @@ func (e *Executor) defaultCommandPhase(ctx context.Context) error {
// shouldn't be vulnerable to this!
if e.ExecutorConfig.CommandEval {
// Make script executable
if err = utils.ChmodExecutable(pathToCommand); err != nil {
if err = osutil.ChmodExecutable(pathToCommand); err != nil {
e.shell.Warningf("Error marking script %q as executable: %v", pathToCommand, err)
return err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/job/hook/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"runtime"

"github.com/buildkite/agent/v3/internal/job/shell"
"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
)

// Find returns the absolute path to the best matching hook file in a path, or
Expand All @@ -23,7 +23,7 @@ func Find(hookDir string, name string) (string, error) {
}
}
// otherwise chech for th default shell script
if p := filepath.Join(hookDir, name); utils.FileExists(p) {
if p := filepath.Join(hookDir, name); osutil.FileExists(p) {
return p, nil
}
// Don't wrap os.ErrNotExist without checking callers handle it.
Expand Down
3 changes: 2 additions & 1 deletion internal/job/knownhosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"time"

"github.com/buildkite/agent/v3/internal/job/shell"
"github.com/buildkite/agent/v3/internal/osutil"
"golang.org/x/crypto/ssh/knownhosts"
)

Expand All @@ -19,7 +20,7 @@ type knownHosts struct {
}

func findKnownHosts(sh *shell.Shell) (*knownHosts, error) {
userHomePath, err := os.UserHomeDir()
userHomePath, err := osutil.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("Could not find the current users home directory (%s)", err)
}
Expand Down
8 changes: 4 additions & 4 deletions internal/job/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

"github.com/buildkite/agent/v3/agent/plugin"
"github.com/buildkite/agent/v3/internal/job/hook"
"github.com/buildkite/agent/v3/internal/utils"
"github.com/buildkite/agent/v3/internal/osutil"
"github.com/buildkite/roko"
)

Expand Down Expand Up @@ -162,7 +162,7 @@ func (e *Executor) VendoredPluginPhase(ctx context.Context) error {
return fmt.Errorf("Failed to resolve vendored plugin path for plugin %s: %w", p.Name(), err)
}

if !utils.FileExists(pluginLocation) {
if !osutil.FileExists(pluginLocation) {
return fmt.Errorf("Vendored plugin path %s doesn't exist", p.Location)
}

Expand Down Expand Up @@ -324,7 +324,7 @@ func (e *Executor) checkoutPlugin(ctx context.Context, p *plugin.Plugin) (*plugi
// that means a potentially slow and unnecessary clone on every build step. Sigh. I think the
// tradeoff is favourable for just blowing away an existing clone if we want least-hassle
// guarantee that the user will get the latest version of their plugin branch/tag/whatever.
if e.ExecutorConfig.PluginsAlwaysCloneFresh && utils.FileExists(pluginDirectory) {
if e.ExecutorConfig.PluginsAlwaysCloneFresh && osutil.FileExists(pluginDirectory) {
e.shell.Commentf("BUILDKITE_PLUGINS_ALWAYS_CLONE_FRESH is true; removing previous checkout of plugin %s", p.Label())
err = os.RemoveAll(pluginDirectory)
if err != nil {
Expand All @@ -333,7 +333,7 @@ func (e *Executor) checkoutPlugin(ctx context.Context, p *plugin.Plugin) (*plugi
}
}

if utils.FileExists(pluginGitDirectory) {
if osutil.FileExists(pluginGitDirectory) {
// It'd be nice to show the current commit of the plugin, so
// let's figure that out.
headCommit, err := gitRevParseInWorkingDirectory(ctx, e.shell, pluginDirectory, "--short=7", "HEAD")
Expand Down
2 changes: 2 additions & 0 deletions internal/osutil/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Package osutil provides some OS-level helper functions.
package osutil
2 changes: 1 addition & 1 deletion internal/utils/file.go → internal/osutil/file.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package utils
package osutil

import (
"fmt"
Expand Down
12 changes: 12 additions & 0 deletions internal/osutil/homedir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package osutil

import "os"

// UserHomeDir is similar to os.UserHomeDir, but prefers $HOME when available
// over other options (such as USERPROFILE on Windows).
func UserHomeDir() (string, error) {
if h := os.Getenv("HOME"); h != "" {
return h, nil
}
return os.UserHomeDir()
}
50 changes: 50 additions & 0 deletions internal/osutil/homedir_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package osutil

import (
"os"
"runtime"
"testing"
)

func TestUserHomeDir(t *testing.T) {
// not parallel because it messes with env vars
origHome := os.Getenv("HOME")
origUserProfile := os.Getenv("USERPROFILE")
t.Cleanup(func() {
os.Setenv("HOME", origHome)
os.Setenv("USERPROFILE", origUserProfile)
})

type testCase struct {
home, userProfile, want string
}

tests := []testCase{
{
// Prefer $HOME on all platforms
home: "home",
userProfile: "userProfile",
want: "home",
},
}
if runtime.GOOS == "windows" {
// Windows can use %USERPROFILE% as a treat when $HOME is unavailable
tests = append(tests, testCase{
home: "",
userProfile: "userProfile",
want: "userProfile",
})
}

for _, test := range tests {
os.Setenv("HOME", test.home)
os.Setenv("USERPROFILE", test.userProfile)
got, err := UserHomeDir()
if err != nil {
t.Errorf("HOME=%q USERPROFILE=%q UserHomeDir() error = %v", test.home, test.userProfile, err)
}
if got != test.want {
t.Errorf("HOME=%q USERPROFILE=%q UserHomeDir() = %q, want %q", test.home, test.userProfile, got, test.want)
}
}
}
2 changes: 1 addition & 1 deletion internal/utils/path.go → internal/osutil/path.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package utils
package osutil

import (
"errors"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package utils
package osutil

import (
"os"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//go:build windows
// +build windows

package utils
package osutil

import (
"os"
Expand Down
4 changes: 0 additions & 4 deletions internal/utils/doc.go

This file was deleted.