Support environment variables in the settings#15082
Conversation
* use StringMap as a container
* recursively resolve ${env:NAME} vars in values in the StringMap or in
the process' environment
* implement some tests
* add comments to ResolveEnvironmentVariableValue * use wil helper * remove unused code
* allow appending or prepending process environment variables * don't handle all exceptions on validation failure
* Use INHERITABLE_SETTING macro
|
holy shit the madman actually did it |
|
idle thought before reading the code: the original PR might predate layering. Lets see how this works with layering. Can the defaults say (for example) |
|
Currently the concrete profile's environment completely replaces the one specified in defaults. So if you've got: "defaults": {
"environment": {
"Foo": "Bar"
}
},
"list": [
{
"name": "PowerShell",
"environment": {
"Baz": "Qux"
}
}
]Your PowerShell profile will get |
ianjoneill
left a comment
There was a problem hiding this comment.
Some thoughts before I open Visual Studio
| til::env environment; | ||
| auto zeroEnvMap = wil::scope_exit([&]() noexcept { | ||
| // Can't zero the keys, but at least we can zero the values. | ||
| for (auto& [name, value] : environment) | ||
| for (auto& [name, value] : environment.as_map()) | ||
| { | ||
| ::SecureZeroMemory(value.data(), value.size() * sizeof(decltype(value.begin())::value_type)); | ||
| } | ||
|
|
||
| environment.clear(); | ||
| environment.as_map().clear(); | ||
| }); |
There was a problem hiding this comment.
Unless I'm missing something, if we did this as part of regenerate() the map would be cleared on exit of the method which would mean the map would be populated and immediately cleared.
It would probably make sense to extract this for loop into a clear() method on til::env, so that the caller doesn't need to worry about the internal representation.
With regards to whether it's necessary, I can't answer that - I don't know why the code originally did this. It's possible the environment could contain sensitive information (e.g. temporary credentials), which you may want to clear out.
| } | ||
| _reloadEnvironmentVariables = winrt::unbox_value_or<bool>(settings.TryLookup(L"reloadEnvironmentVariables").try_as<Windows::Foundation::IPropertyValue>(), | ||
| _reloadEnvironmentVariables); | ||
| _profileGuid = winrt::unbox_value_or<winrt::guid>(settings.TryLookup(L"profileGuid").try_as<Windows::Foundation::IPropertyValue>(), _profileGuid); |
There was a problem hiding this comment.
Ah - it seemed silly both this and TerminalPage doing the same dance fiddling with WSLENV though.
|
Just FYI I should be able to take a look at this tomorrow (Friday). |
|
This is very subtle (and I am only testing as of >5 hours ago, so please ignore if changed), but you can resurrect inherited environment variables depending on sort order. I don't know if I think this is an issue worth fixing, but it is fun! |
|
Oh, no, I'm totally happy with how it works today! I legitimately found it interesting 😄 |
DHowett
left a comment
There was a problem hiding this comment.
I love it. Thanks @ianjoneill and @christapley :)
Just to clarify: as of this PR, it is possible to set environment variables in |
|
@DHowett Oh, that sucks. Just when I thought that I had finally found a way to easily manage my |




Existing environment variables can be referenced by enclosing the name in percent characters (e.g.
%PATH%).Resurrects #9287 by @christapley.
Tests added and manually tested.
Closes #2785
Closes #9233
Co-authored-by: Chris Tapley [email protected]