github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/init.go (about) 1 package lang 2 3 import ( 4 "context" 5 "os" 6 "sync/atomic" 7 "time" 8 9 "github.com/lmorg/murex/app" 10 "github.com/lmorg/murex/builtins/pipes/null" 11 "github.com/lmorg/murex/builtins/pipes/term" 12 "github.com/lmorg/murex/config" 13 "github.com/lmorg/murex/lang/ref" 14 "github.com/lmorg/murex/lang/runmode" 15 "github.com/lmorg/murex/lang/state" 16 "github.com/lmorg/murex/lang/types" 17 "github.com/lmorg/murex/utils/consts" 18 "github.com/lmorg/murex/utils/json" 19 ) 20 21 var ( 22 // FlagTry is true if murex was started with `--try` 23 FlagTry bool 24 25 // FlagTryPipe is true if murex was started with `--trypipe` 26 FlagTryPipe bool 27 28 // FlagTryErr is true if murex was started with `--tryerr` 29 FlagTryErr bool 30 31 // FlagTryPipeErr is true if murex was started with `--trypipeerr` 32 FlagTryPipeErr bool 33 34 hasMurexAlreadyBeenInitialised int32 = -1 35 ) 36 37 // InitEnv initialises murex. Exported function to enable unit tests. 38 func InitEnv() { 39 i := atomic.AddInt32(&hasMurexAlreadyBeenInitialised, 1) 40 if i > 0 { 41 return 42 } 43 44 ShellProcess.CreationTime = time.Now() 45 ShellProcess.State.Set(state.Executing) 46 ShellProcess.Name.Set(os.Args[0]) 47 ShellProcess.Parameters.DefineParsed(os.Args[1:]) 48 ShellProcess.Scope = ShellProcess 49 ShellProcess.Parent = ShellProcess 50 ShellProcess.Previous = ShellProcess 51 ShellProcess.Next = ShellProcess 52 ShellProcess.Config = config.InitConf 53 ShellProcess.Tests = NewTests(ShellProcess) 54 ShellProcess.Variables = NewVariables(ShellProcess) 55 ShellProcess.Stdout = new(term.Out) 56 ShellProcess.Stderr = term.NewErr(true) // TODO: check this is overridden by `config set ...` 57 ShellProcess.FileRef = ref.NewModule(app.ShellModule) 58 ShellProcess.Context = context.Background() 59 ShellProcess.Done = func() { /* we don't want to accidentally terminate the shell process */ } 60 ShellProcess.Kill = func() { /* we don't want to accidentally terminate the shell process */ } 61 ShellProcess.Forks = NewForkManagement() 62 63 switch { 64 case FlagTry: 65 ShellProcess.RunMode = runmode.ModuleTry 66 case FlagTryPipe: 67 ShellProcess.RunMode = runmode.ModuleTryPipe 68 case FlagTryErr: 69 ShellProcess.RunMode = runmode.ModuleTryErr 70 case FlagTryPipeErr: 71 ShellProcess.RunMode = runmode.ModuleTryPipeErr 72 } 73 74 // Sets $SHELL to be murex 75 shellEnv, err := os.Executable() 76 if err != nil { 77 shellEnv = ShellProcess.Name.String() 78 } 79 os.Setenv("SHELL", shellEnv) 80 81 if os.Getenv(consts.EnvMethod) == consts.EnvTrue { 82 ShellProcess.Stdin = term.NewIn(os.Getenv(consts.EnvDataType)) 83 ShellProcess.IsMethod = true 84 } 85 86 if os.Getenv(consts.EnvBackground) == consts.EnvTrue { 87 ShellProcess.Background.Set(true) 88 } 89 90 // Pre-populate $PWDHIST with current working directory 91 s, _ := os.Getwd() 92 pwd := []string{s} 93 if b, err := json.Marshal(&pwd, false); err == nil { 94 GlobalVariables.Set(ShellProcess, "PWDHIST", string(b), types.Json) 95 } 96 97 if err = MethodStdin.Degroup(); err != nil { 98 panic(err.Error()) 99 } 100 if err = MethodStdout.Degroup(); err != nil { 101 panic(err.Error()) 102 } 103 } 104 105 // NewTestProcess creates a dummy process for testing in Go (ie `go test`) 106 func NewTestProcess() (p *Process) { 107 p = new(Process) 108 p.Stdin = new(null.Null) 109 p.Stdout = new(null.Null) 110 p.Stderr = new(null.Null) 111 p.Config = config.InitConf.Copy() 112 p.Variables = NewVariables(p) 113 p.FileRef = &ref.File{Source: &ref.Source{Module: "builtin/testing"}} 114 p.Context, p.Done = context.WithTimeout(context.Background(), 60*time.Second) 115 p.Parent = ShellProcess 116 p.Scope = ShellProcess 117 p.Next = ShellProcess 118 p.Previous = ShellProcess 119 p.Forks = NewForkManagement() 120 121 GlobalFIDs.Register(p) 122 123 return 124 }