mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Merge pull request #39 from AikidoSec/windows-cygwin-bash-support
Add support for Cygwin on windows
This commit is contained in:
commit
025f84407e
2 changed files with 105 additions and 2 deletions
|
|
@ -3,7 +3,8 @@ import {
|
||||||
doesExecutableExistOnSystem,
|
doesExecutableExistOnSystem,
|
||||||
removeLinesMatchingPattern,
|
removeLinesMatchingPattern,
|
||||||
} from "../helpers.js";
|
} from "../helpers.js";
|
||||||
import { execSync } from "child_process";
|
import { execSync, spawnSync } from "child_process";
|
||||||
|
import * as os from "os";
|
||||||
|
|
||||||
const shellName = "Bash";
|
const shellName = "Bash";
|
||||||
const executableName = "bash";
|
const executableName = "bash";
|
||||||
|
|
@ -43,10 +44,12 @@ function setup() {
|
||||||
|
|
||||||
function getStartupFile() {
|
function getStartupFile() {
|
||||||
try {
|
try {
|
||||||
return execSync(startupFileCommand, {
|
var path = execSync(startupFileCommand, {
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
shell: executableName,
|
shell: executableName,
|
||||||
}).trim();
|
}).trim();
|
||||||
|
|
||||||
|
return windowsFixPath(path);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
`Command failed: ${startupFileCommand}. Error: ${error.message}`
|
||||||
|
|
@ -54,6 +57,50 @@ function getStartupFile() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function windowsFixPath(path) {
|
||||||
|
try {
|
||||||
|
if (os.platform() !== "win32") {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On windows cygwin bash, paths are returned in format /c/user/..., but we need it in format C:\user\...
|
||||||
|
// To convert, the cygpath -w command can be used to convert to the desired format.
|
||||||
|
// Cygpath only exists on Cygwin, so we first check if the command is available.
|
||||||
|
// If it is, we use it to convert the path.
|
||||||
|
if (hasCygpath()) {
|
||||||
|
return cygpathw(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
} catch {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasCygpath() {
|
||||||
|
try {
|
||||||
|
var result = spawnSync("where", ["cygpath"], { shell: executableName });
|
||||||
|
return result.status === 0;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cygpathw(path) {
|
||||||
|
try {
|
||||||
|
var result = spawnSync("cygpath", ["-w", path], {
|
||||||
|
encoding: "utf8",
|
||||||
|
shell: executableName,
|
||||||
|
});
|
||||||
|
if (result.status === 0) {
|
||||||
|
return result.stdout.trim();
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
} catch {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: shellName,
|
name: shellName,
|
||||||
isInstalled,
|
isInstalled,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ import { knownAikidoTools } from "../helpers.js";
|
||||||
describe("Bash shell integration", () => {
|
describe("Bash shell integration", () => {
|
||||||
let mockStartupFile;
|
let mockStartupFile;
|
||||||
let bash;
|
let bash;
|
||||||
|
let windowsCygwinPath = "";
|
||||||
|
let platform = "linux";
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
// Create temporary startup file for testing
|
// Create temporary startup file for testing
|
||||||
|
|
@ -37,6 +39,35 @@ describe("Bash shell integration", () => {
|
||||||
mock.module("child_process", {
|
mock.module("child_process", {
|
||||||
namedExports: {
|
namedExports: {
|
||||||
execSync: () => mockStartupFile,
|
execSync: () => mockStartupFile,
|
||||||
|
spawnSync: (command, args) => {
|
||||||
|
if (platform !== "win32") {
|
||||||
|
return { status: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === "where" && args[0] === "cygpath") {
|
||||||
|
return {
|
||||||
|
status: 0,
|
||||||
|
stdout: Buffer.from("C:\\cygwin64\\bin\\cygpath.exe\n"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
command === "cygpath" &&
|
||||||
|
args[0] === "-w" &&
|
||||||
|
args[1] === mockStartupFile
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
status: 0,
|
||||||
|
stdout: windowsCygwinPath + "\n",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
mock.module("os", {
|
||||||
|
namedExports: {
|
||||||
|
platform: () => platform,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -49,9 +80,14 @@ describe("Bash shell integration", () => {
|
||||||
if (fs.existsSync(mockStartupFile)) {
|
if (fs.existsSync(mockStartupFile)) {
|
||||||
fs.unlinkSync(mockStartupFile);
|
fs.unlinkSync(mockStartupFile);
|
||||||
}
|
}
|
||||||
|
if (windowsCygwinPath && fs.existsSync(windowsCygwinPath)) {
|
||||||
|
fs.unlinkSync(windowsCygwinPath);
|
||||||
|
windowsCygwinPath = "";
|
||||||
|
}
|
||||||
|
|
||||||
// Reset mocks
|
// Reset mocks
|
||||||
mock.reset();
|
mock.reset();
|
||||||
|
platform = "linux";
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("isInstalled", () => {
|
describe("isInstalled", () => {
|
||||||
|
|
@ -77,6 +113,26 @@ describe("Bash shell integration", () => {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should use the correct startup file for cygwin bash on Windows", () => {
|
||||||
|
// Simulate Windows platform with Cygwin bash
|
||||||
|
// The mockStartupFile contains a path we cannot open, so we set it to something useless
|
||||||
|
// The cygpath -w command that is mocked, will return the windowsCygwinPath variable
|
||||||
|
// This simulates the conversion from /c/Users/... to C:\Users\...
|
||||||
|
platform = "win32";
|
||||||
|
windowsCygwinPath = mockStartupFile;
|
||||||
|
mockStartupFile = "DUMMY";
|
||||||
|
|
||||||
|
const result = bash.setup();
|
||||||
|
assert.strictEqual(result, true);
|
||||||
|
|
||||||
|
const content = fs.readFileSync(windowsCygwinPath, "utf-8");
|
||||||
|
assert.ok(
|
||||||
|
content.includes(
|
||||||
|
"source ~/.safe-chain/scripts/init-posix.sh # Safe-chain bash initialization script"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("teardown", () => {
|
describe("teardown", () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue