GX_HOME, so both halves can be pointed at the same library - #47
Merged
Conversation
`gx` and the desktop could not be aimed at a library other than the real
one, and worse, they disagreed about how to try.
The desktop resolves its home through `dirs::home_dir()`, which follows
`$HOME`. `gx` is a GraalVM native image reading `user.home`, which on
macOS comes from the password database and ignores `$HOME` entirely. So
launching a desktop under a redirected `$HOME` and then asking `gx` about
it silently asked about the REAL desktop.
That is not hypothetical: it is what happened while verifying v0.9.4. The
"end-to-end" check reported a ready desktop in 0.05s, and the only tell
that it had measured the wrong machine was a brand-new sandbox library
claiming six diagrams and a watched file it could not possibly have. A
plausible number would have been believed.
`GX_HOME` replaces `~/.graph-explorer` wholesale, and BOTH sides read it.
Both is the point: the runtime file names the socket for the library it
belongs to, so a half-applied override splits them in a way nobody would
think to look for. It also answers "keep a second library" and "use a
throwaway one", neither of which had an answer.
Decisions worth naming:
- The variable names the data directory itself, not a home to nest a
dot-directory inside. Putting `.graph-explorer` under a path the
caller chose explicitly is the opposite of what naming one is for.
- A blank value reads as UNSET. `export GX_HOME="$SOMETHING"` with
SOMETHING unset is how a shell passes through an absent value; taken
literally it would put the library at `/library`.
- A relative value is absolutised. The library store decides whether a
name escapes its directory by comparing paths, and `gx` deliberately
takes its CWD from the user's shell.
- It is NOT a general home override. The access policy's denied roots
(`~/.ssh`, `~/.gnupg`, ...) keep reading the true home on both sides,
so relocating a library can never quietly un-deny a secret.
One resolver per side, both routed through: LibraryStore.default now takes
the GX home rather than the user's, so there is a single definition of
where the data lives.
The decision is a pure function of (env, home) on both sides, so the rule
is tested directly rather than through a process-global env var that would
race every other test in the binary. Same four cases in GxHomeSpec and in
main.rs.
Verified with the real binaries, both pointed at one GX_HOME, catching the
full sequence the previous PR made possible and this one made observable:
t= 0.03s desktop: not running (only `gx open` needs it)
t= 0.06s desktop: starting (its window is not up yet)
t= 0.33s desktop: running (watching nothing)
and the real library untouched throughout. That is the test that could not
be written before this change.
✅ Deploy Preview for graph-explorer-net ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gxand the desktop could not be aimed at a library other than the real one — and worse, they disagreed about how to try.$HOME?dirs::home_dir()gxuser.home(GraalVM native image)So launching a desktop under a redirected
$HOMEand then askinggxabout it silently asked about the real desktop.Not hypothetical: it is what happened while verifying v0.9.4. The "end-to-end" check reported a ready desktop in 0.05s, and the only tell that it had measured the wrong machine was a brand-new sandbox library claiming six diagrams and a watched file it could not possibly have. A plausible number would have been believed.
What it does
GX_HOMEreplaces~/.graph-explorerwholesale, and both sides read it. Both is the point — the runtime file names the socket for the library it belongs to, so a half-applied override splits them in a way nobody would think to look for. It also answers "keep a second library" and "use a throwaway one", neither of which had an answer.GX_HOME=/tmp/scratch graph-explorer-desktop & GX_HOME=/tmp/scratch gx statusDecisions worth naming
.graph-explorerunder a path you chose explicitly is the opposite of what naming one is for.export GX_HOME="$SOMETHING"with SOMETHING unset is how a shell passes through an absent value; taken literally it would put the library at/library.gxdeliberately takes its CWD from the user's shell.~/.ssh,~/.gnupg, …) keep reading the true home on both sides, so relocating a library can never quietly un-deny a secret.One resolver per side, both routed through it:
LibraryStore.defaultnow takes the GX home rather than the user's, so there is a single definition of where the data lives.Testing
The decision is a pure function of
(env, home)on both sides, so the rule is tested directly rather than through a process-global env var that would race every other test in the binary. Same four cases inGxHomeSpecand inmain.rs.Then verified with the real binaries, both pointed at one
GX_HOME, catching the full sequence #46 made possible and this one made observable:— with the real library untouched throughout. That is the test that could not be written before this change.
Local on this exact base:
gxCoreJVM175,gxCli61, Rust 40.