Skip to content

fix(home): REPL history and settings follow LUCLI_HOME - #22

Merged
bpamiri merged 3 commits into
wheelsfrom
peter/lucli-home-history-settings
Oct 6, 2026
Merged

bpamiri merged 3 commits into
wheelsfrom
peter/lucli-home-history-settings

Conversation

@bpamiri

@bpamiri bpamiri commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Upstream issue: cybersonic#140

What

With LUCLI_HOME (or -Dlucli.home) pointing at an isolated directory, three places still wrote into the real home, because they built their paths from user.home:

  • lucli repl history: user.home/<profile home>/repl_history;
  • the interactive terminal's history: user.home/.lucli/history;
  • Settings (settings.json, used e.g. by secrets provider use): user.home/.lucli/settings.json. That also isn't the file lucli system paths reports (<LUCLI_HOME>/settings.json) or the one ModuleCommand reads.

How

  • All three resolve the active LuCLI home through LucliPaths.resolve().home(): -Dlucli.home, then LUCLI_HOME, then ~/<profile home>.
  • With neither set, REPL history and the default lucli profile's settings are where they were.
  • Migration: when the active home has no settings.json but user.home/.lucli/settings.json exists (and is a different file), Settings reads it once and saves a copy to the active home. The legacy file is left untouched. So a saved secret-provider choice isn't lost, e.g. for an aliased binary whose profile home is ~/.wheels.
  • The terminal history moves from ~/.lucli/history to the active home without migration (history only).

Tests

  • New:
    • SettingsTest.settingsFollowTheLucliHomeProperty: settings land in lucli.home, and nothing is written under user.home.
    • SettingsTest.legacySettingsAreReadOnceAndCopiedToTheActiveHome: the legacy value is read and copied, and the legacy file is unchanged.
    • ReplCommandHistoryTest.historyFileIsInTheLucliHome.
  • RED on wheels @ 8942048 (the new SettingsTest only, separate worktree): exactly the 2 new cases failed (expected <…/custom-home> but was <…>; copied to the active home ==> expected true); the other 30 passed.
  • GREEN: mvn test gave 772 tests, 0 failures, 0 errors, 6 skipped. BATS not run locally (no bats-core); please rely on CI.
  • End to end (isolated LUCLI_HOME / HOME / -Duser.home, printf '1+1\nexit\n' | lucli repl): v0.6.2.2 wrote user.home/.lucli/repl_history; this branch writes <LUCLI_HOME>/repl_history and nothing under user.home.

Not in this PR (same pattern, follow-ups)

Other user.home/.lucli constructions remain, e.g. ServerConfigHelper.CACHE_DIR, BuiltinVariableManager (line 333), ServerCommandHandler (line 2346), CFLintDownloader, and the dependency installers' fallbacks. They're worth a separate pass with their own tests.

Fork bookkeeping

CHANGELOG ## Unreleased entry; FORK.md "Next queue" row 10.

Upstream

The same change goes to cybersonic/LuCLI as a cherry-pick -x onto upstream main (without FORK.md) once this is reviewed.

🤖 Generated with Claude Code

bpamiri and others added 2 commits October 6, 2026 04:34
ReplCommand, Terminal and Settings built their paths from user.home, so
with LUCLI_HOME / -Dlucli.home set they still wrote into the real home,
and Settings' settings.json wasn't the file 'system paths' reports.
They now resolve the active LuCLI home through LucliPaths.

Settings saved at the old location (user.home/.lucli/settings.json) are
read once and copied to the active home when it has none; the old file
is left untouched.

Upstream: cybersonic#140

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Unit Tests (ubuntu-latest, Java 21)

 63 files   63 suites   2m 36s ⏱️
771 tests 765 ✅ 6 💤 0 ❌
776 runs  770 ✅ 6 💤 0 ❌

Results for commit d7eb282.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Integration Tests (ubuntu-latest, Java 21)

78 tests   78 ✅  2m 5s ⏱️
14 suites   0 💤
 1 files     0 ❌

Results for commit d7eb282.

♻️ This comment has been updated with latest results.

@bpamiri

bpamiri commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

rev1-r3 review @ 76cb0c4: APPROVE (final)

RED before, reproduced. I copied the new SettingsTest onto wheels @ 8942048: 32 tests, exactly 2 failures. settingsFollowTheLucliHomeProperty expected …/custom-home but got …/.lucli, and legacySettingsAreReadOnceAndCopiedToTheActiveHome failed on "copied to the active home". ReplCommandHistoryTest doesn't compile on base, because historyFile() is new. GREEN on the branch: SettingsTest 32/0/0 and ReplCommandHistoryTest 1/0/0.

End to end: JDK 21 jars, with an isolated LUCLI_HOME + -Dlucli.home and a sandboxed HOME + -Duser.home holding a legacy .lucli/settings.json. I took a hash of the legacy file before each run.

Scenario base this branch
printf '1+1\nexit\n' | lucli repl writes user.home/.lucli/repl_history repl_history in LUCLI_HOME; nothing new under user.home
secrets provider list, active home has no settings.json creates user.home/.lucli/prompts; legacy not copied legacy content copied to <LUCLI_HOME>/settings.json; nothing under user.home
same, active home already has settings.json (unchanged) left untouched (no overwrite)
legacy file hash after every run OK OK (never modified or deleted)

Checks against the review brief:

  • the legacy copy never overwrites, because it only runs when the active settings.json is absent;
  • it never deletes or modifies the legacy file, which is only read;
  • nothing is written outside LUCLI_HOME.

The default case keeps the same paths for the default lucli profile.

PR CI: green on every job (Build ×3, Unit ×3, Integration ×2); the APT smoke check was skipped.

Notes, not blocking:

  • The migration also fires for a deliberately isolated fresh home (CI, test sandboxes, -Dlucli.home=/tmp/x). The first run reads the user's real ~/.lucli/settings.json and copies it into the sandbox. That's needed for the motivating case (the brew wheels wrapper sets LUCLI_HOME=~/.wheels explicitly), so I wouldn't restrict it, but say it in the CHANGELOG or docs so nobody is surprised to see their provider choice in a sandbox.
  • Terminal and ReplCommand use the fully qualified org.lucee.lucli.paths.LucliPaths inline, while Settings imports it. Pick one form before the upstream cherry-pick.
  • Unrelated to this PR, found while inventorying homes: the suite's ModuleArgBindingTest installs its typedbind fixture into the real ~/.lucli/modules (user.home). A mvn test run elsewhere on this machine just created ~/.lucli/modules/typedbind. That fits the follow-up list in the description (user.home/.lucli constructions).

Inventory: my binary runs used only sandboxed homes. ~/.wheels is unchanged and ~/.lucee is absent. The only change in ~/.lucli was the typedbind directory above, which another seat's mvn test created, not this review.

…story-settings

Signed-off-by: Peter Amiri <peter@alurium.com>

# Conflicts:
#	CHANGELOG.md
#	FORK.md
@bpamiri

bpamiri commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator Author

rev1-r3 review @ d7eb282: APPROVE (final)

This head is a two-parent merge of the approved 76cb0c4 and wheels (dd80115). The PR's src/ changes against wheels are identical to 76cb0c4: Settings, Terminal, ReplCommand and the two tests. The conflict resolution touches only CHANGELOG and FORK.md, and keeps both sides:

PR CI on this head: Build ×3, Unit ×3 and Integration ×2 all pass; APT smoke skipped. mergeStateStatus is CLEAN.

Ready to merge.

@bpamiri
bpamiri merged commit 7830ed0 into wheels Oct 6, 2026
11 checks passed
@bpamiri
bpamiri deleted the peter/lucli-home-history-settings branch October 6, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant