mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 20:20:49 +00:00
Merge pull request #178 from AikidoSec/feature/poetry-2
Add Poetry support
This commit is contained in:
commit
15cc6ff7fe
19 changed files with 670 additions and 35 deletions
|
|
@ -11,6 +11,7 @@ import {
|
|||
import { createYarnPackageManager } from "./yarn/createPackageManager.js";
|
||||
import { createPipPackageManager } from "./pip/createPackageManager.js";
|
||||
import { createUvPackageManager } from "./uv/createUvPackageManager.js";
|
||||
import { createPoetryPackageManager } from "./poetry/createPoetryPackageManager.js";
|
||||
|
||||
/**
|
||||
* @type {{packageManagerName: PackageManager | null}}
|
||||
|
|
@ -58,6 +59,8 @@ export function initializePackageManager(packageManagerName, context) {
|
|||
state.packageManagerName = createPipPackageManager(context);
|
||||
} else if (packageManagerName === "uv") {
|
||||
state.packageManagerName = createUvPackageManager();
|
||||
} else if (packageManagerName === "poetry") {
|
||||
state.packageManagerName = createPoetryPackageManager();
|
||||
} else {
|
||||
throw new Error("Unsupported package manager: " + packageManagerName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
import { ui } from "../../environment/userInteraction.js";
|
||||
import { safeSpawn } from "../../utils/safeSpawn.js";
|
||||
import { mergeSafeChainProxyEnvironmentVariables } from "../../registryProxy/registryProxy.js";
|
||||
import { getCombinedCaBundlePath } from "../../registryProxy/certBundle.js";
|
||||
|
||||
/**
|
||||
* @returns {import("../currentPackageManager.js").PackageManager}
|
||||
*/
|
||||
export function createPoetryPackageManager() {
|
||||
return {
|
||||
runCommand: (args) => runPoetryCommand(args),
|
||||
|
||||
// MITM only approach for Poetry
|
||||
isSupportedCommand: () => false,
|
||||
getDependencyUpdatesForCommand: () => [],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets CA bundle environment variables used by Poetry and Python libraries.
|
||||
* Poetry uses the Python requests library which respects these environment variables.
|
||||
*
|
||||
* @param {NodeJS.ProcessEnv} env - Environment object to modify
|
||||
* @param {string} combinedCaPath - Path to the combined CA bundle
|
||||
*/
|
||||
function setPoetryCaBundleEnvironmentVariables(env, combinedCaPath) {
|
||||
// SSL_CERT_FILE: Used by Python SSL libraries and requests
|
||||
if (env.SSL_CERT_FILE) {
|
||||
ui.writeWarning("Safe-chain: User defined SSL_CERT_FILE found in environment. It will be overwritten.");
|
||||
}
|
||||
env.SSL_CERT_FILE = combinedCaPath;
|
||||
|
||||
// REQUESTS_CA_BUNDLE: Used by the requests library (which Poetry uses)
|
||||
if (env.REQUESTS_CA_BUNDLE) {
|
||||
ui.writeWarning("Safe-chain: User defined REQUESTS_CA_BUNDLE found in environment. It will be overwritten.");
|
||||
}
|
||||
env.REQUESTS_CA_BUNDLE = combinedCaPath;
|
||||
|
||||
// PIP_CERT: Poetry may use pip internally
|
||||
if (env.PIP_CERT) {
|
||||
ui.writeWarning("Safe-chain: User defined PIP_CERT found in environment. It will be overwritten.");
|
||||
}
|
||||
env.PIP_CERT = combinedCaPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a poetry command with safe-chain's certificate bundle and proxy configuration.
|
||||
*
|
||||
* Poetry respects standard HTTP_PROXY/HTTPS_PROXY environment variables through
|
||||
* the Python requests library.
|
||||
*
|
||||
* @param {string[]} args - Command line arguments to pass to poetry
|
||||
* @returns {Promise<{status: number}>} Exit status of the poetry command
|
||||
*/
|
||||
async function runPoetryCommand(args) {
|
||||
try {
|
||||
const env = mergeSafeChainProxyEnvironmentVariables(process.env);
|
||||
|
||||
const combinedCaPath = getCombinedCaBundlePath();
|
||||
setPoetryCaBundleEnvironmentVariables(env, combinedCaPath);
|
||||
|
||||
const result = await safeSpawn("poetry", args, {
|
||||
stdio: "inherit",
|
||||
env,
|
||||
});
|
||||
|
||||
return { status: result.status };
|
||||
} catch (/** @type any */ error) {
|
||||
if (error.status) {
|
||||
return { status: error.status };
|
||||
} else {
|
||||
ui.writeError("Error executing command:", error.message);
|
||||
ui.writeError("Is 'poetry' installed and available on your system?");
|
||||
return { status: 1 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import { test } from "node:test";
|
||||
import assert from "node:assert";
|
||||
import { createPoetryPackageManager } from "./createPoetryPackageManager.js";
|
||||
|
||||
test("createPoetryPackageManager", async (t) => {
|
||||
await t.test("should create package manager with required interface", () => {
|
||||
const pm = createPoetryPackageManager();
|
||||
|
||||
assert.ok(pm);
|
||||
assert.strictEqual(typeof pm.runCommand, "function");
|
||||
assert.strictEqual(typeof pm.isSupportedCommand, "function");
|
||||
assert.strictEqual(typeof pm.getDependencyUpdatesForCommand, "function");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue