From 3be9586238b842b478dc44507d13f095d6c03984 Mon Sep 17 00:00:00 2001 From: Brandon Lucas Date: Mon, 23 Feb 2026 13:50:04 -0500 Subject: [PATCH] Fix design issues and add comprehensive test suite Guard doSetup() against re-initialization, route welcome to onboard wizard, fix import confirmation logic, remove invalid syncthing generate flags, and show full export path. Add shell-based integration test suite (123 tests) at ~/src/test/pal/ covering all commands. Co-Authored-By: Claude Opus 4.6 --- cli/pal.lux | 43 ++++++++++++++++++++++++++++++++----------- flake.lock | 8 ++++---- flake.nix | 2 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/cli/pal.lux b/cli/pal.lux index edec12c..3ce60bc 100644 --- a/cli/pal.lux +++ b/cli/pal.lux @@ -339,7 +339,7 @@ fn showInteractiveWelcome(): Unit with {Console, Process} = { "3" => showHelp(), _ => { print("") - doSetup() + doOnboard() } } } @@ -371,7 +371,28 @@ fn createDirectories(): Unit with {Process} = { ensureDir(base + "/server") } -fn doSetup(): Unit with {Process} = { +fn doSetup(): Unit with {Console, Process} = { + print("") + + if isInitialized() then { + printWarn("pal is already initialized on this device.") + print("") + let rerun = askConfirm("Re-run setup? This will overwrite your config.", false) + if rerun == false then { + print("") + printHint("No changes made.") + print("") + () + } else { + print("") + doSetupSteps() + } + } else { + doSetupSteps() + } +} + +fn doSetupSteps(): Unit with {Process} = { print("") printHeader("Setting up pal") @@ -403,7 +424,7 @@ fn doSetup(): Unit with {Process} = { if hasCommand("syncthing") then { let hasConfig = execQuiet("test -f " + palDir() + "/syncthing/config/config.xml && echo yes || echo no") if hasConfig |> isNo then { - let ignore3 = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config --no-default-folder --gui-listen=127.0.0.1:8385 2>&1") + let ignore3 = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config 2>&1") printStep("Initializing sync", "done") } else { printStep("Initializing sync", "ready") @@ -508,7 +529,7 @@ fn doSyncSetup(): Unit with {Process} = { let hasConfig = execQuiet("test -f " + palDir() + "/syncthing/config/config.xml && echo yes || echo no") if hasConfig |> isNo then { printStepPending("Creating config") - let ignore = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config --no-default-folder --gui-listen=127.0.0.1:8385 2>&1") + let ignore = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config 2>&1") printStep("Creating config", "done") } else { printStep("Creating config", "exists") @@ -779,7 +800,7 @@ fn doExport(): Unit with {Console, Process} = { let fileSize = execQuiet("du -h " + exportPath + " | cut -f1") printStep("Creating archive", fileSize) print("") - printSuccess("Export created: " + exportFile) + printSuccess("Export created: " + exportPath) print("") printHint("Restore with:") printCmd("pal import " + exportFile) @@ -814,11 +835,7 @@ fn doImport(archivePath: String): Unit with {Console, Process} = { print("") let confirmed = askConfirm("Continue?", false) - if confirmed == false then { - print("") - printHint("Import cancelled.") - print("") - } else { + if confirmed then { print("") printHeader("Importing") @@ -844,6 +861,10 @@ fn doImport(archivePath: String): Unit with {Console, Process} = { printErr("Import failed - config not found in archive") } print("") + } else { + print("") + printHint("Import cancelled.") + print("") } } else { // No existing data, proceed without confirmation @@ -1339,7 +1360,7 @@ fn doOnboardSteps(): Unit with {Console, Process} = { let hasConfig = execQuiet("test -f " + palDir() + "/syncthing/config/config.xml && echo yes || echo no") if hasConfig |> isNo then { printStepPending("Creating sync config") - let ignore11 = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config --no-default-folder --gui-listen=127.0.0.1:8385 2>&1") + let ignore11 = Process.exec("syncthing generate --home=" + palDir() + "/syncthing/config 2>&1") printStep("Creating sync config", "done") } else { printStep("Creating sync config", "exists") diff --git a/flake.lock b/flake.lock index 0e9f001..0bf629a 100644 --- a/flake.lock +++ b/flake.lock @@ -47,13 +47,13 @@ "rust-overlay": "rust-overlay" }, "locked": { - "lastModified": 1771221263, - "narHash": "sha256-Av4s4pelV+ueIMSY61aHuT8KjKZ6ekXtJsnjVc89gtQ=", - "path": "/home/blu/src/lux", + "lastModified": 1771638380, + "narHash": "sha256-RLGfahDSlYi8ec50DtmfOZn9q8JpF2xBTcUb8K2ZQ3Q=", + "path": "/home/blu/src/lux/lang", "type": "path" }, "original": { - "path": "/home/blu/src/lux", + "path": "/home/blu/src/lux/lang", "type": "path" } }, diff --git a/flake.nix b/flake.nix index 8c6b9c7..d8bb0ea 100644 --- a/flake.nix +++ b/flake.nix @@ -15,7 +15,7 @@ }; lux = { - url = "path:/home/blu/src/lux"; + url = "path:/home/blu/src/lux/lang"; inputs.nixpkgs.follows = "nixpkgs"; };