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,
|
||||
removeLinesMatchingPattern,
|
||||
} from "../helpers.js";
|
||||
import { execSync } from "child_process";
|
||||
import { execSync, spawnSync } from "child_process";
|
||||
import * as os from "os";
|
||||
|
||||
const shellName = "Bash";
|
||||
const executableName = "bash";
|
||||
|
|
@ -43,10 +44,12 @@ function setup() {
|
|||
|
||||
function getStartupFile() {
|
||||
try {
|
||||
return execSync(startupFileCommand, {
|
||||
var path = execSync(startupFileCommand, {
|
||||
encoding: "utf8",
|
||||
shell: executableName,
|
||||
}).trim();
|
||||
|
||||
return windowsFixPath(path);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
`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 {
|
||||
name: shellName,
|
||||
isInstalled,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ import { knownAikidoTools } from "../helpers.js";
|
|||
describe("Bash shell integration", () => {
|
||||
let mockStartupFile;
|
||||
let bash;
|
||||
let windowsCygwinPath = "";
|
||||
let platform = "linux";
|
||||
|
||||
beforeEach(async () => {
|
||||
// Create temporary startup file for testing
|
||||
|
|
@ -37,6 +39,35 @@ describe("Bash shell integration", () => {
|
|||
mock.module("child_process", {
|
||||
namedExports: {
|
||||
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)) {
|
||||
fs.unlinkSync(mockStartupFile);
|
||||
}
|
||||
if (windowsCygwinPath && fs.existsSync(windowsCygwinPath)) {
|
||||
fs.unlinkSync(windowsCygwinPath);
|
||||
windowsCygwinPath = "";
|
||||
}
|
||||
|
||||
// Reset mocks
|
||||
mock.reset();
|
||||
platform = "linux";
|
||||
});
|
||||
|
||||
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", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue