Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix case-preserving environment updates on Windows #5356

Merged
merged 5 commits into from
Feb 8, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add comment to OpamStd.Env.Name
  • Loading branch information
dra27 committed Feb 8, 2023
commit 12b4a5beaf163a73e79db26f736a9982963ab3ba
24 changes: 23 additions & 1 deletion src/core/opamStd.mli
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,29 @@ module Env : sig

(** {3 Environment variable handling} *)

(** Environment variable names *)
(** Environment variable names. Windows has complicated semantics for
environment variables. The retrieval functions are case insensitive, but
it's "legal" for the environment block to contain entries which differ
only by case. If environment variables are set entirely using CRT or Win32
API functions, then there isn't usually a problem, the issue arises when
creating a program where the environment block is instead passed. In this
model, it's very easy to end up with two bindings in the same block. When
dealing with Windows programs, this will mostly be transparent, but it's a
problem with Cygwin which actively allows "duplicate" entries which differ
by case only and implements Posix semantics on top of this. The problem is
constantly with us thanks to the use of PATH on Unix, and Path on Windows!
opam tries to ensure that environment variables are looked up according to
the OS semantics (so case insensitively on Windows) and OpamEnv goes to
some trouble to ensure that updates to environment variables are case
preserving (i.e. PATH+=foo gets transformed to Path+=foo if Path exists
in the environment block).

Key to this is not accidentally treating environment variable names as
strings, without using the appropriate comparison functions. Name.t
represents environment variable names as private strings, providing
comparison operators to handle them, and still allowing the possibility
to coerce them to strings.
*)
module Name : sig
include ABSTRACT with type t = private string

Expand Down