sh icon indicating copy to clipboard operation
sh copied to clipboard

interp: provide a public API to access the Runner's final environment after Run

Open theclapp opened this issue 3 years ago • 3 comments

Currently Runner.writeEnv is copied into Runner.Vars at the end of Runner.Run, but there's a comment that says Vars is going away.

After a Slack discussion, @mvdan suggested

// FinalEnv allows querying the environment variables set after the runner has interpreted a program.
// It is only valid to call this method after Runner.Run has finished.
// The returned environment is read-only, and is only valid until the next call to Run or Reset.
func (*Runner) FinalEnv() expand.Environ

which seems like it'd work.

My use-case is that I'm writing a shell app using this library to parse and run shell commands. I am currently working on some rudimentary completion code, where (for example) you can type $GO and the listed completions are GO111MODULE, GOPATH, and GOROOT.

To do this correctly, I need to read the environment after every shell command.

Ideally, of course, this api would list environment variables, function names, and anything else that Runner knows about that the user might want to refer to. If there are separate calls for each kind of "thing", that's fine.

theclapp avatar Mar 08 '22 13:03 theclapp

For the funcs, you can rely on the Funcs map today just like Vars. I would prefer to not have a map field in v4, because that's still inefficient and allows the user to modify it directly, but I haven't thought about what the API could look like yet.

mvdan avatar Mar 08 '22 13:03 mvdan

Err, scratch the inefficiency part for funcs, because as far as I'm aware they don't need to support any form of scoping. But we still want to provide a form of "read only, only after Run has finished" form of API to avoid misuse and data races.

mvdan avatar Mar 08 '22 13:03 mvdan

we still want to provide a form of "read only, only after Run has finished" form of API

For "read only" — provide a function or method on an object that returns a fresh map. For "only after Run has finished", perhaps Run could return an object that you could query for the environment (and perhaps other things that would naturally follow the "only after Run has finished" paradigm, like "command status").

theclapp avatar Apr 05 '22 21:04 theclapp