Skip to content

Commit

Permalink
pkg/mods/runtime: Make $elvish-path $nil if os.Executable returns an …
Browse files Browse the repository at this point in the history
…error.
  • Loading branch information
xiaq committed Aug 13, 2022
1 parent b040248 commit 7c75510
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 14 deletions.
31 changes: 17 additions & 14 deletions pkg/mods/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
//
// A list containing
// [module search directories](command.html#module-search-directories).
//
// This variable is read-only.

//elvdoc:var rc-path
//
Expand All @@ -22,6 +24,8 @@ import (
// If there was an error in determining the path of the RC file, this variable
// is `$nil`.
//
// This variable is read-only.
//
// @cf $runtime:effective-rc-path

//elvdoc:var effective-rc-path
Expand All @@ -38,34 +42,33 @@ import (
// - Otherwise (when Elvish is running interactively and invoked without
// `-norc` or `-rc`), this variable has the same value as `$rc-path`.
//
// This variable is read-only.
//
// @cf $runtime:rc-path

//elvdoc:var elvish-path
//
// The path to the elvish binary. If that could not be determined the value will be the empty
// string.
// The path to the Elvish binary.
//
// If there was an error in determining the path, this variable is `$nil`.
//
// This is read-only.
// This variable is read-only.

func elvishPath() any {
// TODO: Decide what to do if os.Executable returns an error. It appears that all platforms
// return an empty string. Which makes sense and is probably good enough for our purposes.
// Nonetheless, we explicitly encode that logic rather than rely on the behavior of
// os.Executable. TBD is whether we should instead raise an exception.
if binPath, err := os.Executable(); err == nil {
return binPath
}
return ""
}
var osExecutable = os.Executable

// Ns returns the namespace for the runtime: module.
//
// All the public properties of the Evaler should be set before this function is
// called.
func Ns(ev *eval.Evaler) *eval.Ns {
elvishPath, err := osExecutable()
if err != nil {
elvishPath = ""
}

return eval.BuildNsNamed("runtime").
AddVars(map[string]vars.Var{
"elvish-path": vars.FromGet(elvishPath),
"elvish-path": vars.NewReadOnly(nonEmptyOrNil(elvishPath)),
"lib-dirs": vars.NewReadOnly(vals.MakeListSlice(ev.LibDirs)),
"rc-path": vars.NewReadOnly(nonEmptyOrNil(ev.RcPath)),
"effective-rc-path": vars.NewReadOnly(nonEmptyOrNil(ev.EffectiveRcPath)),
Expand Down
6 changes: 6 additions & 0 deletions pkg/mods/runtime/runtime_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package runtime

import (
"errors"
"os"
"testing"

"src.elv.sh/pkg/eval"
"src.elv.sh/pkg/eval/evaltest"
"src.elv.sh/pkg/eval/vals"
"src.elv.sh/pkg/testutil"
)

var That = evaltest.That
Expand All @@ -31,10 +33,14 @@ func TestRuntime(t *testing.T) {
}

func TestRuntime_NilPath(t *testing.T) {
testutil.Set(t, &osExecutable,
func() (string, error) { return "bad", errors.New("bad") })

setup := func(ev *eval.Evaler) {
ev.ExtendGlobal(eval.BuildNs().AddNs("runtime", Ns(ev)))
}
evaltest.TestWithSetup(t, setup,
That("put $runtime:elvish-path").Puts(nil),
That("put $runtime:rc-path").Puts(nil),
That("put $runtime:effective-rc-path").Puts(nil),
)
Expand Down

0 comments on commit 7c75510

Please sign in to comment.