diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c6eb6ce..9afec1e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,11 @@ - Added `os.Root` bindings to the JSVM ([`$os.openRoot`](https://pocketbase.io/jsvm/functions/_os.openRoot.html), [`$os.openInRoot`](https://pocketbase.io/jsvm/functions/_os.openInRoot.html)). -- Various minor UI improvements (updated collections indexes merge UI, enabled seconds in the datepicker, updated helper texts, etc.). +- Added `osutils.IsProbablyGoRun()` helper to loosely check if the executable was started using `go run`. -- ⚠️ Updated the min package Go version to 1.24.0 and bumped Go dependencies. +- Various minor UI improvements (updated collections indexes UI, enabled seconds in the datepicker, updated helper texts, etc.). + +- ⚠️ Updated the minimum package Go version to 1.24.0 and bumped Go dependencies. ## v0.29.3 diff --git a/apis/installer.go b/apis/installer.go index b94c599b..72405808 100644 --- a/apis/installer.go +++ b/apis/installer.go @@ -88,8 +88,7 @@ func findOrCreateInstallerSuperuser(app core.App) (*core.Record, error) { } func executablePath() string { - // most likely ran with go run - if strings.HasPrefix(os.Args[0], os.TempDir()) { + if osutils.IsProbablyGoRun() { return "go run ." } diff --git a/examples/base/main.go b/examples/base/main.go index ff03b85b..1ea529b4 100644 --- a/examples/base/main.go +++ b/examples/base/main.go @@ -5,7 +5,6 @@ import ( "net/http" "os" "path/filepath" - "strings" "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" @@ -14,6 +13,7 @@ import ( "github.com/pocketbase/pocketbase/plugins/jsvm" "github.com/pocketbase/pocketbase/plugins/migratecmd" "github.com/pocketbase/pocketbase/tools/hook" + "github.com/pocketbase/pocketbase/tools/osutils" ) func main() { @@ -123,8 +123,7 @@ func main() { // the default pb_public dir location is relative to the executable func defaultPublicDir() string { - if strings.HasPrefix(os.Args[0], os.TempDir()) { - // most likely ran with go run + if osutils.IsProbablyGoRun() { return "./pb_public" } diff --git a/pocketbase.go b/pocketbase.go index cc083a12..6ca4355a 100644 --- a/pocketbase.go +++ b/pocketbase.go @@ -14,6 +14,7 @@ import ( "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/hook" "github.com/pocketbase/pocketbase/tools/list" + "github.com/pocketbase/pocketbase/tools/osutils" "github.com/pocketbase/pocketbase/tools/routine" "github.com/spf13/cobra" @@ -293,7 +294,7 @@ func (pb *PocketBase) skipBootstrap() bool { // note: we are using os.Args[0] and not os.Executable() since it could // break existing aliased binaries (eg. the community maintained homebrew package) func inspectRuntime() (baseDir string, withGoRun bool) { - if strings.HasPrefix(os.Args[0], os.TempDir()) { + if osutils.IsProbablyGoRun() { // probably ran with go run withGoRun = true baseDir, _ = os.Getwd() diff --git a/tools/osutils/cmd.go b/tools/osutils/cmd.go index d21f8865..5e7ecc33 100644 --- a/tools/osutils/cmd.go +++ b/tools/osutils/cmd.go @@ -63,3 +63,17 @@ func YesNoPrompt(message string, fallback bool) bool { } } } + +// IsProbablyGoRun loosely checks if the current executable is running +// as a result of "go run". +func IsProbablyGoRun() bool { + runDirs := []string{os.TempDir(), os.Getenv("GOCACHE")} + + for _, dir := range runDirs { + if dir != "" && strings.HasPrefix(os.Args[0], dir) { + return true + } + } + + return false +} diff --git a/tools/osutils/cmd_test.go b/tools/osutils/cmd_test.go index 38beeab1..8d15012c 100644 --- a/tools/osutils/cmd_test.go +++ b/tools/osutils/cmd_test.go @@ -64,3 +64,40 @@ func TestYesNoPrompt(t *testing.T) { }) } } + +func TestIsProbablyGoRun(t *testing.T) { + scenarios := []struct { + arg string + envs map[string]string + expected bool + }{ + {"", nil, false}, + {"a/b/c", nil, false}, + {"/a/b/c", nil, false}, + {"/a/b/c", map[string]string{"GOCACHE": "/b/"}, false}, + {"/a/b/c", map[string]string{"GOCACHE": "/a/"}, true}, + {os.TempDir() + "/a/b/c", nil, true}, + } + + originalArgs := os.Args + defer func() { + os.Args = originalArgs + }() + + for _, s := range scenarios { + t.Run(s.arg, func(t *testing.T) { + os.Args = []string{s.arg} + + for k, v := range s.envs { + defer os.Setenv(k, os.Getenv(k)) + os.Setenv(k, v) + } + + result := osutils.IsProbablyGoRun() + + if result != s.expected { + t.Fatalf("Expected %v, got %v", s.expected, result) + } + }) + } +}