Change environment variables to be case-preserving (#12701)

This PR changes `$env` to be **case-preserving** instead of
case-sensitive. That is, it preserves the case of the environment
variable when it is first assigned, but subsequent retrieval and update
ignores the case.

Notably, both `$env.PATH` and `$env.Path` can now be used to read or set
the environment variable, but child processes will always see the
correct case based on the platform.

Fixes #11268.

---

This feature was surprising simple to implement, because most of the
infrastructure to support case-insensitive cell path access already
exists. The `get` command extracts data using a cell path in a
case-insensitive way (!), but accepts a `--sensitive` flag. (I think
this should be flipped around?)
This commit is contained in:
YizhePKU
2024-05-02 06:22:34 +08:00
committed by GitHub
parent 21ebdfe8d7
commit 52d99cc60c
3 changed files with 70 additions and 26 deletions

View File

@ -5,6 +5,7 @@ use crate::{
},
debugger::DebugContext,
Config, IntoInterruptiblePipelineData, Range, Record, ShellError, Span, Value, VarId,
ENV_VARIABLE_ID,
};
use std::{borrow::Cow, collections::HashMap};
@ -37,7 +38,13 @@ pub trait Eval {
Expr::FullCellPath(cell_path) => {
let value = Self::eval::<D>(state, mut_state, &cell_path.head)?;
value.follow_cell_path(&cell_path.tail, false)
// Cell paths are usually case-sensitive, but we give $env
// special treatment.
if cell_path.head.expr == Expr::Var(ENV_VARIABLE_ID) {
value.follow_cell_path(&cell_path.tail, true)
} else {
value.follow_cell_path(&cell_path.tail, false)
}
}
Expr::DateTime(dt) => Ok(Value::date(*dt, expr.span)),
Expr::List(list) => {