mirror of
https://github.com/astral-sh/setup-uv.git
synced 2026-09-04 06:39:22 +00:00
Simplify Python runtime probing and tests
This commit is contained in:
@@ -1,33 +1,29 @@
|
|||||||
import * as path from "node:path";
|
import { join } from "node:path";
|
||||||
import type * as exec from "@actions/exec";
|
import { promisify } from "node:util";
|
||||||
import {
|
import { afterEach, beforeEach, expect, it, jest } from "@jest/globals";
|
||||||
afterEach,
|
|
||||||
beforeEach,
|
|
||||||
describe,
|
|
||||||
expect,
|
|
||||||
it,
|
|
||||||
jest,
|
|
||||||
} from "@jest/globals";
|
|
||||||
import { createSetupInputs } from "../helpers/setup-inputs";
|
import { createSetupInputs } from "../helpers/setup-inputs";
|
||||||
|
|
||||||
const mockGetExecOutput = jest.fn<typeof exec.getExecOutput>();
|
const mockExecFile =
|
||||||
|
jest.fn<
|
||||||
|
(...args: unknown[]) => Promise<{ stdout: string; stderr: string }>
|
||||||
|
>();
|
||||||
const mockDebug = jest.fn();
|
const mockDebug = jest.fn();
|
||||||
const originalPlatform = process.platform;
|
const originalPlatform = process.platform;
|
||||||
|
const inputs = createSetupInputs({
|
||||||
|
activateEnvironment: true,
|
||||||
|
pythonVersion: "3.15t",
|
||||||
|
});
|
||||||
|
|
||||||
jest.unstable_mockModule("@actions/core", () => ({
|
jest.unstable_mockModule("@actions/core", () => ({ debug: mockDebug }));
|
||||||
debug: mockDebug,
|
jest.unstable_mockModule("node:child_process", () => ({
|
||||||
isDebug: jest.fn(() => false),
|
// execFile's custom promisifier returns both stdout and stderr.
|
||||||
}));
|
execFile: Object.assign(mockExecFile, { [promisify.custom]: mockExecFile }),
|
||||||
|
|
||||||
jest.unstable_mockModule("@actions/exec", () => ({
|
|
||||||
getExecOutput: mockGetExecOutput,
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const { getPythonRuntimeId } = await import("../../src/utils/python-runtime");
|
const { getPythonRuntimeId } = await import("../../src/utils/python-runtime");
|
||||||
|
|
||||||
function mockRuntime(overrides: Record<string, unknown> = {}) {
|
function mockRuntime(overrides: Record<string, unknown> = {}) {
|
||||||
mockGetExecOutput.mockResolvedValue({
|
mockExecFile.mockResolvedValue({
|
||||||
exitCode: 0,
|
|
||||||
stderr: "",
|
stderr: "",
|
||||||
stdout: `${JSON.stringify({
|
stdout: `${JSON.stringify({
|
||||||
freethreaded: false,
|
freethreaded: false,
|
||||||
@@ -40,171 +36,76 @@ function mockRuntime(overrides: Record<string, unknown> = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mockGetExecOutput.mockReset();
|
mockExecFile.mockReset();
|
||||||
mockRuntime();
|
mockRuntime();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
Object.defineProperty(process, "platform", { value: originalPlatform });
|
Object.defineProperty(process, "platform", { value: originalPlatform });
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getPythonRuntimeId", () => {
|
it("does not query Python without environment activation", async () => {
|
||||||
it("does not query Python when environment activation is disabled", async () => {
|
expect(
|
||||||
const inputs = createSetupInputs({ pythonVersion: "3.15t" });
|
await getPythonRuntimeId({ ...inputs, activateEnvironment: false }),
|
||||||
|
).toBe("");
|
||||||
|
expect(mockExecFile).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
expect(await getPythonRuntimeId(inputs)).toBe("");
|
it.each([
|
||||||
expect(mockGetExecOutput).not.toHaveBeenCalled();
|
["3.13.1", false, "cpython-3.13.1"],
|
||||||
|
["3.15.0a1", false, "cpython-3.15.0a1"],
|
||||||
|
["3.15.0b2", false, "cpython-3.15.0b2"],
|
||||||
|
["3.15.0rc1", false, "cpython-3.15.0rc1"],
|
||||||
|
["3.15.0rc1", true, "cpython-3.15.0rc1-freethreaded"],
|
||||||
|
["3.15.0rc2", true, "cpython-3.15.0rc2-freethreaded"],
|
||||||
|
["3.15.0", true, "cpython-3.15.0-freethreaded"],
|
||||||
|
])("formats CPython %s, free-threading=%s", async (version, free, expected) => {
|
||||||
|
mockRuntime({ freethreaded: free, pythonVersion: version });
|
||||||
|
expect(await getPythonRuntimeId(inputs)).toBe(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
["pypy", [7, 3, 23, "final", 0], "pypy-7.3.23"],
|
||||||
|
["pypy", [7, 3, 24, "final", 0], "pypy-7.3.24"],
|
||||||
|
["pypy", [7, 3, 24, "alpha", 1], "pypy-7.3.24a1"],
|
||||||
|
["pypy", [7, 3, 24, "beta", 2], "pypy-7.3.24b2"],
|
||||||
|
["pypy", [7, 3, 24, "candidate", 3], "pypy-7.3.24rc3"],
|
||||||
|
["graalpy", [25, 0, 0, "final", 0], "graalpy-25.0.0"],
|
||||||
|
["pypy", [7, 3, 24, "unknown", 0], ""],
|
||||||
|
])("formats %s implementation version %j", async (name, version, expected) => {
|
||||||
|
mockRuntime({
|
||||||
|
implementation: name,
|
||||||
|
implementationVersion: version,
|
||||||
|
pythonVersion: "3.11.15",
|
||||||
});
|
});
|
||||||
|
expect(await getPythonRuntimeId(inputs)).toBe(
|
||||||
it("identifies the resolved CPython version rather than the request", async () => {
|
expected ? `${expected}-python-3.11.15` : "",
|
||||||
const inputs = createSetupInputs({
|
|
||||||
activateEnvironment: true,
|
|
||||||
pythonVersion: "3.13",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(await getPythonRuntimeId(inputs)).toBe("cpython-3.13.1");
|
|
||||||
expect(inputs.pythonVersion).toBe("3.13");
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
|
||||||
["3.15.0a1", false, "cpython-3.15.0a1"],
|
|
||||||
["3.15.0b2", false, "cpython-3.15.0b2"],
|
|
||||||
["3.15.0rc1", false, "cpython-3.15.0rc1"],
|
|
||||||
["3.15.0rc1", true, "cpython-3.15.0rc1-freethreaded"],
|
|
||||||
["3.15.0rc2", true, "cpython-3.15.0rc2-freethreaded"],
|
|
||||||
["3.15.0", true, "cpython-3.15.0-freethreaded"],
|
|
||||||
])(
|
|
||||||
"preserves version %s and free-threading=%s as %s",
|
|
||||||
async (pythonVersion, freethreaded, expected) => {
|
|
||||||
mockRuntime({ freethreaded, pythonVersion });
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe(expected);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
it("derives free-threading from the interpreter rather than the input", async () => {
|
|
||||||
const inputs = createSetupInputs({
|
|
||||||
activateEnvironment: true,
|
|
||||||
pythonVersion: "3.13.1t",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(await getPythonRuntimeId(inputs)).toBe("cpython-3.13.1");
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
|
||||||
[[7, 3, 23, "final", 0], "pypy-7.3.23-python-3.11.15"],
|
|
||||||
[[7, 3, 24, "final", 0], "pypy-7.3.24-python-3.11.15"],
|
|
||||||
[[7, 3, 24, "alpha", 1], "pypy-7.3.24a1-python-3.11.15"],
|
|
||||||
[[7, 3, 24, "beta", 2], "pypy-7.3.24b2-python-3.11.15"],
|
|
||||||
[[7, 3, 24, "candidate", 3], "pypy-7.3.24rc3-python-3.11.15"],
|
|
||||||
])("includes PyPy implementation version %j", async (version, expected) => {
|
|
||||||
mockRuntime({
|
|
||||||
implementation: "pypy",
|
|
||||||
implementationVersion: version,
|
|
||||||
pythonVersion: "3.11.15",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe(expected);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("includes the name and version of other Python implementations", async () => {
|
|
||||||
mockRuntime({
|
|
||||||
implementation: "graalpy",
|
|
||||||
implementationVersion: [25, 0, 0, "final", 0],
|
|
||||||
pythonVersion: "3.12.8",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe("graalpy-25.0.0-python-3.12.8");
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each(["linux", "darwin", "win32"])(
|
|
||||||
"queries the custom venv directly on %s, including paths with spaces",
|
|
||||||
async (platform) => {
|
|
||||||
Object.defineProperty(process, "platform", { value: platform });
|
|
||||||
const inputs = createSetupInputs({
|
|
||||||
activateEnvironment: true,
|
|
||||||
venvPath: "/runner temp/custom venv",
|
|
||||||
workingDirectory: "/different/project",
|
|
||||||
});
|
|
||||||
|
|
||||||
await getPythonRuntimeId(inputs);
|
|
||||||
|
|
||||||
const pythonPath =
|
|
||||||
platform === "win32"
|
|
||||||
? path.join(inputs.venvPath, "Scripts", "python.exe")
|
|
||||||
: path.join(inputs.venvPath, "bin", "python");
|
|
||||||
expect(mockGetExecOutput).toHaveBeenCalledWith(
|
|
||||||
`"${pythonPath}"`,
|
|
||||||
["-I", "-c", expect.any(String)],
|
|
||||||
{ silent: true },
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
it("escapes quotes in the venv path for @actions/exec", async () => {
|
|
||||||
Object.defineProperty(process, "platform", { value: "linux" });
|
|
||||||
const inputs = createSetupInputs({
|
|
||||||
activateEnvironment: true,
|
|
||||||
venvPath: '/workspace/a "quoted" venv',
|
|
||||||
});
|
|
||||||
|
|
||||||
await getPythonRuntimeId(inputs);
|
|
||||||
|
|
||||||
expect(mockGetExecOutput.mock.calls[0][0]).toContain('a \\"quoted\\" venv');
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each(["", "not JSON", "null", "{}"])(
|
|
||||||
"returns an empty output for invalid interpreter output: %j",
|
|
||||||
async (stdout) => {
|
|
||||||
mockGetExecOutput.mockResolvedValue({ exitCode: 0, stderr: "", stdout });
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe("");
|
|
||||||
expect(mockDebug).toHaveBeenCalled();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
it("returns an empty output for an invalid implementation version", async () => {
|
|
||||||
mockRuntime({
|
|
||||||
implementation: "pypy",
|
|
||||||
implementationVersion: [7, 3, 24, "unknown", 0],
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe("");
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([new Error("interpreter missing"), "interpreter failed"])(
|
|
||||||
"returns an empty output if the interpreter cannot be queried: %s",
|
|
||||||
async (error) => {
|
|
||||||
mockGetExecOutput.mockRejectedValue(error);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
await getPythonRuntimeId(
|
|
||||||
createSetupInputs({ activateEnvironment: true }),
|
|
||||||
),
|
|
||||||
).toBe("");
|
|
||||||
expect(mockDebug).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining(error instanceof Error ? error.message : error),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
["linux", 'a "quoted" venv', "bin/python"],
|
||||||
|
["darwin", "custom venv", "bin/python"],
|
||||||
|
["win32", "custom venv", "Scripts/python.exe"],
|
||||||
|
])("passes the venv executable directly on %s", async (platform, name, exe) => {
|
||||||
|
Object.defineProperty(process, "platform", { value: platform });
|
||||||
|
const venvPath = join("/runner temp", name);
|
||||||
|
await getPythonRuntimeId({ ...inputs, venvPath });
|
||||||
|
expect(mockExecFile).toHaveBeenCalledWith(
|
||||||
|
join(venvPath, exe),
|
||||||
|
["-I", "-c", expect.any(String)],
|
||||||
|
{ encoding: "utf8" },
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([new Error("interpreter missing"), "", "not JSON", "null", "{}"])(
|
||||||
|
"returns an empty ID for interpreter failure: %s",
|
||||||
|
async (result) => {
|
||||||
|
if (result instanceof Error) {
|
||||||
|
mockExecFile.mockRejectedValue(result);
|
||||||
|
} else {
|
||||||
|
mockExecFile.mockResolvedValue({ stderr: "", stdout: result });
|
||||||
|
}
|
||||||
|
expect(await getPythonRuntimeId(inputs)).toBe("");
|
||||||
|
expect(mockDebug).toHaveBeenCalled();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|||||||
+17
-49
@@ -10833,7 +10833,7 @@ var require_mock_interceptor = __commonJS({
|
|||||||
var require_mock_client = __commonJS({
|
var require_mock_client = __commonJS({
|
||||||
"node_modules/@actions/http-client/node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
|
"node_modules/@actions/http-client/node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var { promisify: promisify5 } = require("node:util");
|
var { promisify: promisify6 } = require("node:util");
|
||||||
var Client = require_client();
|
var Client = require_client();
|
||||||
var { buildMockDispatch } = require_mock_utils();
|
var { buildMockDispatch } = require_mock_utils();
|
||||||
var {
|
var {
|
||||||
@@ -10873,7 +10873,7 @@ var require_mock_client = __commonJS({
|
|||||||
return new MockInterceptor(opts, this[kDispatches]);
|
return new MockInterceptor(opts, this[kDispatches]);
|
||||||
}
|
}
|
||||||
async [kClose]() {
|
async [kClose]() {
|
||||||
await promisify5(this[kOriginalClose])();
|
await promisify6(this[kOriginalClose])();
|
||||||
this[kConnected] = 0;
|
this[kConnected] = 0;
|
||||||
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
||||||
}
|
}
|
||||||
@@ -10886,7 +10886,7 @@ var require_mock_client = __commonJS({
|
|||||||
var require_mock_pool = __commonJS({
|
var require_mock_pool = __commonJS({
|
||||||
"node_modules/@actions/http-client/node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
|
"node_modules/@actions/http-client/node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var { promisify: promisify5 } = require("node:util");
|
var { promisify: promisify6 } = require("node:util");
|
||||||
var Pool = require_pool();
|
var Pool = require_pool();
|
||||||
var { buildMockDispatch } = require_mock_utils();
|
var { buildMockDispatch } = require_mock_utils();
|
||||||
var {
|
var {
|
||||||
@@ -10926,7 +10926,7 @@ var require_mock_pool = __commonJS({
|
|||||||
return new MockInterceptor(opts, this[kDispatches]);
|
return new MockInterceptor(opts, this[kDispatches]);
|
||||||
}
|
}
|
||||||
async [kClose]() {
|
async [kClose]() {
|
||||||
await promisify5(this[kOriginalClose])();
|
await promisify6(this[kOriginalClose])();
|
||||||
this[kConnected] = 0;
|
this[kConnected] = 0;
|
||||||
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
||||||
}
|
}
|
||||||
@@ -14676,7 +14676,7 @@ var require_util4 = __commonJS({
|
|||||||
var { getEncoding } = require_encoding();
|
var { getEncoding } = require_encoding();
|
||||||
var { serializeAMimeType, parseMIMEType } = require_data_url();
|
var { serializeAMimeType, parseMIMEType } = require_data_url();
|
||||||
var { types: types2 } = require("node:util");
|
var { types: types2 } = require("node:util");
|
||||||
var { StringDecoder: StringDecoder2 } = require("string_decoder");
|
var { StringDecoder } = require("string_decoder");
|
||||||
var { btoa: btoa2 } = require("node:buffer");
|
var { btoa: btoa2 } = require("node:buffer");
|
||||||
var staticPropertyDescriptors = {
|
var staticPropertyDescriptors = {
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
@@ -14767,7 +14767,7 @@ var require_util4 = __commonJS({
|
|||||||
dataURL += serializeAMimeType(parsed);
|
dataURL += serializeAMimeType(parsed);
|
||||||
}
|
}
|
||||||
dataURL += ";base64,";
|
dataURL += ";base64,";
|
||||||
const decoder = new StringDecoder2("latin1");
|
const decoder = new StringDecoder("latin1");
|
||||||
for (const chunk of bytes) {
|
for (const chunk of bytes) {
|
||||||
dataURL += btoa2(decoder.write(chunk));
|
dataURL += btoa2(decoder.write(chunk));
|
||||||
}
|
}
|
||||||
@@ -14796,7 +14796,7 @@ var require_util4 = __commonJS({
|
|||||||
}
|
}
|
||||||
case "BinaryString": {
|
case "BinaryString": {
|
||||||
let binaryString = "";
|
let binaryString = "";
|
||||||
const decoder = new StringDecoder2("latin1");
|
const decoder = new StringDecoder("latin1");
|
||||||
for (const chunk of bytes) {
|
for (const chunk of bytes) {
|
||||||
binaryString += decoder.write(chunk);
|
binaryString += decoder.write(chunk);
|
||||||
}
|
}
|
||||||
@@ -43099,7 +43099,7 @@ var require_mock_interceptor2 = __commonJS({
|
|||||||
var require_mock_client2 = __commonJS({
|
var require_mock_client2 = __commonJS({
|
||||||
"node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
|
"node_modules/undici/lib/mock/mock-client.js"(exports2, module2) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var { promisify: promisify5 } = require("node:util");
|
var { promisify: promisify6 } = require("node:util");
|
||||||
var Client = require_client2();
|
var Client = require_client2();
|
||||||
var { buildMockDispatch } = require_mock_utils2();
|
var { buildMockDispatch } = require_mock_utils2();
|
||||||
var {
|
var {
|
||||||
@@ -43147,7 +43147,7 @@ var require_mock_client2 = __commonJS({
|
|||||||
this[kDispatches] = [];
|
this[kDispatches] = [];
|
||||||
}
|
}
|
||||||
async [kClose]() {
|
async [kClose]() {
|
||||||
await promisify5(this[kOriginalClose])();
|
await promisify6(this[kOriginalClose])();
|
||||||
this[kConnected] = 0;
|
this[kConnected] = 0;
|
||||||
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
||||||
}
|
}
|
||||||
@@ -43360,7 +43360,7 @@ var require_mock_call_history = __commonJS({
|
|||||||
var require_mock_pool2 = __commonJS({
|
var require_mock_pool2 = __commonJS({
|
||||||
"node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
|
"node_modules/undici/lib/mock/mock-pool.js"(exports2, module2) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var { promisify: promisify5 } = require("node:util");
|
var { promisify: promisify6 } = require("node:util");
|
||||||
var Pool = require_pool2();
|
var Pool = require_pool2();
|
||||||
var { buildMockDispatch } = require_mock_utils2();
|
var { buildMockDispatch } = require_mock_utils2();
|
||||||
var {
|
var {
|
||||||
@@ -43408,7 +43408,7 @@ var require_mock_pool2 = __commonJS({
|
|||||||
this[kDispatches] = [];
|
this[kDispatches] = [];
|
||||||
}
|
}
|
||||||
async [kClose]() {
|
async [kClose]() {
|
||||||
await promisify5(this[kOriginalClose])();
|
await promisify6(this[kOriginalClose])();
|
||||||
this[kConnected] = 0;
|
this[kConnected] = 0;
|
||||||
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
||||||
}
|
}
|
||||||
@@ -58186,9 +58186,6 @@ var _summary = new Summary();
|
|||||||
// node_modules/@actions/core/lib/platform.js
|
// node_modules/@actions/core/lib/platform.js
|
||||||
var import_os2 = __toESM(require("os"), 1);
|
var import_os2 = __toESM(require("os"), 1);
|
||||||
|
|
||||||
// node_modules/@actions/exec/lib/exec.js
|
|
||||||
var import_string_decoder = require("string_decoder");
|
|
||||||
|
|
||||||
// node_modules/@actions/exec/lib/toolrunner.js
|
// node_modules/@actions/exec/lib/toolrunner.js
|
||||||
var os3 = __toESM(require("os"), 1);
|
var os3 = __toESM(require("os"), 1);
|
||||||
var events = __toESM(require("events"), 1);
|
var events = __toESM(require("events"), 1);
|
||||||
@@ -59009,38 +59006,6 @@ function exec(commandLine, args, options) {
|
|||||||
return runner.exec();
|
return runner.exec();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getExecOutput(commandLine, args, options) {
|
|
||||||
return __awaiter7(this, void 0, void 0, function* () {
|
|
||||||
var _a2, _b;
|
|
||||||
let stdout = "";
|
|
||||||
let stderr = "";
|
|
||||||
const stdoutDecoder = new import_string_decoder.StringDecoder("utf8");
|
|
||||||
const stderrDecoder = new import_string_decoder.StringDecoder("utf8");
|
|
||||||
const originalStdoutListener = (_a2 = options === null || options === void 0 ? void 0 : options.listeners) === null || _a2 === void 0 ? void 0 : _a2.stdout;
|
|
||||||
const originalStdErrListener = (_b = options === null || options === void 0 ? void 0 : options.listeners) === null || _b === void 0 ? void 0 : _b.stderr;
|
|
||||||
const stdErrListener = (data) => {
|
|
||||||
stderr += stderrDecoder.write(data);
|
|
||||||
if (originalStdErrListener) {
|
|
||||||
originalStdErrListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const stdOutListener = (data) => {
|
|
||||||
stdout += stdoutDecoder.write(data);
|
|
||||||
if (originalStdoutListener) {
|
|
||||||
originalStdoutListener(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const listeners = Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.listeners), { stdout: stdOutListener, stderr: stdErrListener });
|
|
||||||
const exitCode = yield exec(commandLine, args, Object.assign(Object.assign({}, options), { listeners }));
|
|
||||||
stdout += stdoutDecoder.end();
|
|
||||||
stderr += stderrDecoder.end();
|
|
||||||
return {
|
|
||||||
exitCode,
|
|
||||||
stdout,
|
|
||||||
stderr
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// node_modules/@actions/core/lib/platform.js
|
// node_modules/@actions/core/lib/platform.js
|
||||||
var platform = import_os2.default.platform();
|
var platform = import_os2.default.platform();
|
||||||
@@ -102102,7 +102067,10 @@ function getResolutionStrategy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// src/utils/python-runtime.ts
|
// src/utils/python-runtime.ts
|
||||||
|
var import_node_child_process = require("node:child_process");
|
||||||
var import_node_path2 = require("node:path");
|
var import_node_path2 = require("node:path");
|
||||||
|
var import_node_util4 = require("node:util");
|
||||||
|
var execFileAsync = (0, import_node_util4.promisify)(import_node_child_process.execFile);
|
||||||
var PYTHON_RUNTIME_QUERY = `
|
var PYTHON_RUNTIME_QUERY = `
|
||||||
import json
|
import json
|
||||||
import platform
|
import platform
|
||||||
@@ -102141,10 +102109,10 @@ async function getPythonRuntimeId(inputs) {
|
|||||||
}
|
}
|
||||||
const pythonPath = process.platform === "win32" ? (0, import_node_path2.join)(inputs.venvPath, "Scripts", "python.exe") : (0, import_node_path2.join)(inputs.venvPath, "bin", "python");
|
const pythonPath = process.platform === "win32" ? (0, import_node_path2.join)(inputs.venvPath, "Scripts", "python.exe") : (0, import_node_path2.join)(inputs.venvPath, "bin", "python");
|
||||||
try {
|
try {
|
||||||
const { stdout } = await getExecOutput(
|
const { stdout } = await execFileAsync(
|
||||||
`"${pythonPath.replace(/"/g, '\\"')}"`,
|
pythonPath,
|
||||||
["-I", "-c", PYTHON_RUNTIME_QUERY],
|
["-I", "-c", PYTHON_RUNTIME_QUERY],
|
||||||
{ silent: !isDebug() }
|
{ encoding: "utf8" }
|
||||||
);
|
);
|
||||||
return formatRuntimeId(JSON.parse(stdout));
|
return formatRuntimeId(JSON.parse(stdout));
|
||||||
} catch (error2) {
|
} catch (error2) {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import { execFile } from "node:child_process";
|
||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
|
import { promisify } from "node:util";
|
||||||
import * as core from "@actions/core";
|
import * as core from "@actions/core";
|
||||||
import * as exec from "@actions/exec";
|
|
||||||
import type { SetupInputs } from "./inputs";
|
import type { SetupInputs } from "./inputs";
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
const PYTHON_RUNTIME_QUERY = `
|
const PYTHON_RUNTIME_QUERY = `
|
||||||
import json
|
import json
|
||||||
import platform
|
import platform
|
||||||
@@ -69,11 +72,10 @@ export async function getPythonRuntimeId(inputs: SetupInputs): Promise<string> {
|
|||||||
: join(inputs.venvPath, "bin", "python");
|
: join(inputs.venvPath, "bin", "python");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// @actions/exec parses the executable as a command line, so quote the path.
|
const { stdout } = await execFileAsync(
|
||||||
const { stdout } = await exec.getExecOutput(
|
pythonPath,
|
||||||
`"${pythonPath.replace(/"/g, '\\"')}"`,
|
|
||||||
["-I", "-c", PYTHON_RUNTIME_QUERY],
|
["-I", "-c", PYTHON_RUNTIME_QUERY],
|
||||||
{ silent: !core.isDebug() },
|
{ encoding: "utf8" },
|
||||||
);
|
);
|
||||||
return formatRuntimeId(JSON.parse(stdout));
|
return formatRuntimeId(JSON.parse(stdout));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user