diff --git a/README.md b/README.md
index 9cf5917..4f37e51 100644
--- a/README.md
+++ b/README.md
@@ -190,13 +190,21 @@ flowchart TD
FindRoot --> CheckLucafile{Lucafile exists
in repo root?}
CheckLucafile -->|No| Exit2([Exit: no Lucafile])
- CheckLucafile -->|Yes| CheckLuca{luca command
available?}
+ CheckLucafile -->|Yes| CheckLuca{luca installed &
version correct?}
- CheckLuca -->|No| LogNotFound["Log: not found, installing"]
- CheckLuca -->|Yes| CheckVersion{".luca-version"
matches installed?}
+ CheckLuca -->|Yes| RunInstall
+ CheckLuca -->|No| CheckTTY{Interactive
terminal?}
- CheckVersion -->|Yes or no file| RunInstall
- CheckVersion -->|No| LogMismatch["Log: version mismatch
(installed vs required)"]
+ CheckTTY -->|"No TTY (e.g. GUI Git client)"| LucaMissing{luca
installed?}
+ LucaMissing -->|No| WarnNoTTYAbsent["⚠️ Non-interactive: luca absent
skipping install — run from terminal"]
+ LucaMissing -->|"Yes, wrong version"| WarnNoTTYMismatch["⚠️ Non-interactive: version mismatch
skipping self-update — run from terminal"]
+
+ WarnNoTTYAbsent --> Exit3([Exit: skip — no binary available])
+ WarnNoTTYMismatch --> RunInstall
+
+ CheckTTY -->|TTY present| LucaMissing2{luca
installed?}
+ LucaMissing2 -->|No| LogNotFound["Log: not found, installing"]
+ LucaMissing2 -->|"Yes, wrong version"| LogMismatch["Log: version mismatch
(installed vs required)"]
LogNotFound --> Download[Download & run
install.sh]
LogMismatch --> Download
@@ -211,16 +219,16 @@ flowchart TD
CheckResult -->|Yes| Success[✅ Tools synchronized]
CheckResult -->|No| Warning[⚠️ Some tools may
have failed]
- Success --> NotifyPath
- Warning --> NotifyPath
-
- NotifyPath["ℹ️ PATH will update
on next prompt"]
- NotifyPath --> Exit3([Exit: done])
+ Success --> Exit4([Exit: done])
+ Warning --> Exit4
style Exit1 fill:#FFE4B5
style Exit2 fill:#FFE4B5
+ style Exit3 fill:#FFE4B5
style ErrorExit fill:#FFB6C1
style Success fill:#90EE90
+ style WarnNoTTYAbsent fill:#FFE4B5
+ style WarnNoTTYMismatch fill:#FFE4B5
```
---
@@ -336,8 +344,14 @@ sequenceDiagram
G->>PC: Trigger post-checkout
PC->>PC: Check for Lucafile
PC->>PC: Check luca version vs .luca-version
- PC->>IS: Run install.sh if missing or version mismatch
- IS-->>PC: Done
+ alt TTY present and update needed
+ PC->>IS: Run install.sh
+ IS-->>PC: Done
+ else No TTY and luca absent
+ PC->>PC: ⚠️ Skip — non-interactive, no binary
+ else No TTY and version mismatch
+ PC->>PC: ⚠️ Skip self-update — non-interactive
+ end
PC->>L: luca install --quiet
L->>L: Install/update tools
L-->>PC: Done
diff --git a/post-checkout b/post-checkout
index 164d77b..8c852cf 100755
--- a/post-checkout
+++ b/post-checkout
@@ -129,27 +129,40 @@ log_info "Found $FOUND_SPEC, synchronizing tools..."
# Check if Luca is installed and version is correct, install/update if not
if ! is_luca_installed || ! is_luca_version_correct; then
- if ! is_luca_installed; then
- log_info "Luca not found, installing..."
+ if [ ! -t 0 ]; then
+ # No TTY — sudo cannot prompt for a password (e.g. GUI Git client).
+ # Skip the self-update and fall through to luca install below.
+ if ! is_luca_installed; then
+ log_warning "Non-interactive environment detected (e.g. GUI Git client). Luca is not installed — skipping automatic installation. Please run the setup from a terminal."
+ exit 0
+ else
+ REQUIRED=$(cat "$VERSION_FILE")
+ INSTALLED=$(luca --version 2>/dev/null)
+ log_warning "Non-interactive environment detected (e.g. GUI Git client). Luca version mismatch (installed: $INSTALLED, required: $REQUIRED) — skipping automatic update. Please run the setup from a terminal to apply the correct version."
+ fi
else
- REQUIRED=$(cat "$VERSION_FILE")
- INSTALLED=$(luca --version 2>/dev/null)
- log_info "Luca version mismatch (installed: $INSTALLED, required: $REQUIRED), updating..."
- fi
+ if ! is_luca_installed; then
+ log_info "Luca not found, installing..."
+ else
+ REQUIRED=$(cat "$VERSION_FILE")
+ INSTALLED=$(luca --version 2>/dev/null)
+ log_info "Luca version mismatch (installed: $INSTALLED, required: $REQUIRED), updating..."
+ fi
- if command -v curl >/dev/null 2>&1; then
- /bin/bash -c "$(curl -fsSL $INSTALL_SCRIPT_URL)"
- INSTALL_RESULT=$?
+ if command -v curl >/dev/null 2>&1; then
+ /bin/bash -c "$(curl -fsSL $INSTALL_SCRIPT_URL)"
+ INSTALL_RESULT=$?
- if [ $INSTALL_RESULT -ne 0 ]; then
- log_error "Failed to install Luca"
+ if [ $INSTALL_RESULT -ne 0 ]; then
+ log_error "Failed to install Luca"
+ exit 1
+ fi
+
+ log_success "Luca installed"
+ else
+ log_error "curl is required to install Luca"
exit 1
fi
-
- log_success "Luca installed"
- else
- log_error "curl is required to install Luca"
- exit 1
fi
fi
diff --git a/tests/post_checkout.bats b/tests/post_checkout.bats
index 55e0096..1284932 100644
--- a/tests/post_checkout.bats
+++ b/tests/post_checkout.bats
@@ -86,7 +86,7 @@ setup() {
fi
}
-@test "luca absent: curl called to install when luca not in PATH" {
+@test "luca absent, no-tty: skips installation with informative message and exits 0" {
cp "$FIXTURE_DIR/Lucafile" "$FAKE_REPO/Lucafile"
# Build a PATH that has git/curl mocks but NOT luca
local no_luca_bin="$BATS_TEST_TMPDIR/no_luca_bin"
@@ -95,11 +95,15 @@ setup() {
ln -sf "$TESTS_DIR/test_helper/mocks/$mock" "$no_luca_bin/$mock"
done
- # Intentionally omit /usr/local/bin to ensure real luca is not found
+ # Intentionally omit /usr/local/bin to ensure real luca is not found.
+ # bats runs without a TTY so the non-interactive path is exercised.
run env PATH="$no_luca_bin:/usr/bin:/bin" \
"$REPO_ROOT/post-checkout" prev_ref new_ref 1
- assert_output --partial "installing"
+ assert_success
+ assert_output --partial "Non-interactive environment"
+ assert_output --partial "skipping automatic installation"
+ assert_output --partial "terminal"
}
# ---------------------------------------------------------------------------
@@ -142,15 +146,29 @@ setup() {
refute_output --partial "installing"
}
-@test "version check: luca version mismatch triggers reinstall with mismatch message" {
+@test "version check, no-tty: version mismatch shows warning with installed and required versions" {
cp "$FIXTURE_DIR/Lucafile" "$FAKE_REPO/Lucafile"
echo "v2.0.0" > "$FAKE_REPO/.luca-version" # differs from MOCK_LUCA_VERSION (v1.0.0)
run "$REPO_ROOT/post-checkout" prev_ref new_ref 1
+ assert_output --partial "Non-interactive environment"
assert_output --partial "version mismatch"
assert_output --partial "v1.0.0"
assert_output --partial "v2.0.0"
+ assert_output --partial "terminal"
+}
+
+@test "version check, no-tty: version mismatch still runs luca install" {
+ cp "$FIXTURE_DIR/Lucafile" "$FAKE_REPO/Lucafile"
+ echo "v2.0.0" > "$FAKE_REPO/.luca-version" # differs from MOCK_LUCA_VERSION (v1.0.0)
+
+ run "$REPO_ROOT/post-checkout" prev_ref new_ref 1
+
+ assert_success
+ assert_output --partial "Tools synchronized successfully"
+ run grep "luca install --quiet --no-install-post-checkout-git-hook" "$MOCK_LUCA_CALL_LOG"
+ assert_success
}
@test "version check: no .luca-version file skips version check" {