From fb2c2c02b96bd8e16b3e770324b6b11208a2b908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Sun, 28 Jun 2026 21:34:03 +0200 Subject: [PATCH] Use /usr/bin/env bash for widely compatible shebang MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sandro Jäckel --- scripts/benchmark-search-graph.sh | 2 +- scripts/build.sh | 2 +- scripts/check-nolint-whitelist.sh | 2 +- scripts/clean.sh | 2 +- scripts/embed-frontend.sh | 2 +- scripts/env.sh | 2 +- scripts/lint.sh | 2 +- scripts/repro.sh | 2 +- scripts/soak-test.sh | 2 +- scripts/test.sh | 2 +- scripts/vendor-grammar.sh | 2 +- src/cli/cli.c | 4 ++-- test-infrastructure/run.sh | 2 +- tests/repro/repro_issue409.c | 2 +- tests/test_pipeline.c | 26 +++++++++++++------------- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/scripts/benchmark-search-graph.sh b/scripts/benchmark-search-graph.sh index 3da58492c..cc94147ec 100755 --- a/scripts/benchmark-search-graph.sh +++ b/scripts/benchmark-search-graph.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # benchmark-search-graph.sh — Time search_graph name_pattern= queries against a # codebase-memory-mcp binary to measure the regex / LIKE pre-filter performance. # diff --git a/scripts/build.sh b/scripts/build.sh index a8c59e736..87bed215b 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # build.sh — Clean build of production binary (standard or with UI). # # Usage: diff --git a/scripts/check-nolint-whitelist.sh b/scripts/check-nolint-whitelist.sh index f2432bfe2..757a270fc 100755 --- a/scripts/check-nolint-whitelist.sh +++ b/scripts/check-nolint-whitelist.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Verify NOLINT(misc-no-recursion) only appears on whitelisted functions. WHITELIST="src/foundation/recursion_whitelist.h" if [ ! -f "$WHITELIST" ]; then diff --git a/scripts/clean.sh b/scripts/clean.sh index 662cf3aa8..ea9e15976 100755 --- a/scripts/clean.sh +++ b/scripts/clean.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # clean.sh — Remove ALL build artifacts, caches, and generated files. # # Usage: scripts/clean.sh diff --git a/scripts/embed-frontend.sh b/scripts/embed-frontend.sh index 908c39790..0b7b87309 100755 --- a/scripts/embed-frontend.sh +++ b/scripts/embed-frontend.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # embed-frontend.sh — Convert built frontend assets into linkable object files. # # Usage: scripts/embed-frontend.sh diff --git a/scripts/env.sh b/scripts/env.sh index df932b766..151cd1bf4 100755 --- a/scripts/env.sh +++ b/scripts/env.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # env.sh — Shared environment detection for all build scripts. # # Sourced by test.sh, build.sh, lint.sh. Not meant to run standalone. diff --git a/scripts/lint.sh b/scripts/lint.sh index 62c912b24..44cfed89d 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # lint.sh — Run all linters (clang-tidy + cppcheck + clang-format). # # Usage: diff --git a/scripts/repro.sh b/scripts/repro.sh index 299831302..898511e44 100755 --- a/scripts/repro.sh +++ b/scripts/repro.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # repro.sh — Build + run the cumulative BUG-REPRODUCTION suite (test-repro). # # Unlike test.sh (the gating suite, must be GREEN), this suite is RED by design: diff --git a/scripts/soak-test.sh b/scripts/soak-test.sh index 9429a2397..387527baa 100755 --- a/scripts/soak-test.sh +++ b/scripts/soak-test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # soak-test.sh — Endurance test for codebase-memory-mcp. # # Runs compressed workload cycles: queries, file mutations, reindexes, idle periods. diff --git a/scripts/test.sh b/scripts/test.sh index 62210b426..3892ae6d0 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # test.sh — Clean build + run all C tests with ASan + UBSan. # # Usage: diff --git a/scripts/vendor-grammar.sh b/scripts/vendor-grammar.sh index 83009f2ff..696f486e4 100755 --- a/scripts/vendor-grammar.sh +++ b/scripts/vendor-grammar.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # vendor-grammar.sh: Vendor a single tree-sitter grammar into internal/cbm/vendored/grammars// # Usage: ./scripts/vendor-grammar.sh [subdir] # repo_url: GitHub repository URL (e.g., https://github.com/tree-sitter/tree-sitter-json) diff --git a/src/cli/cli.c b/src/cli/cli.c index 6b32a8b51..c4b8bdb18 100644 --- a/src/cli/cli.c +++ b/src/cli/cli.c @@ -1933,7 +1933,7 @@ void cbm_install_hook_gate_script(const char *home, const char *binary_path) { return; } (void)fprintf(f, - "#!/bin/bash\n" + "#!/usr/bin/env bash\n" "# codebase-memory-mcp search augmenter (Claude Code PreToolUse).\n" "# NOTE: the legacy filename is kept for zero-migration upgrades.\n" "# Despite the name this NEVER blocks a tool call - it only adds\n" @@ -1977,7 +1977,7 @@ static void cbm_install_session_reminder_script(const char *home) { return; } (void)fprintf( - f, "#!/bin/bash\n" + f, "#!/usr/bin/env bash\n" "# SessionStart hook: remind agent to use codebase-memory-mcp tools.\n" "# Installed by codebase-memory-mcp. Fires on startup/resume/clear/compact.\n" "cat << 'REMINDER'\n" diff --git a/test-infrastructure/run.sh b/test-infrastructure/run.sh index 32b1826db..2786f2559 100755 --- a/test-infrastructure/run.sh +++ b/test-infrastructure/run.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Local CI — test all platforms before pushing. # # Coverage: diff --git a/tests/repro/repro_issue409.c b/tests/repro/repro_issue409.c index eb969df13..e73622a2e 100644 --- a/tests/repro/repro_issue409.c +++ b/tests/repro/repro_issue409.c @@ -154,7 +154,7 @@ TEST(repro_issue409_install_wires_hook_augment_not_blocking_gate) { snprintf(script_path, sizeof(script_path), "%s/cbm-code-discovery-gate", hooks_dir); rp409_write_file(script_path, - "#!/bin/bash\n" + "#!/usr/bin/env bash\n" "# Gate hook: nudges Claude toward codebase-memory-mcp for code discovery.\n" "# First Grep/Glob/Read per session -> block. Subsequent -> allow.\n" "# PPID = Claude Code process PID, unique per session.\n" diff --git a/tests/test_pipeline.c b/tests/test_pipeline.c index 3e7edf23c..4105ec34c 100644 --- a/tests/test_pipeline.c +++ b/tests/test_pipeline.c @@ -3707,7 +3707,7 @@ TEST(infra_parse_dotenv_quoted) { TEST(infra_parse_shell) { /* Port of TestParseShellScript */ - const char *src = "#!/bin/bash\n" + const char *src = "#!/usr/bin/env bash\n" "set -e\n" "\n" "# Configuration\n" @@ -3726,7 +3726,7 @@ TEST(infra_parse_shell) { cbm_shell_result_t r; ASSERT_EQ(cbm_parse_shell_source(src, &r), 0); - ASSERT_STR_EQ(r.shebang, "/bin/bash"); + ASSERT_STR_EQ(r.shebang, "/usr/bin/env bash"); ASSERT_STR_EQ(find_env_var(r.env_vars, r.env_count, "ENVIRONMENT"), "development"); ASSERT_STR_EQ(find_env_var(r.env_vars, r.env_count, "YOUR_CONTAINER_NAME"), @@ -3755,7 +3755,7 @@ TEST(infra_parse_shell_with_source) { TEST(infra_parse_shell_secret_filtered) { /* Port of TestParseShellScriptSecretFiltered */ - const char *src = "#!/bin/bash\n" + const char *src = "#!/usr/bin/env bash\n" "export API_SECRET=\"should-not-appear\"\n" "export DATABASE_URL=\"https://db.example.com\"\n"; @@ -3768,10 +3768,10 @@ TEST(infra_parse_shell_secret_filtered) { TEST(infra_parse_shell_shebang_only) { /* Port of TestParseShellScriptShebanOnly */ - const char *src = "#!/bin/bash\n# just comments\n"; + const char *src = "#!/usr/bin/env bash\n# just comments\n"; cbm_shell_result_t r; ASSERT_EQ(cbm_parse_shell_source(src, &r), 0); - ASSERT_STR_EQ(r.shebang, "/bin/bash"); + ASSERT_STR_EQ(r.shebang, "/usr/bin/env bash"); PASS(); } @@ -4493,7 +4493,7 @@ TEST(envscan_shell_env_urls) { FAIL("tmpdir"); write_temp_file(tmpdir, "setup.sh", - "#!/bin/bash\n" + "#!/usr/bin/env bash\n" "export DB_URL=\"https://db.example.com/api/sync\"\n" "APP_NAME=\"my-service\"\n" "CALLBACK_URL=https://hooks.example.com/notify\n"); @@ -4668,7 +4668,7 @@ TEST(envscan_secret_value_exclusion) { write_temp_file( tmpdir, "deploy.sh", - "#!/bin/bash\n" + "#!/usr/bin/env bash\n" "export GH_URL=\"https://ghp_abcdefghijklmnopqrstuvwxyz1234567890@github.com/repo\"\n" "export NORMAL_ENDPOINT=\"https://api.example.com/orders\"\n"); @@ -4692,10 +4692,10 @@ TEST(envscan_secret_file_exclusion) { /* Secret file should be skipped */ write_temp_file(tmpdir, "credentials.sh", - "#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n"); + "#!/usr/bin/env bash\nexport API_URL=\"https://api.example.com/v1\"\n"); /* Normal file should be scanned */ write_temp_file(tmpdir, "setup.sh", - "#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n"); + "#!/usr/bin/env bash\nexport API_URL=\"https://api.example.com/v1\"\n"); cbm_env_binding_t bindings[32]; int count = cbm_scan_project_env_urls(tmpdir, bindings, 32); @@ -4727,7 +4727,7 @@ TEST(envscan_skips_ignored_dirs) { snprintf(gitdir, sizeof(gitdir), "%s/.git", tmpdir); cbm_mkdir(gitdir); write_temp_file(tmpdir, ".git/config.sh", - "#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n"); + "#!/usr/bin/env bash\nexport API_URL=\"https://api.example.com/v1\"\n"); /* File inside node_modules should be skipped */ char nmdir[512]; @@ -4737,11 +4737,11 @@ TEST(envscan_skips_ignored_dirs) { snprintf(nmpkg, sizeof(nmpkg), "%s/node_modules/pkg", tmpdir); cbm_mkdir(nmpkg); write_temp_file(tmpdir, "node_modules/pkg/config.sh", - "#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n"); + "#!/usr/bin/env bash\nexport API_URL=\"https://api.example.com/v1\"\n"); /* File at root level should be scanned */ write_temp_file(tmpdir, "deploy.sh", - "#!/bin/bash\nexport API_URL=\"https://api.example.com/v1\"\n"); + "#!/usr/bin/env bash\nexport API_URL=\"https://api.example.com/v1\"\n"); cbm_env_binding_t bindings[32]; int count = cbm_scan_project_env_urls(tmpdir, bindings, 32); @@ -4776,7 +4776,7 @@ TEST(envscan_non_url_values_skipped) { "ENV DEBUG=true\n" "ENV LOG_LEVEL=info\n"); write_temp_file(tmpdir, "config.sh", - "#!/bin/bash\n" + "#!/usr/bin/env bash\n" "export REGION=\"us-east-1\"\n" "export COUNT=42\n");