This commit is contained in:
Reinier Criel 2026-04-13 11:01:45 -07:00
parent 1cf8fd1241
commit d064d46668
32 changed files with 429 additions and 400 deletions

View file

@ -3,7 +3,6 @@ import {
doesExecutableExistOnSystem,
removeLinesMatchingPattern,
getScriptsDir,
getSafeChainDir,
} from "../helpers.js";
import { execSync, spawnSync } from "child_process";
import * as os from "os";
@ -54,15 +53,6 @@ function teardown(tools) {
function setup() {
const startupFile = getStartupFile();
const customDir = getSafeChainDir();
if (customDir) {
addLineToFile(
startupFile,
`export SAFE_CHAIN_DIR="${customDir}" # Safe-chain installation directory`,
eol
);
}
addLineToFile(
startupFile,
`source ${path.join(getScriptsDir(), "init-posix.sh")} # Safe-chain bash initialization script`,
@ -143,18 +133,7 @@ function cygpathw(path) {
/** @param {string} preamble */
function buildManualInstructions(preamble) {
const customDir = getSafeChainDir();
const instructions = [preamble];
if (customDir) {
instructions.push(
` export SAFE_CHAIN_DIR="${customDir}"`,
` source ${path.join(getScriptsDir(), "init-posix.sh")}`,
);
} else {
instructions.push(` source ~/.safe-chain/scripts/init-posix.sh`);
}
const instructions = [preamble, ` source ${path.join(getScriptsDir(), "init-posix.sh")}`];
instructions.push(`Then restart your terminal or run: source ~/.bashrc`);
return instructions;
}

View file

@ -10,7 +10,6 @@ describe("Bash shell integration", () => {
let bash;
let windowsCygwinPath = "";
let platform = "linux";
let getSafeChainDirResult = undefined;
beforeEach(async () => {
// Create temporary startup file for testing
@ -21,7 +20,6 @@ describe("Bash shell integration", () => {
namedExports: {
doesExecutableExistOnSystem: () => true,
getScriptsDir: () => "/test-home/.safe-chain/scripts",
getSafeChainDir: () => getSafeChainDirResult,
addLineToFile: (filePath, line) => {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, "", "utf-8");
@ -91,7 +89,6 @@ describe("Bash shell integration", () => {
// Reset mocks
mock.reset();
platform = "linux";
getSafeChainDirResult = undefined;
});
describe("isInstalled", () => {
@ -203,26 +200,18 @@ describe("Bash shell integration", () => {
});
});
describe("SAFE_CHAIN_DIR", () => {
it("should write export line to rc file when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
describe("custom install dir", () => {
it("writes only the source line to the rc file", () => {
bash.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes('export SAFE_CHAIN_DIR="/custom/safe-chain" # Safe-chain installation directory')
content.includes("source /test-home/.safe-chain/scripts/init-posix.sh")
);
});
it("should not write export line when no custom dir is set", () => {
getSafeChainDirResult = undefined;
bash.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should remove export line on teardown", () => {
it("removes legacy export lines on teardown", () => {
const initialContent = [
'#!/bin/bash',
'export SAFE_CHAIN_DIR="/custom/safe-chain" # Safe-chain installation directory',
@ -236,12 +225,9 @@ describe("Bash shell integration", () => {
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should show custom manual setup instructions when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
it("shows source-only manual setup instructions", () => {
assert.deepStrictEqual(bash.getManualSetupInstructions(), [
"Add the following line to your ~/.bashrc file:",
' export SAFE_CHAIN_DIR="/custom/safe-chain"',
" source /test-home/.safe-chain/scripts/init-posix.sh",
"Then restart your terminal or run: source ~/.bashrc",
]);

View file

@ -3,7 +3,6 @@ import {
doesExecutableExistOnSystem,
removeLinesMatchingPattern,
getScriptsDir,
getSafeChainDir,
} from "../helpers.js";
import { execSync } from "child_process";
import path from "path";
@ -53,15 +52,6 @@ function teardown(tools) {
function setup() {
const startupFile = getStartupFile();
const customDir = getSafeChainDir();
if (customDir) {
addLineToFile(
startupFile,
`set -gx SAFE_CHAIN_DIR "${customDir}" # Safe-chain installation directory`,
eol
);
}
addLineToFile(
startupFile,
`source ${path.join(getScriptsDir(), "init-fish.fish")} # Safe-chain Fish initialization script`,
@ -86,18 +76,7 @@ function getStartupFile() {
/** @param {string} preamble */
function buildManualInstructions(preamble) {
const customDir = getSafeChainDir();
const instructions = [preamble];
if (customDir) {
instructions.push(
` set -gx SAFE_CHAIN_DIR "${customDir}"`,
` source ${path.join(getScriptsDir(), "init-fish.fish")}`,
);
} else {
instructions.push(` source ~/.safe-chain/scripts/init-fish.fish`);
}
const instructions = [preamble, ` source ${path.join(getScriptsDir(), "init-fish.fish")}`];
instructions.push(
`Then restart your terminal or run: source ~/.config/fish/config.fish`,
);

View file

@ -8,7 +8,6 @@ import { knownAikidoTools } from "../helpers.js";
describe("Fish shell integration", () => {
let mockStartupFile;
let fish;
let getSafeChainDirResult = undefined;
beforeEach(async () => {
// Create temporary startup file for testing
@ -19,7 +18,6 @@ describe("Fish shell integration", () => {
namedExports: {
doesExecutableExistOnSystem: () => true,
getScriptsDir: () => "/test-home/.safe-chain/scripts",
getSafeChainDir: () => getSafeChainDirResult,
addLineToFile: (filePath, line) => {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, "", "utf-8");
@ -55,7 +53,6 @@ describe("Fish shell integration", () => {
// Reset mocks
mock.reset();
getSafeChainDirResult = undefined;
});
describe("isInstalled", () => {
@ -156,26 +153,18 @@ describe("Fish shell integration", () => {
});
});
describe("SAFE_CHAIN_DIR", () => {
it("should write set line to config file when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
describe("custom install dir", () => {
it("writes only the source line to the config file", () => {
fish.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes('set -gx SAFE_CHAIN_DIR "/custom/safe-chain" # Safe-chain installation directory')
content.includes("source /test-home/.safe-chain/scripts/init-fish.fish")
);
});
it("should not write set line when no custom dir is set", () => {
getSafeChainDirResult = undefined;
fish.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should remove set line on teardown", () => {
it("removes legacy set lines on teardown", () => {
const initialContent = [
'set -gx SAFE_CHAIN_DIR "/custom/safe-chain" # Safe-chain installation directory',
"source /test-home/.safe-chain/scripts/init-fish.fish # Safe-chain Fish initialization script",
@ -188,12 +177,9 @@ describe("Fish shell integration", () => {
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should show custom manual setup instructions when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
it("shows source-only manual setup instructions", () => {
assert.deepStrictEqual(fish.getManualSetupInstructions(), [
"Add the following line to your ~/.config/fish/config.fish file:",
' set -gx SAFE_CHAIN_DIR "/custom/safe-chain"',
" source /test-home/.safe-chain/scripts/init-fish.fish",
"Then restart your terminal or run: source ~/.config/fish/config.fish",
]);

View file

@ -4,7 +4,6 @@ import {
removeLinesMatchingPattern,
validatePowerShellExecutionPolicy,
getScriptsDir,
getSafeChainDir,
} from "../helpers.js";
import { execSync } from "child_process";
import path from "path";
@ -58,14 +57,6 @@ async function setup() {
const startupFile = getStartupFile();
const customDir = getSafeChainDir();
if (customDir) {
addLineToFile(
startupFile,
`$env:SAFE_CHAIN_DIR = '${customDir}' # Safe-chain installation directory`,
);
}
addLineToFile(
startupFile,
`. "${path.join(getScriptsDir(), "init-pwsh.ps1")}" # Safe-chain PowerShell initialization script`,
@ -89,18 +80,7 @@ function getStartupFile() {
/** @param {string} preamble */
function buildManualInstructions(preamble) {
const customDir = getSafeChainDir();
const instructions = [preamble];
if (customDir) {
instructions.push(
` $env:SAFE_CHAIN_DIR = '${customDir}'`,
` . "${path.join(getScriptsDir(), "init-pwsh.ps1")}"`,
);
} else {
instructions.push(` . "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"`);
}
const instructions = [preamble, ` . "${path.join(getScriptsDir(), "init-pwsh.ps1")}"`];
instructions.push(`Then restart your terminal or run: . $PROFILE`);
return instructions;
}

View file

@ -9,7 +9,6 @@ describe("PowerShell Core shell integration", () => {
let mockStartupFile;
let powershell;
let executionPolicyResult;
let getSafeChainDirResult = undefined;
beforeEach(async () => {
// Create temporary startup file for testing
@ -27,7 +26,6 @@ describe("PowerShell Core shell integration", () => {
mock.module("../helpers.js", {
namedExports: {
doesExecutableExistOnSystem: () => true,
getSafeChainDir: () => getSafeChainDirResult,
addLineToFile: (filePath, line) => {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, "", "utf-8");
@ -65,7 +63,6 @@ describe("PowerShell Core shell integration", () => {
// Reset mocks
mock.reset();
getSafeChainDirResult = undefined;
});
describe("isInstalled", () => {
@ -209,26 +206,18 @@ describe("PowerShell Core shell integration", () => {
});
});
describe("SAFE_CHAIN_DIR", () => {
it("should write $env:SAFE_CHAIN_DIR line to profile when custom dir is set", async () => {
getSafeChainDirResult = "C:\\custom\\safe-chain";
describe("custom install dir", () => {
it("writes only the source line to the profile", async () => {
await powershell.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes("$env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain' # Safe-chain installation directory")
content.includes('. "/test-home/.safe-chain/scripts/init-pwsh.ps1"')
);
});
it("should not write $env:SAFE_CHAIN_DIR line when no custom dir is set", async () => {
getSafeChainDirResult = undefined;
await powershell.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should remove $env:SAFE_CHAIN_DIR line on teardown", () => {
it("removes legacy env lines on teardown", () => {
const initialContent = [
"# PowerShell profile",
"$env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain' # Safe-chain installation directory",
@ -242,12 +231,9 @@ describe("PowerShell Core shell integration", () => {
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should show custom manual setup instructions when custom dir is set", () => {
getSafeChainDirResult = "C:\\custom\\safe-chain";
it("shows source-only manual setup instructions", () => {
assert.deepStrictEqual(powershell.getManualSetupInstructions(), [
'Add the following line to your PowerShell profile (run "echo $PROFILE" to find its location):',
" $env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain'",
' . "/test-home/.safe-chain/scripts/init-pwsh.ps1"',
"Then restart your terminal or run: . $PROFILE",
]);

View file

@ -4,7 +4,6 @@ import {
removeLinesMatchingPattern,
validatePowerShellExecutionPolicy,
getScriptsDir,
getSafeChainDir,
} from "../helpers.js";
import { execSync } from "child_process";
import path from "path";
@ -58,14 +57,6 @@ async function setup() {
const startupFile = getStartupFile();
const customDir = getSafeChainDir();
if (customDir) {
addLineToFile(
startupFile,
`$env:SAFE_CHAIN_DIR = '${customDir}' # Safe-chain installation directory`,
);
}
addLineToFile(
startupFile,
`. "${path.join(getScriptsDir(), "init-pwsh.ps1")}" # Safe-chain PowerShell initialization script`,
@ -89,18 +80,7 @@ function getStartupFile() {
/** @param {string} preamble */
function buildManualInstructions(preamble) {
const customDir = getSafeChainDir();
const instructions = [preamble];
if (customDir) {
instructions.push(
` $env:SAFE_CHAIN_DIR = '${customDir}'`,
` . "${path.join(getScriptsDir(), "init-pwsh.ps1")}"`,
);
} else {
instructions.push(` . "$HOME\\.safe-chain\\scripts\\init-pwsh.ps1"`);
}
const instructions = [preamble, ` . "${path.join(getScriptsDir(), "init-pwsh.ps1")}"`];
instructions.push(`Then restart your terminal or run: . $PROFILE`);
return instructions;
}

View file

@ -9,7 +9,6 @@ describe("Windows PowerShell shell integration", () => {
let mockStartupFile;
let windowsPowershell;
let executionPolicyResult;
let getSafeChainDirResult = undefined;
beforeEach(async () => {
// Create temporary startup file for testing
@ -27,7 +26,6 @@ describe("Windows PowerShell shell integration", () => {
mock.module("../helpers.js", {
namedExports: {
doesExecutableExistOnSystem: () => true,
getSafeChainDir: () => getSafeChainDirResult,
addLineToFile: (filePath, line) => {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, "", "utf-8");
@ -65,7 +63,6 @@ describe("Windows PowerShell shell integration", () => {
// Reset mocks
mock.reset();
getSafeChainDirResult = undefined;
});
describe("isInstalled", () => {
@ -209,26 +206,18 @@ describe("Windows PowerShell shell integration", () => {
});
});
describe("SAFE_CHAIN_DIR", () => {
it("should write $env:SAFE_CHAIN_DIR line to profile when custom dir is set", async () => {
getSafeChainDirResult = "C:\\custom\\safe-chain";
describe("custom install dir", () => {
it("writes only the source line to the profile", async () => {
await windowsPowershell.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes("$env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain' # Safe-chain installation directory")
content.includes('. "/test-home/.safe-chain/scripts/init-pwsh.ps1"')
);
});
it("should not write $env:SAFE_CHAIN_DIR line when no custom dir is set", async () => {
getSafeChainDirResult = undefined;
await windowsPowershell.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should remove $env:SAFE_CHAIN_DIR line on teardown", () => {
it("removes legacy env lines on teardown", () => {
const initialContent = [
"# Windows PowerShell profile",
"$env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain' # Safe-chain installation directory",
@ -242,12 +231,9 @@ describe("Windows PowerShell shell integration", () => {
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should show custom manual teardown instructions when custom dir is set", () => {
getSafeChainDirResult = "C:\\custom\\safe-chain";
it("shows source-only manual teardown instructions", () => {
assert.deepStrictEqual(windowsPowershell.getManualTeardownInstructions(), [
'Remove the following line from your PowerShell profile (run "echo $PROFILE" to find its location):',
" $env:SAFE_CHAIN_DIR = 'C:\\custom\\safe-chain'",
' . "/test-home/.safe-chain/scripts/init-pwsh.ps1"',
"Then restart your terminal or run: . $PROFILE",
]);

View file

@ -3,7 +3,6 @@ import {
doesExecutableExistOnSystem,
removeLinesMatchingPattern,
getScriptsDir,
getSafeChainDir,
} from "../helpers.js";
import { execSync } from "child_process";
import path from "path";
@ -53,15 +52,6 @@ function teardown(tools) {
function setup() {
const startupFile = getStartupFile();
const customDir = getSafeChainDir();
if (customDir) {
addLineToFile(
startupFile,
`export SAFE_CHAIN_DIR="${customDir}" # Safe-chain installation directory`,
eol
);
}
addLineToFile(
startupFile,
`source ${path.join(getScriptsDir(), "init-posix.sh")} # Safe-chain Zsh initialization script`,
@ -86,18 +76,7 @@ function getStartupFile() {
/** @param {string} preamble */
function buildManualInstructions(preamble) {
const customDir = getSafeChainDir();
const instructions = [preamble];
if (customDir) {
instructions.push(
` export SAFE_CHAIN_DIR="${customDir}"`,
` source ${path.join(getScriptsDir(), "init-posix.sh")}`,
);
} else {
instructions.push(` source ~/.safe-chain/scripts/init-posix.sh`);
}
const instructions = [preamble, ` source ${path.join(getScriptsDir(), "init-posix.sh")}`];
instructions.push(`Then restart your terminal or run: source ~/.zshrc`);
return instructions;
}

View file

@ -8,7 +8,6 @@ import { knownAikidoTools } from "../helpers.js";
describe("Zsh shell integration", () => {
let mockStartupFile;
let zsh;
let getSafeChainDirResult = undefined;
beforeEach(async () => {
// Create temporary startup file for testing
@ -19,7 +18,6 @@ describe("Zsh shell integration", () => {
namedExports: {
doesExecutableExistOnSystem: () => true,
getScriptsDir: () => "/test-home/.safe-chain/scripts",
getSafeChainDir: () => getSafeChainDirResult,
addLineToFile: (filePath, line) => {
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, "", "utf-8");
@ -55,7 +53,6 @@ describe("Zsh shell integration", () => {
// Reset mocks
mock.reset();
getSafeChainDirResult = undefined;
});
describe("isInstalled", () => {
@ -174,26 +171,18 @@ describe("Zsh shell integration", () => {
});
});
describe("SAFE_CHAIN_DIR", () => {
it("should write export line to rc file when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
describe("custom install dir", () => {
it("writes only the source line to the rc file", () => {
zsh.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(
content.includes('export SAFE_CHAIN_DIR="/custom/safe-chain" # Safe-chain installation directory')
content.includes("source /test-home/.safe-chain/scripts/init-posix.sh")
);
});
it("should not write export line when no custom dir is set", () => {
getSafeChainDirResult = undefined;
zsh.setup();
const content = fs.readFileSync(mockStartupFile, "utf-8");
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should remove export line on teardown", () => {
it("removes legacy export lines on teardown", () => {
const initialContent = [
"#!/bin/zsh",
'export SAFE_CHAIN_DIR="/custom/safe-chain" # Safe-chain installation directory',
@ -207,12 +196,9 @@ describe("Zsh shell integration", () => {
assert.ok(!content.includes("SAFE_CHAIN_DIR"));
});
it("should show custom manual teardown instructions when custom dir is set", () => {
getSafeChainDirResult = "/custom/safe-chain";
it("shows source-only manual teardown instructions", () => {
assert.deepStrictEqual(zsh.getManualTeardownInstructions(), [
"Remove the following line from your ~/.zshrc file:",
' export SAFE_CHAIN_DIR="/custom/safe-chain"',
" source /test-home/.safe-chain/scripts/init-posix.sh",
"Then restart your terminal or run: source ~/.zshrc",
]);