@vercel/python 6.1.1 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +624 -503
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var require_windows = __commonJS({
|
|
|
48
48
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.js"(exports, module2) {
|
|
49
49
|
module2.exports = isexe;
|
|
50
50
|
isexe.sync = sync;
|
|
51
|
-
var
|
|
51
|
+
var fs5 = require("fs");
|
|
52
52
|
function checkPathExt(path, options) {
|
|
53
53
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
54
54
|
if (!pathext) {
|
|
@@ -73,12 +73,12 @@ var require_windows = __commonJS({
|
|
|
73
73
|
return checkPathExt(path, options);
|
|
74
74
|
}
|
|
75
75
|
function isexe(path, options, cb) {
|
|
76
|
-
|
|
76
|
+
fs5.stat(path, function(er, stat) {
|
|
77
77
|
cb(er, er ? false : checkStat(stat, path, options));
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
function sync(path, options) {
|
|
81
|
-
return checkStat(
|
|
81
|
+
return checkStat(fs5.statSync(path), path, options);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
});
|
|
@@ -88,14 +88,14 @@ var require_mode = __commonJS({
|
|
|
88
88
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.js"(exports, module2) {
|
|
89
89
|
module2.exports = isexe;
|
|
90
90
|
isexe.sync = sync;
|
|
91
|
-
var
|
|
91
|
+
var fs5 = require("fs");
|
|
92
92
|
function isexe(path, options, cb) {
|
|
93
|
-
|
|
93
|
+
fs5.stat(path, function(er, stat) {
|
|
94
94
|
cb(er, er ? false : checkStat(stat, options));
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
function sync(path, options) {
|
|
98
|
-
return checkStat(
|
|
98
|
+
return checkStat(fs5.statSync(path), options);
|
|
99
99
|
}
|
|
100
100
|
function checkStat(stat, options) {
|
|
101
101
|
return stat.isFile() && checkMode(stat, options);
|
|
@@ -119,7 +119,7 @@ var require_mode = __commonJS({
|
|
|
119
119
|
// ../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js
|
|
120
120
|
var require_isexe = __commonJS({
|
|
121
121
|
"../../node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.js"(exports, module2) {
|
|
122
|
-
var
|
|
122
|
+
var fs5 = require("fs");
|
|
123
123
|
var core;
|
|
124
124
|
if (process.platform === "win32" || global.TESTING_WINDOWS) {
|
|
125
125
|
core = require_windows();
|
|
@@ -395,7 +395,7 @@ var require_shebang_command = __commonJS({
|
|
|
395
395
|
var require_readShebang = __commonJS({
|
|
396
396
|
"../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/util/readShebang.js"(exports, module2) {
|
|
397
397
|
"use strict";
|
|
398
|
-
var
|
|
398
|
+
var fs5 = require("fs");
|
|
399
399
|
var shebangCommand = require_shebang_command();
|
|
400
400
|
function readShebang(command) {
|
|
401
401
|
const size = 150;
|
|
@@ -408,9 +408,9 @@ var require_readShebang = __commonJS({
|
|
|
408
408
|
}
|
|
409
409
|
let fd;
|
|
410
410
|
try {
|
|
411
|
-
fd =
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
fd = fs5.openSync(command, "r");
|
|
412
|
+
fs5.readSync(fd, buffer, 0, size, 0);
|
|
413
|
+
fs5.closeSync(fd);
|
|
414
414
|
} catch (e) {
|
|
415
415
|
}
|
|
416
416
|
return shebangCommand(buffer.toString());
|
|
@@ -1498,7 +1498,7 @@ var require_parse = __commonJS({
|
|
|
1498
1498
|
var escape = require_escape();
|
|
1499
1499
|
var readShebang = require_readShebang();
|
|
1500
1500
|
var semver = require_semver();
|
|
1501
|
-
var
|
|
1501
|
+
var isWin3 = process.platform === "win32";
|
|
1502
1502
|
var isExecutableRegExp = /\.(?:com|exe)$/i;
|
|
1503
1503
|
var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
|
|
1504
1504
|
var supportsShellOption = niceTry(() => semver.satisfies(process.version, "^4.8.0 || ^5.7.0 || >= 6.0.0", true)) || false;
|
|
@@ -1513,7 +1513,7 @@ var require_parse = __commonJS({
|
|
|
1513
1513
|
return parsed.file;
|
|
1514
1514
|
}
|
|
1515
1515
|
function parseNonShell(parsed) {
|
|
1516
|
-
if (!
|
|
1516
|
+
if (!isWin3) {
|
|
1517
1517
|
return parsed;
|
|
1518
1518
|
}
|
|
1519
1519
|
const commandFile = detectShebang(parsed);
|
|
@@ -1535,7 +1535,7 @@ var require_parse = __commonJS({
|
|
|
1535
1535
|
return parsed;
|
|
1536
1536
|
}
|
|
1537
1537
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
1538
|
-
if (
|
|
1538
|
+
if (isWin3) {
|
|
1539
1539
|
parsed.command = typeof parsed.options.shell === "string" ? parsed.options.shell : process.env.comspec || "cmd.exe";
|
|
1540
1540
|
parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
|
|
1541
1541
|
parsed.options.windowsVerbatimArguments = true;
|
|
@@ -1578,7 +1578,7 @@ var require_parse = __commonJS({
|
|
|
1578
1578
|
var require_enoent = __commonJS({
|
|
1579
1579
|
"../../node_modules/.pnpm/cross-spawn@6.0.5/node_modules/cross-spawn/lib/enoent.js"(exports, module2) {
|
|
1580
1580
|
"use strict";
|
|
1581
|
-
var
|
|
1581
|
+
var isWin3 = process.platform === "win32";
|
|
1582
1582
|
function notFoundError(original, syscall) {
|
|
1583
1583
|
return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
|
|
1584
1584
|
code: "ENOENT",
|
|
@@ -1589,7 +1589,7 @@ var require_enoent = __commonJS({
|
|
|
1589
1589
|
});
|
|
1590
1590
|
}
|
|
1591
1591
|
function hookChildProcess(cp, parsed) {
|
|
1592
|
-
if (!
|
|
1592
|
+
if (!isWin3) {
|
|
1593
1593
|
return;
|
|
1594
1594
|
}
|
|
1595
1595
|
const originalEmit = cp.emit;
|
|
@@ -1604,13 +1604,13 @@ var require_enoent = __commonJS({
|
|
|
1604
1604
|
};
|
|
1605
1605
|
}
|
|
1606
1606
|
function verifyENOENT(status, parsed) {
|
|
1607
|
-
if (
|
|
1607
|
+
if (isWin3 && status === 1 && !parsed.file) {
|
|
1608
1608
|
return notFoundError(parsed.original, "spawn");
|
|
1609
1609
|
}
|
|
1610
1610
|
return null;
|
|
1611
1611
|
}
|
|
1612
1612
|
function verifyENOENTSync(status, parsed) {
|
|
1613
|
-
if (
|
|
1613
|
+
if (isWin3 && status === 1 && !parsed.file) {
|
|
1614
1614
|
return notFoundError(parsed.original, "spawnSync");
|
|
1615
1615
|
}
|
|
1616
1616
|
return null;
|
|
@@ -1895,9 +1895,9 @@ var require_pump = __commonJS({
|
|
|
1895
1895
|
"../../node_modules/.pnpm/pump@3.0.2/node_modules/pump/index.js"(exports, module2) {
|
|
1896
1896
|
var once = require_once();
|
|
1897
1897
|
var eos = require_end_of_stream();
|
|
1898
|
-
var
|
|
1898
|
+
var fs5;
|
|
1899
1899
|
try {
|
|
1900
|
-
|
|
1900
|
+
fs5 = require("fs");
|
|
1901
1901
|
} catch (e) {
|
|
1902
1902
|
}
|
|
1903
1903
|
var noop = function() {
|
|
@@ -1909,9 +1909,9 @@ var require_pump = __commonJS({
|
|
|
1909
1909
|
var isFS = function(stream) {
|
|
1910
1910
|
if (!ancient)
|
|
1911
1911
|
return false;
|
|
1912
|
-
if (!
|
|
1912
|
+
if (!fs5)
|
|
1913
1913
|
return false;
|
|
1914
|
-
return (stream instanceof (
|
|
1914
|
+
return (stream instanceof (fs5.ReadStream || noop) || stream instanceof (fs5.WriteStream || noop)) && isFn(stream.close);
|
|
1915
1915
|
};
|
|
1916
1916
|
var isRequest = function(stream) {
|
|
1917
1917
|
return stream.setHeader && isFn(stream.abort);
|
|
@@ -2143,7 +2143,7 @@ var require_signal_exit = __commonJS({
|
|
|
2143
2143
|
} else {
|
|
2144
2144
|
assert = require("assert");
|
|
2145
2145
|
signals = require_signals();
|
|
2146
|
-
|
|
2146
|
+
isWin3 = /^win/i.test(process2.platform);
|
|
2147
2147
|
EE = require("events");
|
|
2148
2148
|
if (typeof EE !== "function") {
|
|
2149
2149
|
EE = EE.EventEmitter;
|
|
@@ -2215,7 +2215,7 @@ var require_signal_exit = __commonJS({
|
|
|
2215
2215
|
unload();
|
|
2216
2216
|
emit("exit", null, sig);
|
|
2217
2217
|
emit("afterexit", null, sig);
|
|
2218
|
-
if (
|
|
2218
|
+
if (isWin3 && sig === "SIGHUP") {
|
|
2219
2219
|
sig = "SIGINT";
|
|
2220
2220
|
}
|
|
2221
2221
|
process2.kill(process2.pid, sig);
|
|
@@ -2272,7 +2272,7 @@ var require_signal_exit = __commonJS({
|
|
|
2272
2272
|
}
|
|
2273
2273
|
var assert;
|
|
2274
2274
|
var signals;
|
|
2275
|
-
var
|
|
2275
|
+
var isWin3;
|
|
2276
2276
|
var EE;
|
|
2277
2277
|
var emitter;
|
|
2278
2278
|
var unload;
|
|
@@ -2651,7 +2651,7 @@ ${stderr}${stdout}`;
|
|
|
2651
2651
|
var require_lib = __commonJS({
|
|
2652
2652
|
"../../node_modules/.pnpm/which@3.0.0/node_modules/which/lib/index.js"(exports, module2) {
|
|
2653
2653
|
var isexe = require_isexe();
|
|
2654
|
-
var { join:
|
|
2654
|
+
var { join: join6, delimiter, sep, posix } = require("path");
|
|
2655
2655
|
var isWindows = process.platform === "win32";
|
|
2656
2656
|
var rSlash = new RegExp(`[${posix.sep}${sep === posix.sep ? "" : sep}]`.replace(/(\\)/g, "\\$1"));
|
|
2657
2657
|
var rRel = new RegExp(`^\\.${rSlash.source}`);
|
|
@@ -2680,7 +2680,7 @@ var require_lib = __commonJS({
|
|
|
2680
2680
|
var getPathPart = (raw, cmd) => {
|
|
2681
2681
|
const pathPart = /^".*"$/.test(raw) ? raw.slice(1, -1) : raw;
|
|
2682
2682
|
const prefix = !pathPart && rRel.test(cmd) ? cmd.slice(0, 2) : "";
|
|
2683
|
-
return prefix +
|
|
2683
|
+
return prefix + join6(pathPart, cmd);
|
|
2684
2684
|
};
|
|
2685
2685
|
var which3 = async (cmd, opt = {}) => {
|
|
2686
2686
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
@@ -2748,20 +2748,139 @@ __export(src_exports, {
|
|
|
2748
2748
|
version: () => version
|
|
2749
2749
|
});
|
|
2750
2750
|
module.exports = __toCommonJS(src_exports);
|
|
2751
|
-
var
|
|
2751
|
+
var import_fs5 = __toESM(require("fs"));
|
|
2752
2752
|
var import_util = require("util");
|
|
2753
|
-
var
|
|
2754
|
-
var
|
|
2753
|
+
var import_path5 = require("path");
|
|
2754
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
2755
2755
|
|
|
2756
2756
|
// src/install.ts
|
|
2757
2757
|
var import_execa = __toESM(require_execa());
|
|
2758
|
-
var
|
|
2758
|
+
var import_fs2 = __toESM(require("fs"));
|
|
2759
2759
|
var import_os = __toESM(require("os"));
|
|
2760
|
-
var
|
|
2760
|
+
var import_path2 = require("path");
|
|
2761
2761
|
var import_which = __toESM(require_lib());
|
|
2762
|
+
var import_build_utils2 = require("@vercel/build-utils");
|
|
2763
|
+
|
|
2764
|
+
// src/utils.ts
|
|
2765
|
+
var import_fs = __toESM(require("fs"));
|
|
2766
|
+
var import_path = require("path");
|
|
2762
2767
|
var import_build_utils = require("@vercel/build-utils");
|
|
2768
|
+
var execa = require_execa();
|
|
2763
2769
|
var isWin = process.platform === "win32";
|
|
2764
|
-
var
|
|
2770
|
+
var isInVirtualEnv = () => {
|
|
2771
|
+
return process.env.VIRTUAL_ENV;
|
|
2772
|
+
};
|
|
2773
|
+
function getVenvBinDir(venvPath) {
|
|
2774
|
+
return (0, import_path.join)(venvPath, isWin ? "Scripts" : "bin");
|
|
2775
|
+
}
|
|
2776
|
+
function useVirtualEnv(workPath, env, systemPython) {
|
|
2777
|
+
const venvDirs = [".venv", "venv"];
|
|
2778
|
+
let pythonCmd = systemPython;
|
|
2779
|
+
for (const venv of venvDirs) {
|
|
2780
|
+
const venvRoot = (0, import_path.join)(workPath, venv);
|
|
2781
|
+
const binDir = process.platform === "win32" ? (0, import_path.join)(venvRoot, "Scripts") : (0, import_path.join)(venvRoot, "bin");
|
|
2782
|
+
const candidates = process.platform === "win32" ? [(0, import_path.join)(binDir, "python.exe"), (0, import_path.join)(binDir, "python")] : [(0, import_path.join)(binDir, "python3"), (0, import_path.join)(binDir, "python")];
|
|
2783
|
+
const found = candidates.find((p) => import_fs.default.existsSync(p));
|
|
2784
|
+
if (found) {
|
|
2785
|
+
pythonCmd = found;
|
|
2786
|
+
env.VIRTUAL_ENV = venvRoot;
|
|
2787
|
+
env.PATH = `${binDir}${import_path.delimiter}${env.PATH || ""}`;
|
|
2788
|
+
return { pythonCmd, venvRoot };
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
return { pythonCmd };
|
|
2792
|
+
}
|
|
2793
|
+
function createVenvEnv(venvPath, baseEnv = process.env) {
|
|
2794
|
+
const env = { ...baseEnv, VIRTUAL_ENV: venvPath };
|
|
2795
|
+
const binDir = getVenvBinDir(venvPath);
|
|
2796
|
+
const existingPath = env.PATH || process.env.PATH || "";
|
|
2797
|
+
env.PATH = existingPath ? `${binDir}${import_path.delimiter}${existingPath}` : binDir;
|
|
2798
|
+
return env;
|
|
2799
|
+
}
|
|
2800
|
+
async function ensureVenv({
|
|
2801
|
+
pythonPath,
|
|
2802
|
+
venvPath
|
|
2803
|
+
}) {
|
|
2804
|
+
const marker = (0, import_path.join)(venvPath, "pyvenv.cfg");
|
|
2805
|
+
try {
|
|
2806
|
+
await import_fs.default.promises.access(marker);
|
|
2807
|
+
return;
|
|
2808
|
+
} catch {
|
|
2809
|
+
}
|
|
2810
|
+
await import_fs.default.promises.mkdir(venvPath, { recursive: true });
|
|
2811
|
+
console.log(`Creating virtual environment at "${venvPath}"...`);
|
|
2812
|
+
await execa(pythonPath, ["-m", "venv", venvPath]);
|
|
2813
|
+
}
|
|
2814
|
+
function getVenvPythonBin(venvPath) {
|
|
2815
|
+
return (0, import_path.join)(getVenvBinDir(venvPath), isWin ? "python.exe" : "python");
|
|
2816
|
+
}
|
|
2817
|
+
async function runPyprojectScript(workPath, scriptNames, env) {
|
|
2818
|
+
const pyprojectPath = (0, import_path.join)(workPath, "pyproject.toml");
|
|
2819
|
+
if (!import_fs.default.existsSync(pyprojectPath))
|
|
2820
|
+
return false;
|
|
2821
|
+
let pyproject = null;
|
|
2822
|
+
try {
|
|
2823
|
+
pyproject = await (0, import_build_utils.readConfigFile)(pyprojectPath);
|
|
2824
|
+
} catch {
|
|
2825
|
+
console.error("Failed to parse pyproject.toml");
|
|
2826
|
+
return false;
|
|
2827
|
+
}
|
|
2828
|
+
const scripts = pyproject?.tool?.vercel?.scripts || {};
|
|
2829
|
+
const candidates = typeof scriptNames === "string" ? [scriptNames] : Array.from(scriptNames);
|
|
2830
|
+
const scriptToRun = candidates.find((name) => Boolean(scripts[name]));
|
|
2831
|
+
if (!scriptToRun)
|
|
2832
|
+
return false;
|
|
2833
|
+
const systemPython = process.platform === "win32" ? "python" : "python3";
|
|
2834
|
+
const finalEnv = { ...process.env, ...env };
|
|
2835
|
+
useVirtualEnv(workPath, finalEnv, systemPython);
|
|
2836
|
+
const scriptCommand = scripts[scriptToRun];
|
|
2837
|
+
if (typeof scriptCommand === "string" && scriptCommand.trim()) {
|
|
2838
|
+
console.log(`Executing: ${scriptCommand}`);
|
|
2839
|
+
await (0, import_build_utils.execCommand)(scriptCommand, {
|
|
2840
|
+
cwd: workPath,
|
|
2841
|
+
env: finalEnv
|
|
2842
|
+
});
|
|
2843
|
+
return true;
|
|
2844
|
+
}
|
|
2845
|
+
return false;
|
|
2846
|
+
}
|
|
2847
|
+
async function runUvCommand(options) {
|
|
2848
|
+
const { uvPath, args, cwd, venvPath } = options;
|
|
2849
|
+
const pretty = `uv ${args.join(" ")}`;
|
|
2850
|
+
(0, import_build_utils.debug)(`Running "${pretty}"...`);
|
|
2851
|
+
if (!uvPath) {
|
|
2852
|
+
throw new Error(`uv is required to run "${pretty}" but is not available`);
|
|
2853
|
+
}
|
|
2854
|
+
try {
|
|
2855
|
+
await execa(uvPath, args, {
|
|
2856
|
+
cwd,
|
|
2857
|
+
env: createVenvEnv(venvPath)
|
|
2858
|
+
});
|
|
2859
|
+
return true;
|
|
2860
|
+
} catch (err) {
|
|
2861
|
+
throw new Error(
|
|
2862
|
+
`Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
function findDir({
|
|
2867
|
+
file,
|
|
2868
|
+
entryDirectory,
|
|
2869
|
+
workPath,
|
|
2870
|
+
fsFiles
|
|
2871
|
+
}) {
|
|
2872
|
+
if (fsFiles[(0, import_path.join)(entryDirectory, file)]) {
|
|
2873
|
+
return (0, import_path.join)(workPath, entryDirectory);
|
|
2874
|
+
}
|
|
2875
|
+
if (fsFiles[file]) {
|
|
2876
|
+
return workPath;
|
|
2877
|
+
}
|
|
2878
|
+
return null;
|
|
2879
|
+
}
|
|
2880
|
+
|
|
2881
|
+
// src/install.ts
|
|
2882
|
+
var isWin2 = process.platform === "win32";
|
|
2883
|
+
var uvExec = isWin2 ? "uv.exe" : "uv";
|
|
2765
2884
|
var makeDependencyCheckCode = (dependency) => `
|
|
2766
2885
|
from importlib import util
|
|
2767
2886
|
dep = '${dependency}'.replace('-', '_')
|
|
@@ -2776,7 +2895,7 @@ async function isInstalled(pythonPath, dependency, cwd) {
|
|
|
2776
2895
|
{
|
|
2777
2896
|
stdio: "pipe",
|
|
2778
2897
|
cwd,
|
|
2779
|
-
env: { ...process.env, PYTHONPATH: (0,
|
|
2898
|
+
env: { ...process.env, PYTHONPATH: (0, import_path2.join)(cwd, resolveVendorDir()) }
|
|
2780
2899
|
}
|
|
2781
2900
|
);
|
|
2782
2901
|
return stdout.startsWith(cwd);
|
|
@@ -2799,7 +2918,7 @@ async function areRequirementsInstalled(pythonPath, requirementsPath, cwd) {
|
|
|
2799
2918
|
{
|
|
2800
2919
|
stdio: "pipe",
|
|
2801
2920
|
cwd,
|
|
2802
|
-
env: { ...process.env, PYTHONPATH: (0,
|
|
2921
|
+
env: { ...process.env, PYTHONPATH: (0, import_path2.join)(cwd, resolveVendorDir()) }
|
|
2803
2922
|
}
|
|
2804
2923
|
);
|
|
2805
2924
|
return true;
|
|
@@ -2807,10 +2926,334 @@ async function areRequirementsInstalled(pythonPath, requirementsPath, cwd) {
|
|
|
2807
2926
|
return false;
|
|
2808
2927
|
}
|
|
2809
2928
|
}
|
|
2929
|
+
async function runUvSync({
|
|
2930
|
+
uvPath,
|
|
2931
|
+
venvPath,
|
|
2932
|
+
projectDir,
|
|
2933
|
+
locked
|
|
2934
|
+
}) {
|
|
2935
|
+
const args = ["sync", "--active", "--no-dev"];
|
|
2936
|
+
if (locked) {
|
|
2937
|
+
args.push("--locked");
|
|
2938
|
+
}
|
|
2939
|
+
args.push("--no-editable");
|
|
2940
|
+
await runUvCommand({
|
|
2941
|
+
uvPath,
|
|
2942
|
+
args,
|
|
2943
|
+
cwd: projectDir,
|
|
2944
|
+
venvPath
|
|
2945
|
+
});
|
|
2946
|
+
}
|
|
2947
|
+
async function getSitePackagesDirs(pythonBin) {
|
|
2948
|
+
const code = `
|
|
2949
|
+
import json
|
|
2950
|
+
import sysconfig
|
|
2951
|
+
paths = []
|
|
2952
|
+
for key in ("purelib", "platlib"):
|
|
2953
|
+
candidate = sysconfig.get_path(key)
|
|
2954
|
+
if candidate and candidate not in paths:
|
|
2955
|
+
paths.append(candidate)
|
|
2956
|
+
print(json.dumps(paths))
|
|
2957
|
+
`.trim();
|
|
2958
|
+
const { stdout } = await (0, import_execa.default)(pythonBin, ["-c", code]);
|
|
2959
|
+
try {
|
|
2960
|
+
const parsed = JSON.parse(stdout);
|
|
2961
|
+
if (Array.isArray(parsed)) {
|
|
2962
|
+
return parsed.filter((p) => typeof p === "string");
|
|
2963
|
+
}
|
|
2964
|
+
} catch (err) {
|
|
2965
|
+
(0, import_build_utils2.debug)("Failed to parse site-packages output", err);
|
|
2966
|
+
}
|
|
2967
|
+
return [];
|
|
2968
|
+
}
|
|
2969
|
+
async function getVenvSitePackagesDirs(venvPath) {
|
|
2970
|
+
const pythonBin = getVenvPythonBin(venvPath);
|
|
2971
|
+
return getSitePackagesDirs(pythonBin);
|
|
2972
|
+
}
|
|
2810
2973
|
function resolveVendorDir() {
|
|
2811
2974
|
const vendorDir = process.env.VERCEL_PYTHON_VENDOR_DIR || "_vendor";
|
|
2812
2975
|
return vendorDir;
|
|
2813
2976
|
}
|
|
2977
|
+
async function detectInstallSource({
|
|
2978
|
+
workPath,
|
|
2979
|
+
entryDirectory,
|
|
2980
|
+
fsFiles
|
|
2981
|
+
}) {
|
|
2982
|
+
const uvLockDir = findDir({
|
|
2983
|
+
file: "uv.lock",
|
|
2984
|
+
entryDirectory,
|
|
2985
|
+
workPath,
|
|
2986
|
+
fsFiles
|
|
2987
|
+
});
|
|
2988
|
+
const pyprojectDir = findDir({
|
|
2989
|
+
file: "pyproject.toml",
|
|
2990
|
+
entryDirectory,
|
|
2991
|
+
workPath,
|
|
2992
|
+
fsFiles
|
|
2993
|
+
});
|
|
2994
|
+
const pipfileLockDir = findDir({
|
|
2995
|
+
file: "Pipfile.lock",
|
|
2996
|
+
entryDirectory,
|
|
2997
|
+
workPath,
|
|
2998
|
+
fsFiles
|
|
2999
|
+
});
|
|
3000
|
+
const pipfileDir = findDir({
|
|
3001
|
+
file: "Pipfile",
|
|
3002
|
+
entryDirectory,
|
|
3003
|
+
workPath,
|
|
3004
|
+
fsFiles
|
|
3005
|
+
});
|
|
3006
|
+
const requirementsDir = findDir({
|
|
3007
|
+
file: "requirements.txt",
|
|
3008
|
+
entryDirectory,
|
|
3009
|
+
workPath,
|
|
3010
|
+
fsFiles
|
|
3011
|
+
});
|
|
3012
|
+
let manifestPath = null;
|
|
3013
|
+
let manifestType = null;
|
|
3014
|
+
if (uvLockDir && pyprojectDir) {
|
|
3015
|
+
manifestType = "uv.lock";
|
|
3016
|
+
manifestPath = (0, import_path2.join)(uvLockDir, "uv.lock");
|
|
3017
|
+
} else if (pyprojectDir) {
|
|
3018
|
+
manifestType = "pyproject.toml";
|
|
3019
|
+
manifestPath = (0, import_path2.join)(pyprojectDir, "pyproject.toml");
|
|
3020
|
+
} else if (pipfileLockDir) {
|
|
3021
|
+
manifestType = "Pipfile.lock";
|
|
3022
|
+
manifestPath = (0, import_path2.join)(pipfileLockDir, "Pipfile.lock");
|
|
3023
|
+
} else if (pipfileDir) {
|
|
3024
|
+
manifestType = "Pipfile";
|
|
3025
|
+
manifestPath = (0, import_path2.join)(pipfileDir, "Pipfile");
|
|
3026
|
+
} else if (requirementsDir) {
|
|
3027
|
+
manifestType = "requirements.txt";
|
|
3028
|
+
manifestPath = (0, import_path2.join)(requirementsDir, "requirements.txt");
|
|
3029
|
+
}
|
|
3030
|
+
let manifestContent;
|
|
3031
|
+
if (manifestPath) {
|
|
3032
|
+
try {
|
|
3033
|
+
manifestContent = await import_fs2.default.promises.readFile(manifestPath, "utf8");
|
|
3034
|
+
} catch (err) {
|
|
3035
|
+
(0, import_build_utils2.debug)("Failed to read install manifest contents", err);
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
3038
|
+
return { manifestPath, manifestType, manifestContent };
|
|
3039
|
+
}
|
|
3040
|
+
async function createPyprojectToml({
|
|
3041
|
+
projectName,
|
|
3042
|
+
pyprojectPath,
|
|
3043
|
+
dependencies
|
|
3044
|
+
}) {
|
|
3045
|
+
const requiresPython = ">=3.12";
|
|
3046
|
+
const depsToml = dependencies.length > 0 ? [
|
|
3047
|
+
"dependencies = [",
|
|
3048
|
+
...dependencies.map((dep) => ` "${dep}",`),
|
|
3049
|
+
"]"
|
|
3050
|
+
].join("\n") : "dependencies = []";
|
|
3051
|
+
const content = [
|
|
3052
|
+
"[project]",
|
|
3053
|
+
`name = "${projectName}"`,
|
|
3054
|
+
'version = "0.1.0"',
|
|
3055
|
+
`requires-python = "${requiresPython}"`,
|
|
3056
|
+
"classifiers = [",
|
|
3057
|
+
' "Private :: Do Not Upload",',
|
|
3058
|
+
"]",
|
|
3059
|
+
depsToml,
|
|
3060
|
+
""
|
|
3061
|
+
].join("\n");
|
|
3062
|
+
await import_fs2.default.promises.writeFile(pyprojectPath, content);
|
|
3063
|
+
}
|
|
3064
|
+
async function uvLock({
|
|
3065
|
+
projectDir,
|
|
3066
|
+
uvPath
|
|
3067
|
+
}) {
|
|
3068
|
+
const args = ["lock"];
|
|
3069
|
+
const pretty = `${uvPath} ${args.join(" ")}`;
|
|
3070
|
+
(0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
|
|
3071
|
+
try {
|
|
3072
|
+
await (0, import_execa.default)(uvPath, args, { cwd: projectDir });
|
|
3073
|
+
} catch (err) {
|
|
3074
|
+
throw new Error(
|
|
3075
|
+
`Failed to run "${pretty}": ${err instanceof Error ? err.message : String(err)}`
|
|
3076
|
+
);
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
async function uvAddDependencies({
|
|
3080
|
+
projectDir,
|
|
3081
|
+
uvPath,
|
|
3082
|
+
venvPath,
|
|
3083
|
+
dependencies
|
|
3084
|
+
}) {
|
|
3085
|
+
const toAdd = dependencies.filter(Boolean);
|
|
3086
|
+
if (!toAdd.length)
|
|
3087
|
+
return;
|
|
3088
|
+
const args = ["add", "--active", ...toAdd];
|
|
3089
|
+
const pretty = `${uvPath} ${args.join(" ")}`;
|
|
3090
|
+
(0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
|
|
3091
|
+
await runUvCommand({ uvPath, args, cwd: projectDir, venvPath });
|
|
3092
|
+
}
|
|
3093
|
+
async function uvAddFromFile({
|
|
3094
|
+
projectDir,
|
|
3095
|
+
uvPath,
|
|
3096
|
+
venvPath,
|
|
3097
|
+
requirementsPath
|
|
3098
|
+
}) {
|
|
3099
|
+
const args = ["add", "--active", "-r", requirementsPath];
|
|
3100
|
+
const pretty = `${uvPath} ${args.join(" ")}`;
|
|
3101
|
+
(0, import_build_utils2.debug)(`Running "${pretty}" in ${projectDir}...`);
|
|
3102
|
+
await runUvCommand({ uvPath, args, cwd: projectDir, venvPath });
|
|
3103
|
+
}
|
|
3104
|
+
function getDependencyName(spec) {
|
|
3105
|
+
const match = spec.match(/^[A-Za-z0-9_.-]+/);
|
|
3106
|
+
return match ? match[0].toLowerCase() : spec.toLowerCase();
|
|
3107
|
+
}
|
|
3108
|
+
async function filterMissingRuntimeDependencies({
|
|
3109
|
+
pyprojectPath,
|
|
3110
|
+
runtimeDependencies
|
|
3111
|
+
}) {
|
|
3112
|
+
let declared = [];
|
|
3113
|
+
try {
|
|
3114
|
+
const config = await (0, import_build_utils2.readConfigFile)(pyprojectPath);
|
|
3115
|
+
declared = config?.project?.dependencies || [];
|
|
3116
|
+
} catch (err) {
|
|
3117
|
+
(0, import_build_utils2.debug)("Failed to parse pyproject.toml when filtering runtime deps", err);
|
|
3118
|
+
}
|
|
3119
|
+
const declaredNames = new Set(declared.map(getDependencyName));
|
|
3120
|
+
return runtimeDependencies.filter((spec) => {
|
|
3121
|
+
const name = getDependencyName(spec);
|
|
3122
|
+
return !declaredNames.has(name);
|
|
3123
|
+
});
|
|
3124
|
+
}
|
|
3125
|
+
async function ensureUvProject({
|
|
3126
|
+
workPath,
|
|
3127
|
+
entryDirectory,
|
|
3128
|
+
fsFiles,
|
|
3129
|
+
pythonPath,
|
|
3130
|
+
pipPath,
|
|
3131
|
+
uvPath,
|
|
3132
|
+
venvPath,
|
|
3133
|
+
meta,
|
|
3134
|
+
runtimeDependencies
|
|
3135
|
+
}) {
|
|
3136
|
+
const installInfo = await detectInstallSource({
|
|
3137
|
+
workPath,
|
|
3138
|
+
entryDirectory,
|
|
3139
|
+
fsFiles
|
|
3140
|
+
});
|
|
3141
|
+
const { manifestType, manifestPath } = installInfo;
|
|
3142
|
+
let projectDir;
|
|
3143
|
+
let pyprojectPath;
|
|
3144
|
+
if (manifestType === "uv.lock") {
|
|
3145
|
+
if (!manifestPath) {
|
|
3146
|
+
throw new Error("Expected uv.lock path to be resolved, but it was null");
|
|
3147
|
+
}
|
|
3148
|
+
projectDir = (0, import_path2.dirname)(manifestPath);
|
|
3149
|
+
pyprojectPath = (0, import_path2.join)(projectDir, "pyproject.toml");
|
|
3150
|
+
if (!import_fs2.default.existsSync(pyprojectPath)) {
|
|
3151
|
+
throw new Error(
|
|
3152
|
+
`Expected "pyproject.toml" next to "uv.lock" in "${projectDir}"`
|
|
3153
|
+
);
|
|
3154
|
+
}
|
|
3155
|
+
console.log("Installing required dependencies from uv.lock...");
|
|
3156
|
+
} else if (manifestType === "pyproject.toml") {
|
|
3157
|
+
if (!manifestPath) {
|
|
3158
|
+
throw new Error(
|
|
3159
|
+
"Expected pyproject.toml path to be resolved, but it was null"
|
|
3160
|
+
);
|
|
3161
|
+
}
|
|
3162
|
+
projectDir = (0, import_path2.dirname)(manifestPath);
|
|
3163
|
+
pyprojectPath = manifestPath;
|
|
3164
|
+
console.log("Installing required dependencies from pyproject.toml...");
|
|
3165
|
+
const lockPath2 = (0, import_path2.join)(projectDir, "uv.lock");
|
|
3166
|
+
if (!import_fs2.default.existsSync(lockPath2)) {
|
|
3167
|
+
await uvLock({ projectDir, uvPath });
|
|
3168
|
+
}
|
|
3169
|
+
} else if (manifestType === "Pipfile.lock" || manifestType === "Pipfile") {
|
|
3170
|
+
if (!manifestPath) {
|
|
3171
|
+
throw new Error(
|
|
3172
|
+
"Expected Pipfile/Pipfile.lock path to be resolved, but it was null"
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
projectDir = (0, import_path2.dirname)(manifestPath);
|
|
3176
|
+
console.log(`Installing required dependencies from ${manifestType}...`);
|
|
3177
|
+
const exportedReq = await exportRequirementsFromPipfile({
|
|
3178
|
+
pythonPath,
|
|
3179
|
+
pipPath,
|
|
3180
|
+
uvPath,
|
|
3181
|
+
projectDir,
|
|
3182
|
+
meta
|
|
3183
|
+
});
|
|
3184
|
+
pyprojectPath = (0, import_path2.join)(projectDir, "pyproject.toml");
|
|
3185
|
+
if (!import_fs2.default.existsSync(pyprojectPath)) {
|
|
3186
|
+
await createPyprojectToml({
|
|
3187
|
+
projectName: "app",
|
|
3188
|
+
pyprojectPath,
|
|
3189
|
+
dependencies: []
|
|
3190
|
+
});
|
|
3191
|
+
}
|
|
3192
|
+
await uvAddFromFile({
|
|
3193
|
+
projectDir,
|
|
3194
|
+
uvPath,
|
|
3195
|
+
venvPath,
|
|
3196
|
+
requirementsPath: exportedReq
|
|
3197
|
+
});
|
|
3198
|
+
} else if (manifestType === "requirements.txt") {
|
|
3199
|
+
if (!manifestPath) {
|
|
3200
|
+
throw new Error(
|
|
3201
|
+
"Expected requirements.txt path to be resolved, but it was null"
|
|
3202
|
+
);
|
|
3203
|
+
}
|
|
3204
|
+
projectDir = (0, import_path2.dirname)(manifestPath);
|
|
3205
|
+
pyprojectPath = (0, import_path2.join)(projectDir, "pyproject.toml");
|
|
3206
|
+
console.log(
|
|
3207
|
+
"Installing required dependencies from requirements.txt with uv..."
|
|
3208
|
+
);
|
|
3209
|
+
if (!import_fs2.default.existsSync(pyprojectPath)) {
|
|
3210
|
+
await createPyprojectToml({
|
|
3211
|
+
projectName: "app",
|
|
3212
|
+
pyprojectPath,
|
|
3213
|
+
dependencies: []
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
await uvAddFromFile({
|
|
3217
|
+
projectDir,
|
|
3218
|
+
uvPath,
|
|
3219
|
+
venvPath,
|
|
3220
|
+
requirementsPath: manifestPath
|
|
3221
|
+
});
|
|
3222
|
+
} else {
|
|
3223
|
+
projectDir = workPath;
|
|
3224
|
+
pyprojectPath = (0, import_path2.join)(projectDir, "pyproject.toml");
|
|
3225
|
+
console.log(
|
|
3226
|
+
"No Python manifest found; creating an empty pyproject.toml and uv.lock..."
|
|
3227
|
+
);
|
|
3228
|
+
await createPyprojectToml({
|
|
3229
|
+
projectName: "app",
|
|
3230
|
+
pyprojectPath,
|
|
3231
|
+
dependencies: []
|
|
3232
|
+
});
|
|
3233
|
+
await uvLock({ projectDir, uvPath });
|
|
3234
|
+
}
|
|
3235
|
+
if (runtimeDependencies.length) {
|
|
3236
|
+
const missingRuntimeDeps = await filterMissingRuntimeDependencies({
|
|
3237
|
+
pyprojectPath,
|
|
3238
|
+
runtimeDependencies
|
|
3239
|
+
});
|
|
3240
|
+
if (missingRuntimeDeps.length) {
|
|
3241
|
+
await uvAddDependencies({
|
|
3242
|
+
projectDir,
|
|
3243
|
+
uvPath,
|
|
3244
|
+
venvPath,
|
|
3245
|
+
dependencies: missingRuntimeDeps
|
|
3246
|
+
});
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
const lockPath = (0, import_path2.join)(projectDir, "uv.lock");
|
|
3250
|
+
if (!import_fs2.default.existsSync(lockPath)) {
|
|
3251
|
+
throw new Error(
|
|
3252
|
+
`Expected "uv.lock" to exist in "${projectDir}" after preparing uv project`
|
|
3253
|
+
);
|
|
3254
|
+
}
|
|
3255
|
+
return { projectDir, pyprojectPath, lockPath };
|
|
3256
|
+
}
|
|
2814
3257
|
async function getGlobalScriptsDir(pythonPath) {
|
|
2815
3258
|
const code = `import sysconfig; print(sysconfig.get_path('scripts'))`;
|
|
2816
3259
|
try {
|
|
@@ -2818,7 +3261,7 @@ async function getGlobalScriptsDir(pythonPath) {
|
|
|
2818
3261
|
const out = stdout.trim();
|
|
2819
3262
|
return out || null;
|
|
2820
3263
|
} catch (err) {
|
|
2821
|
-
(0,
|
|
3264
|
+
(0, import_build_utils2.debug)("Failed to resolve Python global scripts directory", err);
|
|
2822
3265
|
return null;
|
|
2823
3266
|
}
|
|
2824
3267
|
}
|
|
@@ -2832,12 +3275,12 @@ async function getUserScriptsDir(pythonPath) {
|
|
|
2832
3275
|
const out = stdout.trim();
|
|
2833
3276
|
return out || null;
|
|
2834
3277
|
} catch (err) {
|
|
2835
|
-
(0,
|
|
3278
|
+
(0, import_build_utils2.debug)("Failed to resolve Python user scripts directory", err);
|
|
2836
3279
|
return null;
|
|
2837
3280
|
}
|
|
2838
3281
|
}
|
|
2839
3282
|
async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
|
|
2840
|
-
const target = targetDir ? (0,
|
|
3283
|
+
const target = targetDir ? (0, import_path2.join)(targetDir, resolveVendorDir()) : resolveVendorDir();
|
|
2841
3284
|
process.env.PIP_USER = "0";
|
|
2842
3285
|
if (uvPath) {
|
|
2843
3286
|
const uvArgs = [
|
|
@@ -2847,10 +3290,10 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
|
|
|
2847
3290
|
"--no-cache-dir",
|
|
2848
3291
|
"--target",
|
|
2849
3292
|
target,
|
|
2850
|
-
...args
|
|
3293
|
+
...filterUnsafeUvPipArgs(args)
|
|
2851
3294
|
];
|
|
2852
3295
|
const prettyUv = `${uvPath} ${uvArgs.join(" ")}`;
|
|
2853
|
-
(0,
|
|
3296
|
+
(0, import_build_utils2.debug)(`Running "${prettyUv}"...`);
|
|
2854
3297
|
try {
|
|
2855
3298
|
await (0, import_execa.default)(uvPath, uvArgs, {
|
|
2856
3299
|
cwd: workPath
|
|
@@ -2858,7 +3301,7 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
|
|
|
2858
3301
|
return;
|
|
2859
3302
|
} catch (err) {
|
|
2860
3303
|
console.log(`Failed to run "${prettyUv}", falling back to pip`);
|
|
2861
|
-
(0,
|
|
3304
|
+
(0, import_build_utils2.debug)(`error: ${err}`);
|
|
2862
3305
|
}
|
|
2863
3306
|
}
|
|
2864
3307
|
const cmdArgs = [
|
|
@@ -2871,14 +3314,14 @@ async function pipInstall(pipPath, uvPath, workPath, args, targetDir) {
|
|
|
2871
3314
|
...args
|
|
2872
3315
|
];
|
|
2873
3316
|
const pretty = `${pipPath} ${cmdArgs.join(" ")}`;
|
|
2874
|
-
(0,
|
|
3317
|
+
(0, import_build_utils2.debug)(`Running "${pretty}"...`);
|
|
2875
3318
|
try {
|
|
2876
3319
|
await (0, import_execa.default)(pipPath, cmdArgs, {
|
|
2877
3320
|
cwd: workPath
|
|
2878
3321
|
});
|
|
2879
3322
|
} catch (err) {
|
|
2880
3323
|
console.log(`Failed to run "${pretty}"`);
|
|
2881
|
-
(0,
|
|
3324
|
+
(0, import_build_utils2.debug)(`error: ${err}`);
|
|
2882
3325
|
throw err;
|
|
2883
3326
|
}
|
|
2884
3327
|
}
|
|
@@ -2889,38 +3332,38 @@ async function maybeFindUvBin(pythonPath) {
|
|
|
2889
3332
|
try {
|
|
2890
3333
|
const globalScriptsDir = await getGlobalScriptsDir(pythonPath);
|
|
2891
3334
|
if (globalScriptsDir) {
|
|
2892
|
-
const uvPath = (0,
|
|
2893
|
-
if (
|
|
3335
|
+
const uvPath = (0, import_path2.join)(globalScriptsDir, uvExec);
|
|
3336
|
+
if (import_fs2.default.existsSync(uvPath))
|
|
2894
3337
|
return uvPath;
|
|
2895
3338
|
}
|
|
2896
3339
|
} catch (err) {
|
|
2897
|
-
(0,
|
|
3340
|
+
(0, import_build_utils2.debug)("Failed to resolve Python global scripts directory", err);
|
|
2898
3341
|
}
|
|
2899
3342
|
try {
|
|
2900
3343
|
const userScriptsDir = await getUserScriptsDir(pythonPath);
|
|
2901
3344
|
if (userScriptsDir) {
|
|
2902
|
-
const uvPath = (0,
|
|
2903
|
-
if (
|
|
3345
|
+
const uvPath = (0, import_path2.join)(userScriptsDir, uvExec);
|
|
3346
|
+
if (import_fs2.default.existsSync(uvPath))
|
|
2904
3347
|
return uvPath;
|
|
2905
3348
|
}
|
|
2906
3349
|
} catch (err) {
|
|
2907
|
-
(0,
|
|
3350
|
+
(0, import_build_utils2.debug)("Failed to resolve Python user scripts directory", err);
|
|
2908
3351
|
}
|
|
2909
3352
|
try {
|
|
2910
3353
|
const candidates = [];
|
|
2911
|
-
if (!
|
|
2912
|
-
candidates.push((0,
|
|
3354
|
+
if (!isWin2) {
|
|
3355
|
+
candidates.push((0, import_path2.join)(import_os.default.homedir(), ".local", "bin", "uv"));
|
|
2913
3356
|
candidates.push("/usr/local/bin/uv");
|
|
2914
3357
|
candidates.push("/opt/homebrew/bin/uv");
|
|
2915
3358
|
} else {
|
|
2916
3359
|
candidates.push("C:\\Users\\Public\\uv\\uv.exe");
|
|
2917
3360
|
}
|
|
2918
3361
|
for (const p of candidates) {
|
|
2919
|
-
if (
|
|
3362
|
+
if (import_fs2.default.existsSync(p))
|
|
2920
3363
|
return p;
|
|
2921
3364
|
}
|
|
2922
3365
|
} catch (err) {
|
|
2923
|
-
(0,
|
|
3366
|
+
(0, import_build_utils2.debug)("Failed to resolve uv fallback paths", err);
|
|
2924
3367
|
}
|
|
2925
3368
|
return null;
|
|
2926
3369
|
}
|
|
@@ -2968,7 +3411,7 @@ async function installRequirement({
|
|
|
2968
3411
|
}) {
|
|
2969
3412
|
const actualTargetDir = targetDir || workPath;
|
|
2970
3413
|
if (meta.isDev && await isInstalled(pythonPath, dependency, actualTargetDir)) {
|
|
2971
|
-
(0,
|
|
3414
|
+
(0, import_build_utils2.debug)(
|
|
2972
3415
|
`Skipping ${dependency} dependency installation, already installed in ${actualTargetDir}`
|
|
2973
3416
|
);
|
|
2974
3417
|
return;
|
|
@@ -2988,7 +3431,7 @@ async function installRequirementsFile({
|
|
|
2988
3431
|
}) {
|
|
2989
3432
|
const actualTargetDir = targetDir || workPath;
|
|
2990
3433
|
if (meta.isDev && await areRequirementsInstalled(pythonPath, filePath, actualTargetDir)) {
|
|
2991
|
-
(0,
|
|
3434
|
+
(0, import_build_utils2.debug)(`Skipping requirements file installation, already installed`);
|
|
2992
3435
|
return;
|
|
2993
3436
|
}
|
|
2994
3437
|
await pipInstall(
|
|
@@ -2999,35 +3442,8 @@ async function installRequirementsFile({
|
|
|
2999
3442
|
targetDir
|
|
3000
3443
|
);
|
|
3001
3444
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
if (!uvPath) {
|
|
3005
|
-
throw new Error("uv is not available to export requirements");
|
|
3006
|
-
}
|
|
3007
|
-
const args = [
|
|
3008
|
-
"export",
|
|
3009
|
-
"--no-default-groups",
|
|
3010
|
-
"--no-emit-workspace",
|
|
3011
|
-
"--no-editable"
|
|
3012
|
-
];
|
|
3013
|
-
if (locked) {
|
|
3014
|
-
args.push("--frozen");
|
|
3015
|
-
}
|
|
3016
|
-
(0, import_build_utils.debug)(`Running "${uvPath} ${args.join(" ")}" in ${projectDir}...`);
|
|
3017
|
-
let stdout;
|
|
3018
|
-
try {
|
|
3019
|
-
const { stdout: out } = await (0, import_execa.default)(uvPath, args, { cwd: projectDir });
|
|
3020
|
-
stdout = out;
|
|
3021
|
-
} catch (err) {
|
|
3022
|
-
throw new Error(
|
|
3023
|
-
`Failed to run "${uvPath} ${args.join(" ")}": ${err instanceof Error ? err.message : String(err)}`
|
|
3024
|
-
);
|
|
3025
|
-
}
|
|
3026
|
-
const tmpDir = await import_fs.default.promises.mkdtemp((0, import_path.join)(import_os.default.tmpdir(), "vercel-uv-"));
|
|
3027
|
-
const outPath = (0, import_path.join)(tmpDir, "requirements.uv.txt");
|
|
3028
|
-
await import_fs.default.promises.writeFile(outPath, stdout);
|
|
3029
|
-
(0, import_build_utils.debug)(`Exported requirements to ${outPath}`);
|
|
3030
|
-
return outPath;
|
|
3445
|
+
function filterUnsafeUvPipArgs(args) {
|
|
3446
|
+
return args.filter((arg) => arg !== "--no-warn-script-location");
|
|
3031
3447
|
}
|
|
3032
3448
|
async function exportRequirementsFromPipfile({
|
|
3033
3449
|
pythonPath,
|
|
@@ -3036,8 +3452,8 @@ async function exportRequirementsFromPipfile({
|
|
|
3036
3452
|
projectDir,
|
|
3037
3453
|
meta
|
|
3038
3454
|
}) {
|
|
3039
|
-
const tempDir = await
|
|
3040
|
-
(0,
|
|
3455
|
+
const tempDir = await import_fs2.default.promises.mkdtemp(
|
|
3456
|
+
(0, import_path2.join)(import_os.default.tmpdir(), "vercel-pipenv-")
|
|
3041
3457
|
);
|
|
3042
3458
|
await installRequirement({
|
|
3043
3459
|
pythonPath,
|
|
@@ -3049,9 +3465,9 @@ async function exportRequirementsFromPipfile({
|
|
|
3049
3465
|
args: ["--no-warn-script-location"],
|
|
3050
3466
|
uvPath
|
|
3051
3467
|
});
|
|
3052
|
-
const tempVendorDir = (0,
|
|
3053
|
-
const convertCmd =
|
|
3054
|
-
(0,
|
|
3468
|
+
const tempVendorDir = (0, import_path2.join)(tempDir, resolveVendorDir());
|
|
3469
|
+
const convertCmd = isWin2 ? (0, import_path2.join)(tempVendorDir, "Scripts", "pipfile2req.exe") : (0, import_path2.join)(tempVendorDir, "bin", "pipfile2req");
|
|
3470
|
+
(0, import_build_utils2.debug)(`Running "${convertCmd}" in ${projectDir}...`);
|
|
3055
3471
|
let stdout;
|
|
3056
3472
|
try {
|
|
3057
3473
|
const { stdout: out } = await (0, import_execa.default)(convertCmd, [], {
|
|
@@ -3064,17 +3480,46 @@ async function exportRequirementsFromPipfile({
|
|
|
3064
3480
|
`Failed to run "${convertCmd}": ${err instanceof Error ? err.message : String(err)}`
|
|
3065
3481
|
);
|
|
3066
3482
|
}
|
|
3067
|
-
const outPath = (0,
|
|
3068
|
-
await
|
|
3069
|
-
(0,
|
|
3483
|
+
const outPath = (0, import_path2.join)(tempDir, "requirements.pipenv.txt");
|
|
3484
|
+
await import_fs2.default.promises.writeFile(outPath, stdout);
|
|
3485
|
+
(0, import_build_utils2.debug)(`Exported pipfile requirements to ${outPath}`);
|
|
3070
3486
|
return outPath;
|
|
3071
3487
|
}
|
|
3488
|
+
async function mirrorSitePackagesIntoVendor({
|
|
3489
|
+
venvPath,
|
|
3490
|
+
vendorDirName
|
|
3491
|
+
}) {
|
|
3492
|
+
const vendorFiles = {};
|
|
3493
|
+
try {
|
|
3494
|
+
const sitePackageDirs = await getVenvSitePackagesDirs(venvPath);
|
|
3495
|
+
for (const dir of sitePackageDirs) {
|
|
3496
|
+
if (!import_fs2.default.existsSync(dir))
|
|
3497
|
+
continue;
|
|
3498
|
+
const dirFiles = await (0, import_build_utils2.glob)("**", dir);
|
|
3499
|
+
for (const relativePath of Object.keys(dirFiles)) {
|
|
3500
|
+
if (relativePath.endsWith(".pyc") || relativePath.includes("__pycache__")) {
|
|
3501
|
+
continue;
|
|
3502
|
+
}
|
|
3503
|
+
const srcFsPath = (0, import_path2.join)(dir, relativePath);
|
|
3504
|
+
const bundlePath = (0, import_path2.join)(vendorDirName, relativePath).replace(
|
|
3505
|
+
/\\/g,
|
|
3506
|
+
"/"
|
|
3507
|
+
);
|
|
3508
|
+
vendorFiles[bundlePath] = new import_build_utils2.FileFsRef({ fsPath: srcFsPath });
|
|
3509
|
+
}
|
|
3510
|
+
}
|
|
3511
|
+
} catch (err) {
|
|
3512
|
+
console.log("Failed to collect site-packages from virtual environment");
|
|
3513
|
+
throw err;
|
|
3514
|
+
}
|
|
3515
|
+
return vendorFiles;
|
|
3516
|
+
}
|
|
3072
3517
|
|
|
3073
3518
|
// src/index.ts
|
|
3074
|
-
var
|
|
3519
|
+
var import_build_utils8 = require("@vercel/build-utils");
|
|
3075
3520
|
|
|
3076
3521
|
// src/version.ts
|
|
3077
|
-
var
|
|
3522
|
+
var import_build_utils3 = require("@vercel/build-utils");
|
|
3078
3523
|
var import_which2 = __toESM(require_lib());
|
|
3079
3524
|
var allOptions = [
|
|
3080
3525
|
{
|
|
@@ -3125,7 +3570,7 @@ function getLatestPythonVersion({
|
|
|
3125
3570
|
}
|
|
3126
3571
|
const selection = allOptions.find(isInstalled2);
|
|
3127
3572
|
if (!selection) {
|
|
3128
|
-
throw new
|
|
3573
|
+
throw new import_build_utils3.NowBuildError({
|
|
3129
3574
|
code: "PYTHON_NOT_FOUND",
|
|
3130
3575
|
link: "http://vercel.link/python-version",
|
|
3131
3576
|
message: `Unable to find any supported Python versions.`
|
|
@@ -3226,7 +3671,7 @@ function getSupportedPythonVersion({
|
|
|
3226
3671
|
}
|
|
3227
3672
|
if (requested) {
|
|
3228
3673
|
if (isDiscontinued(requested)) {
|
|
3229
|
-
throw new
|
|
3674
|
+
throw new import_build_utils3.NowBuildError({
|
|
3230
3675
|
code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
|
|
3231
3676
|
link: "http://vercel.link/python-version",
|
|
3232
3677
|
message: `Python version "${requested.version}" detected in ${source} is discontinued and must be upgraded.`
|
|
@@ -3257,7 +3702,7 @@ function getSupportedPythonVersion({
|
|
|
3257
3702
|
);
|
|
3258
3703
|
}
|
|
3259
3704
|
if (isDiscontinued(selection)) {
|
|
3260
|
-
throw new
|
|
3705
|
+
throw new import_build_utils3.NowBuildError({
|
|
3261
3706
|
code: "BUILD_UTILS_PYTHON_VERSION_DISCONTINUED",
|
|
3262
3707
|
link: "http://vercel.link/python-version",
|
|
3263
3708
|
message: `Python version "${selection.version}" declared in project configuration is discontinued and must be upgraded.`
|
|
@@ -3287,16 +3732,16 @@ var import_path4 = require("path");
|
|
|
3287
3732
|
var import_build_utils6 = require("@vercel/build-utils");
|
|
3288
3733
|
|
|
3289
3734
|
// src/entrypoint.ts
|
|
3290
|
-
var
|
|
3291
|
-
var
|
|
3292
|
-
var import_build_utils3 = require("@vercel/build-utils");
|
|
3735
|
+
var import_fs3 = __toESM(require("fs"));
|
|
3736
|
+
var import_path3 = require("path");
|
|
3293
3737
|
var import_build_utils4 = require("@vercel/build-utils");
|
|
3738
|
+
var import_build_utils5 = require("@vercel/build-utils");
|
|
3294
3739
|
var FASTAPI_ENTRYPOINT_FILENAMES = ["app", "index", "server", "main"];
|
|
3295
3740
|
var FASTAPI_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
|
|
3296
3741
|
var FASTAPI_CONTENT_REGEX = /(from\s+fastapi\s+import\s+FastAPI|import\s+fastapi|FastAPI\s*\()/;
|
|
3297
3742
|
var FASTAPI_CANDIDATE_ENTRYPOINTS = FASTAPI_ENTRYPOINT_FILENAMES.flatMap(
|
|
3298
3743
|
(filename) => FASTAPI_ENTRYPOINT_DIRS.map(
|
|
3299
|
-
(dir) =>
|
|
3744
|
+
(dir) => import_path3.posix.join(dir, `${filename}.py`)
|
|
3300
3745
|
)
|
|
3301
3746
|
);
|
|
3302
3747
|
function isFastapiEntrypoint(file) {
|
|
@@ -3304,7 +3749,7 @@ function isFastapiEntrypoint(file) {
|
|
|
3304
3749
|
const fsPath = file.fsPath;
|
|
3305
3750
|
if (!fsPath)
|
|
3306
3751
|
return false;
|
|
3307
|
-
const contents =
|
|
3752
|
+
const contents = import_fs3.default.readFileSync(fsPath, "utf8");
|
|
3308
3753
|
return FASTAPI_CONTENT_REGEX.test(contents);
|
|
3309
3754
|
} catch {
|
|
3310
3755
|
return false;
|
|
@@ -3315,7 +3760,7 @@ var FLASK_ENTRYPOINT_DIRS = ["", "src", "app", "api"];
|
|
|
3315
3760
|
var FLASK_CONTENT_REGEX = /(from\s+flask\s+import\s+Flask|import\s+flask|Flask\s*\()/;
|
|
3316
3761
|
var FLASK_CANDIDATE_ENTRYPOINTS = FLASK_ENTRYPOINT_FILENAMES.flatMap(
|
|
3317
3762
|
(filename) => FLASK_ENTRYPOINT_DIRS.map(
|
|
3318
|
-
(dir) =>
|
|
3763
|
+
(dir) => import_path3.posix.join(dir, `${filename}.py`)
|
|
3319
3764
|
)
|
|
3320
3765
|
);
|
|
3321
3766
|
function isFlaskEntrypoint(file) {
|
|
@@ -3323,7 +3768,7 @@ function isFlaskEntrypoint(file) {
|
|
|
3323
3768
|
const fsPath = file.fsPath;
|
|
3324
3769
|
if (!fsPath)
|
|
3325
3770
|
return false;
|
|
3326
|
-
const contents =
|
|
3771
|
+
const contents = import_fs3.default.readFileSync(fsPath, "utf8");
|
|
3327
3772
|
return FLASK_CONTENT_REGEX.test(contents);
|
|
3328
3773
|
} catch {
|
|
3329
3774
|
return false;
|
|
@@ -3332,7 +3777,7 @@ function isFlaskEntrypoint(file) {
|
|
|
3332
3777
|
async function detectFlaskEntrypoint(workPath, configuredEntrypoint) {
|
|
3333
3778
|
const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
|
|
3334
3779
|
try {
|
|
3335
|
-
const fsFiles = await (0,
|
|
3780
|
+
const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
|
|
3336
3781
|
if (fsFiles[entry])
|
|
3337
3782
|
return entry;
|
|
3338
3783
|
const candidates = FLASK_CANDIDATE_ENTRYPOINTS.filter(
|
|
@@ -3342,19 +3787,19 @@ async function detectFlaskEntrypoint(workPath, configuredEntrypoint) {
|
|
|
3342
3787
|
const flaskEntrypoint = candidates.find(
|
|
3343
3788
|
(c) => isFlaskEntrypoint(fsFiles[c])
|
|
3344
3789
|
) || candidates[0];
|
|
3345
|
-
(0,
|
|
3790
|
+
(0, import_build_utils4.debug)(`Detected Flask entrypoint: ${flaskEntrypoint}`);
|
|
3346
3791
|
return flaskEntrypoint;
|
|
3347
3792
|
}
|
|
3348
3793
|
return null;
|
|
3349
3794
|
} catch {
|
|
3350
|
-
(0,
|
|
3795
|
+
(0, import_build_utils4.debug)("Failed to discover entrypoint for Flask");
|
|
3351
3796
|
return null;
|
|
3352
3797
|
}
|
|
3353
3798
|
}
|
|
3354
3799
|
async function detectFastapiEntrypoint(workPath, configuredEntrypoint) {
|
|
3355
3800
|
const entry = configuredEntrypoint.endsWith(".py") ? configuredEntrypoint : `${configuredEntrypoint}.py`;
|
|
3356
3801
|
try {
|
|
3357
|
-
const fsFiles = await (0,
|
|
3802
|
+
const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
|
|
3358
3803
|
if (fsFiles[entry])
|
|
3359
3804
|
return entry;
|
|
3360
3805
|
const candidates = FASTAPI_CANDIDATE_ENTRYPOINTS.filter(
|
|
@@ -3364,17 +3809,17 @@ async function detectFastapiEntrypoint(workPath, configuredEntrypoint) {
|
|
|
3364
3809
|
const fastapiEntrypoint = candidates.find(
|
|
3365
3810
|
(c) => isFastapiEntrypoint(fsFiles[c])
|
|
3366
3811
|
) || candidates[0];
|
|
3367
|
-
(0,
|
|
3812
|
+
(0, import_build_utils4.debug)(`Detected FastAPI entrypoint: ${fastapiEntrypoint}`);
|
|
3368
3813
|
return fastapiEntrypoint;
|
|
3369
3814
|
}
|
|
3370
3815
|
return null;
|
|
3371
3816
|
} catch {
|
|
3372
|
-
(0,
|
|
3817
|
+
(0, import_build_utils4.debug)("Failed to discover entrypoint for FastAPI");
|
|
3373
3818
|
return null;
|
|
3374
3819
|
}
|
|
3375
3820
|
}
|
|
3376
3821
|
async function getPyprojectEntrypoint(workPath) {
|
|
3377
|
-
const pyprojectData = await (0,
|
|
3822
|
+
const pyprojectData = await (0, import_build_utils5.readConfigFile)((0, import_path3.join)(workPath, "pyproject.toml"));
|
|
3378
3823
|
if (!pyprojectData)
|
|
3379
3824
|
return null;
|
|
3380
3825
|
const scripts = pyprojectData.project?.scripts;
|
|
@@ -3387,7 +3832,7 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
3387
3832
|
const modulePath = match[1];
|
|
3388
3833
|
const relPath = modulePath.replace(/\./g, "/");
|
|
3389
3834
|
try {
|
|
3390
|
-
const fsFiles = await (0,
|
|
3835
|
+
const fsFiles = await (0, import_build_utils4.glob)("**", workPath);
|
|
3391
3836
|
const candidates = [`${relPath}.py`, `${relPath}/__init__.py`];
|
|
3392
3837
|
for (const candidate of candidates) {
|
|
3393
3838
|
if (fsFiles[candidate])
|
|
@@ -3395,7 +3840,7 @@ async function getPyprojectEntrypoint(workPath) {
|
|
|
3395
3840
|
}
|
|
3396
3841
|
return null;
|
|
3397
3842
|
} catch {
|
|
3398
|
-
(0,
|
|
3843
|
+
(0, import_build_utils4.debug)("Failed to discover Python entrypoint from pyproject.toml");
|
|
3399
3844
|
return null;
|
|
3400
3845
|
}
|
|
3401
3846
|
}
|
|
@@ -3411,61 +3856,6 @@ async function detectPythonEntrypoint(framework, workPath, configuredEntrypoint)
|
|
|
3411
3856
|
return await getPyprojectEntrypoint(workPath);
|
|
3412
3857
|
}
|
|
3413
3858
|
|
|
3414
|
-
// src/utils.ts
|
|
3415
|
-
var import_fs3 = __toESM(require("fs"));
|
|
3416
|
-
var import_path3 = require("path");
|
|
3417
|
-
var import_build_utils5 = require("@vercel/build-utils");
|
|
3418
|
-
var isInVirtualEnv = () => {
|
|
3419
|
-
return process.env.VIRTUAL_ENV;
|
|
3420
|
-
};
|
|
3421
|
-
function useVirtualEnv(workPath, env, systemPython) {
|
|
3422
|
-
const venvDirs = [".venv", "venv"];
|
|
3423
|
-
let pythonCmd = systemPython;
|
|
3424
|
-
for (const venv of venvDirs) {
|
|
3425
|
-
const venvRoot = (0, import_path3.join)(workPath, venv);
|
|
3426
|
-
const binDir = process.platform === "win32" ? (0, import_path3.join)(venvRoot, "Scripts") : (0, import_path3.join)(venvRoot, "bin");
|
|
3427
|
-
const candidates = process.platform === "win32" ? [(0, import_path3.join)(binDir, "python.exe"), (0, import_path3.join)(binDir, "python")] : [(0, import_path3.join)(binDir, "python3"), (0, import_path3.join)(binDir, "python")];
|
|
3428
|
-
const found = candidates.find((p) => import_fs3.default.existsSync(p));
|
|
3429
|
-
if (found) {
|
|
3430
|
-
pythonCmd = found;
|
|
3431
|
-
env.VIRTUAL_ENV = venvRoot;
|
|
3432
|
-
env.PATH = `${binDir}${import_path3.delimiter}${env.PATH || ""}`;
|
|
3433
|
-
return { pythonCmd, venvRoot };
|
|
3434
|
-
}
|
|
3435
|
-
}
|
|
3436
|
-
return { pythonCmd };
|
|
3437
|
-
}
|
|
3438
|
-
async function runPyprojectScript(workPath, scriptNames, env) {
|
|
3439
|
-
const pyprojectPath = (0, import_path3.join)(workPath, "pyproject.toml");
|
|
3440
|
-
if (!import_fs3.default.existsSync(pyprojectPath))
|
|
3441
|
-
return false;
|
|
3442
|
-
let pyproject = null;
|
|
3443
|
-
try {
|
|
3444
|
-
pyproject = await (0, import_build_utils5.readConfigFile)(pyprojectPath);
|
|
3445
|
-
} catch {
|
|
3446
|
-
console.error("Failed to parse pyproject.toml");
|
|
3447
|
-
return false;
|
|
3448
|
-
}
|
|
3449
|
-
const scripts = pyproject?.tool?.vercel?.scripts || {};
|
|
3450
|
-
const candidates = typeof scriptNames === "string" ? [scriptNames] : Array.from(scriptNames);
|
|
3451
|
-
const scriptToRun = candidates.find((name) => Boolean(scripts[name]));
|
|
3452
|
-
if (!scriptToRun)
|
|
3453
|
-
return false;
|
|
3454
|
-
const systemPython = process.platform === "win32" ? "python" : "python3";
|
|
3455
|
-
const finalEnv = { ...process.env, ...env };
|
|
3456
|
-
useVirtualEnv(workPath, finalEnv, systemPython);
|
|
3457
|
-
const scriptCommand = scripts[scriptToRun];
|
|
3458
|
-
if (typeof scriptCommand === "string" && scriptCommand.trim()) {
|
|
3459
|
-
console.log(`Executing: ${scriptCommand}`);
|
|
3460
|
-
await (0, import_build_utils5.execCommand)(scriptCommand, {
|
|
3461
|
-
cwd: workPath,
|
|
3462
|
-
env: finalEnv
|
|
3463
|
-
});
|
|
3464
|
-
return true;
|
|
3465
|
-
}
|
|
3466
|
-
return false;
|
|
3467
|
-
}
|
|
3468
|
-
|
|
3469
3859
|
// src/start-dev-server.ts
|
|
3470
3860
|
function silenceNodeWarnings() {
|
|
3471
3861
|
const original = process.emitWarning.bind(
|
|
@@ -3835,153 +4225,29 @@ If you are using a virtual environment, activate it before running "vercel dev",
|
|
|
3835
4225
|
}
|
|
3836
4226
|
};
|
|
3837
4227
|
|
|
3838
|
-
// src/uv-workspace.ts
|
|
3839
|
-
var import_fs5 = __toESM(require("fs"));
|
|
3840
|
-
var import_os2 = __toESM(require("os"));
|
|
3841
|
-
var import_path5 = require("path");
|
|
3842
|
-
var import_build_utils7 = require("@vercel/build-utils");
|
|
3843
|
-
function getDependencyName(spec) {
|
|
3844
|
-
const match = spec.match(/^[A-Za-z0-9_.-]+/);
|
|
3845
|
-
return match ? match[0] : null;
|
|
3846
|
-
}
|
|
3847
|
-
async function installUvWorkspaceDependencies({
|
|
3848
|
-
repoRootPath,
|
|
3849
|
-
pyprojectDir,
|
|
3850
|
-
pythonPath,
|
|
3851
|
-
pipPath,
|
|
3852
|
-
uvPath,
|
|
3853
|
-
workPath,
|
|
3854
|
-
vendorBaseDir,
|
|
3855
|
-
meta
|
|
3856
|
-
}) {
|
|
3857
|
-
if (!repoRootPath || !pyprojectDir) {
|
|
3858
|
-
return;
|
|
3859
|
-
}
|
|
3860
|
-
let rootPyproject = null;
|
|
3861
|
-
try {
|
|
3862
|
-
rootPyproject = await (0, import_build_utils7.readConfigFile)(
|
|
3863
|
-
(0, import_path5.join)(repoRootPath, "pyproject.toml")
|
|
3864
|
-
);
|
|
3865
|
-
} catch (err) {
|
|
3866
|
-
(0, import_build_utils7.debug)("Failed to parse workspace root pyproject.toml", err);
|
|
3867
|
-
}
|
|
3868
|
-
const uvTool = rootPyproject?.tool?.uv;
|
|
3869
|
-
const workspaceCfg = uvTool?.workspace;
|
|
3870
|
-
const sourcesCfg = uvTool?.sources;
|
|
3871
|
-
if (!workspaceCfg || !sourcesCfg) {
|
|
3872
|
-
return;
|
|
3873
|
-
}
|
|
3874
|
-
const workspaceSourceNames = new Set(
|
|
3875
|
-
Object.entries(sourcesCfg).filter(([, src]) => src && src.workspace).map(([name]) => name)
|
|
3876
|
-
);
|
|
3877
|
-
if (!workspaceSourceNames.size) {
|
|
3878
|
-
return;
|
|
3879
|
-
}
|
|
3880
|
-
let appPyproject = null;
|
|
3881
|
-
try {
|
|
3882
|
-
appPyproject = await (0, import_build_utils7.readConfigFile)(
|
|
3883
|
-
(0, import_path5.join)(pyprojectDir, "pyproject.toml")
|
|
3884
|
-
);
|
|
3885
|
-
} catch (err) {
|
|
3886
|
-
(0, import_build_utils7.debug)("Failed to parse app pyproject.toml for workspace deps", err);
|
|
3887
|
-
}
|
|
3888
|
-
const appDeps = appPyproject?.project?.dependencies ?? [];
|
|
3889
|
-
const workspaceDepsForApp = /* @__PURE__ */ new Set();
|
|
3890
|
-
for (const spec of appDeps) {
|
|
3891
|
-
const name = getDependencyName(spec);
|
|
3892
|
-
if (name && workspaceSourceNames.has(name)) {
|
|
3893
|
-
workspaceDepsForApp.add(name);
|
|
3894
|
-
}
|
|
3895
|
-
}
|
|
3896
|
-
if (!workspaceDepsForApp.size) {
|
|
3897
|
-
return;
|
|
3898
|
-
}
|
|
3899
|
-
const members = workspaceCfg.members ?? [];
|
|
3900
|
-
const nameToDir = /* @__PURE__ */ new Map();
|
|
3901
|
-
for (const member of members) {
|
|
3902
|
-
const memberDir = (0, import_path5.join)(repoRootPath, member);
|
|
3903
|
-
let memberPyproject = null;
|
|
3904
|
-
try {
|
|
3905
|
-
memberPyproject = await (0, import_build_utils7.readConfigFile)(
|
|
3906
|
-
(0, import_path5.join)(memberDir, "pyproject.toml")
|
|
3907
|
-
);
|
|
3908
|
-
} catch (err) {
|
|
3909
|
-
(0, import_build_utils7.debug)("Failed to parse workspace member pyproject.toml", err);
|
|
3910
|
-
continue;
|
|
3911
|
-
}
|
|
3912
|
-
const projectName = memberPyproject?.project?.name;
|
|
3913
|
-
if (projectName) {
|
|
3914
|
-
nameToDir.set(projectName, memberDir);
|
|
3915
|
-
}
|
|
3916
|
-
}
|
|
3917
|
-
const requirementLines = [];
|
|
3918
|
-
for (const name of workspaceDepsForApp) {
|
|
3919
|
-
const dir = nameToDir.get(name);
|
|
3920
|
-
if (!dir) {
|
|
3921
|
-
(0, import_build_utils7.debug)(
|
|
3922
|
-
`uv workspace dependency "${name}" declared but corresponding member directory not found`
|
|
3923
|
-
);
|
|
3924
|
-
continue;
|
|
3925
|
-
}
|
|
3926
|
-
requirementLines.push(dir);
|
|
3927
|
-
}
|
|
3928
|
-
if (!requirementLines.length) {
|
|
3929
|
-
return;
|
|
3930
|
-
}
|
|
3931
|
-
const tmpDir = await import_fs5.default.promises.mkdtemp(
|
|
3932
|
-
(0, import_path5.join)(import_os2.default.tmpdir(), "vercel-uv-workspace-")
|
|
3933
|
-
);
|
|
3934
|
-
const reqPath = (0, import_path5.join)(tmpDir, "requirements.workspace.txt");
|
|
3935
|
-
await import_fs5.default.promises.writeFile(reqPath, requirementLines.join("\n"));
|
|
3936
|
-
await installRequirementsFile({
|
|
3937
|
-
pythonPath,
|
|
3938
|
-
pipPath,
|
|
3939
|
-
uvPath,
|
|
3940
|
-
filePath: reqPath,
|
|
3941
|
-
workPath,
|
|
3942
|
-
targetDir: vendorBaseDir,
|
|
3943
|
-
meta
|
|
3944
|
-
});
|
|
3945
|
-
}
|
|
3946
|
-
|
|
3947
4228
|
// src/index.ts
|
|
3948
|
-
var readFile = (0, import_util.promisify)(
|
|
3949
|
-
var writeFile = (0, import_util.promisify)(
|
|
4229
|
+
var readFile = (0, import_util.promisify)(import_fs5.default.readFile);
|
|
4230
|
+
var writeFile = (0, import_util.promisify)(import_fs5.default.writeFile);
|
|
3950
4231
|
var version = 3;
|
|
3951
|
-
function findDir({
|
|
3952
|
-
file,
|
|
3953
|
-
entryDirectory,
|
|
3954
|
-
workPath,
|
|
3955
|
-
fsFiles
|
|
3956
|
-
}) {
|
|
3957
|
-
if (fsFiles[(0, import_path6.join)(entryDirectory, file)]) {
|
|
3958
|
-
return (0, import_path6.join)(workPath, entryDirectory);
|
|
3959
|
-
}
|
|
3960
|
-
if (fsFiles[file]) {
|
|
3961
|
-
return workPath;
|
|
3962
|
-
}
|
|
3963
|
-
return null;
|
|
3964
|
-
}
|
|
3965
4232
|
async function downloadFilesInWorkPath({
|
|
3966
4233
|
entrypoint,
|
|
3967
4234
|
workPath,
|
|
3968
4235
|
files,
|
|
3969
4236
|
meta = {}
|
|
3970
4237
|
}) {
|
|
3971
|
-
(0,
|
|
3972
|
-
let downloadedFiles = await (0,
|
|
4238
|
+
(0, import_build_utils7.debug)("Downloading user files...");
|
|
4239
|
+
let downloadedFiles = await (0, import_build_utils7.download)(files, workPath, meta);
|
|
3973
4240
|
if (meta.isDev) {
|
|
3974
|
-
const { devCacheDir = (0,
|
|
3975
|
-
const destCache = (0,
|
|
3976
|
-
await (0,
|
|
3977
|
-
downloadedFiles = await (0,
|
|
4241
|
+
const { devCacheDir = (0, import_path5.join)(workPath, ".now", "cache") } = meta;
|
|
4242
|
+
const destCache = (0, import_path5.join)(devCacheDir, (0, import_path5.basename)(entrypoint, ".py"));
|
|
4243
|
+
await (0, import_build_utils7.download)(downloadedFiles, destCache);
|
|
4244
|
+
downloadedFiles = await (0, import_build_utils7.glob)("**", destCache);
|
|
3978
4245
|
workPath = destCache;
|
|
3979
4246
|
}
|
|
3980
4247
|
return workPath;
|
|
3981
4248
|
}
|
|
3982
4249
|
var build = async ({
|
|
3983
4250
|
workPath,
|
|
3984
|
-
repoRootPath,
|
|
3985
4251
|
files: originalFiles,
|
|
3986
4252
|
entrypoint,
|
|
3987
4253
|
meta = {},
|
|
@@ -3996,7 +4262,7 @@ var build = async ({
|
|
|
3996
4262
|
});
|
|
3997
4263
|
try {
|
|
3998
4264
|
if (meta.isDev) {
|
|
3999
|
-
const setupCfg = (0,
|
|
4265
|
+
const setupCfg = (0, import_path5.join)(workPath, "setup.cfg");
|
|
4000
4266
|
await writeFile(setupCfg, "[install]\nprefix=\n");
|
|
4001
4267
|
}
|
|
4002
4268
|
} catch (err) {
|
|
@@ -4009,8 +4275,8 @@ var build = async ({
|
|
|
4009
4275
|
lockfileVersion,
|
|
4010
4276
|
packageJsonPackageManager,
|
|
4011
4277
|
turboSupportsCorepackHome
|
|
4012
|
-
} = await (0,
|
|
4013
|
-
const spawnEnv = (0,
|
|
4278
|
+
} = await (0, import_build_utils7.scanParentDirs)(workPath, true);
|
|
4279
|
+
const spawnEnv = (0, import_build_utils7.getEnvForPackageManager)({
|
|
4014
4280
|
cliType,
|
|
4015
4281
|
lockfileVersion,
|
|
4016
4282
|
packageJsonPackageManager,
|
|
@@ -4022,7 +4288,7 @@ var build = async ({
|
|
|
4022
4288
|
if (typeof installCommand === "string") {
|
|
4023
4289
|
if (installCommand.trim()) {
|
|
4024
4290
|
console.log(`Running "install" command: \`${installCommand}\`...`);
|
|
4025
|
-
await (0,
|
|
4291
|
+
await (0, import_build_utils7.execCommand)(installCommand, {
|
|
4026
4292
|
env: spawnEnv,
|
|
4027
4293
|
cwd: workPath
|
|
4028
4294
|
});
|
|
@@ -4034,7 +4300,7 @@ var build = async ({
|
|
|
4034
4300
|
config?.buildCommand;
|
|
4035
4301
|
if (projectBuildCommand) {
|
|
4036
4302
|
console.log(`Running "${projectBuildCommand}"`);
|
|
4037
|
-
await (0,
|
|
4303
|
+
await (0, import_build_utils7.execCommand)(projectBuildCommand, {
|
|
4038
4304
|
env: spawnEnv,
|
|
4039
4305
|
cwd: workPath
|
|
4040
4306
|
});
|
|
@@ -4046,7 +4312,7 @@ var build = async ({
|
|
|
4046
4312
|
);
|
|
4047
4313
|
}
|
|
4048
4314
|
}
|
|
4049
|
-
let fsFiles = await (0,
|
|
4315
|
+
let fsFiles = await (0, import_build_utils7.glob)("**", workPath);
|
|
4050
4316
|
if ((framework === "fastapi" || framework === "flask") && (!fsFiles[entrypoint] || !entrypoint.endsWith(".py"))) {
|
|
4051
4317
|
const detected = await detectPythonEntrypoint(
|
|
4052
4318
|
config.framework,
|
|
@@ -4054,13 +4320,13 @@ var build = async ({
|
|
|
4054
4320
|
entrypoint
|
|
4055
4321
|
);
|
|
4056
4322
|
if (detected) {
|
|
4057
|
-
(0,
|
|
4323
|
+
(0, import_build_utils7.debug)(
|
|
4058
4324
|
`Resolved Python entrypoint to "${detected}" (configured "${entrypoint}" not found).`
|
|
4059
4325
|
);
|
|
4060
4326
|
entrypoint = detected;
|
|
4061
4327
|
} else {
|
|
4062
4328
|
const searchedList = framework === "fastapi" ? FASTAPI_CANDIDATE_ENTRYPOINTS.join(", ") : FLASK_CANDIDATE_ENTRYPOINTS.join(", ");
|
|
4063
|
-
throw new
|
|
4329
|
+
throw new import_build_utils7.NowBuildError({
|
|
4064
4330
|
code: `${framework.toUpperCase()}_ENTRYPOINT_NOT_FOUND`,
|
|
4065
4331
|
message: `No ${framework} entrypoint found. Add an 'app' script in pyproject.toml or define an entrypoint in one of: ${searchedList}.`,
|
|
4066
4332
|
link: `https://vercel.com/docs/frameworks/backend/${framework}#exporting-the-${framework}-application`,
|
|
@@ -4068,46 +4334,42 @@ var build = async ({
|
|
|
4068
4334
|
});
|
|
4069
4335
|
}
|
|
4070
4336
|
}
|
|
4071
|
-
const entryDirectory = (0,
|
|
4072
|
-
const
|
|
4073
|
-
|
|
4074
|
-
const uvLockDir = findDir({
|
|
4075
|
-
file: "uv.lock",
|
|
4337
|
+
const entryDirectory = (0, import_path5.dirname)(entrypoint);
|
|
4338
|
+
const pyprojectDir = findDir({
|
|
4339
|
+
file: "pyproject.toml",
|
|
4076
4340
|
entryDirectory,
|
|
4077
4341
|
workPath,
|
|
4078
4342
|
fsFiles
|
|
4079
4343
|
});
|
|
4080
|
-
const
|
|
4081
|
-
file: "
|
|
4344
|
+
const pipfileLockDir = findDir({
|
|
4345
|
+
file: "Pipfile.lock",
|
|
4082
4346
|
entryDirectory,
|
|
4083
4347
|
workPath,
|
|
4084
4348
|
fsFiles
|
|
4085
4349
|
});
|
|
4086
|
-
const pipfileLockDir = fsFiles[(0, import_path6.join)(entryDirectory, "Pipfile.lock")] ? (0, import_path6.join)(workPath, entryDirectory) : fsFiles["Pipfile.lock"] ? workPath : null;
|
|
4087
|
-
const pipfileDir = fsFiles[(0, import_path6.join)(entryDirectory, "Pipfile")] ? (0, import_path6.join)(workPath, entryDirectory) : fsFiles["Pipfile"] ? workPath : null;
|
|
4088
4350
|
let declaredPythonVersion;
|
|
4089
4351
|
if (pyprojectDir) {
|
|
4090
4352
|
let requiresPython;
|
|
4091
4353
|
try {
|
|
4092
|
-
const pyproject = await (0,
|
|
4354
|
+
const pyproject = await (0, import_build_utils8.readConfigFile)((0, import_path5.join)(pyprojectDir, "pyproject.toml"));
|
|
4093
4355
|
requiresPython = pyproject?.project?.["requires-python"];
|
|
4094
4356
|
} catch (err) {
|
|
4095
|
-
(0,
|
|
4357
|
+
(0, import_build_utils7.debug)("Failed to parse pyproject.toml", err);
|
|
4096
4358
|
}
|
|
4097
4359
|
if (typeof requiresPython === "string" && requiresPython.trim()) {
|
|
4098
4360
|
declaredPythonVersion = {
|
|
4099
4361
|
version: requiresPython.trim(),
|
|
4100
4362
|
source: "pyproject.toml"
|
|
4101
4363
|
};
|
|
4102
|
-
(0,
|
|
4364
|
+
(0, import_build_utils7.debug)(`Found requires-python "${requiresPython}" in pyproject.toml`);
|
|
4103
4365
|
}
|
|
4104
4366
|
} else if (pipfileLockDir) {
|
|
4105
4367
|
let lock = {};
|
|
4106
4368
|
try {
|
|
4107
|
-
const json = await readFile((0,
|
|
4369
|
+
const json = await readFile((0, import_path5.join)(pipfileLockDir, "Pipfile.lock"), "utf8");
|
|
4108
4370
|
lock = JSON.parse(json);
|
|
4109
4371
|
} catch (err) {
|
|
4110
|
-
throw new
|
|
4372
|
+
throw new import_build_utils7.NowBuildError({
|
|
4111
4373
|
code: "INVALID_PIPFILE_LOCK",
|
|
4112
4374
|
message: "Unable to parse Pipfile.lock"
|
|
4113
4375
|
});
|
|
@@ -4115,191 +4377,55 @@ var build = async ({
|
|
|
4115
4377
|
const pyFromLock = lock?._meta?.requires?.python_version;
|
|
4116
4378
|
if (pyFromLock) {
|
|
4117
4379
|
declaredPythonVersion = { version: pyFromLock, source: "Pipfile.lock" };
|
|
4118
|
-
(0,
|
|
4380
|
+
(0, import_build_utils7.debug)(`Found Python version ${pyFromLock} in Pipfile.lock`);
|
|
4119
4381
|
}
|
|
4120
4382
|
}
|
|
4121
4383
|
const pythonVersion = getSupportedPythonVersion({
|
|
4122
4384
|
isDev: meta.isDev,
|
|
4123
4385
|
declaredPythonVersion
|
|
4124
4386
|
});
|
|
4125
|
-
fsFiles = await (0,
|
|
4126
|
-
const
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
entryDirectory
|
|
4133
|
-
);
|
|
4134
|
-
try {
|
|
4135
|
-
await import_fs6.default.promises.mkdir(vendorBaseDir, { recursive: true });
|
|
4136
|
-
} catch (err) {
|
|
4137
|
-
console.log("Failed to create vendor cache directory");
|
|
4138
|
-
throw err;
|
|
4139
|
-
}
|
|
4140
|
-
let installationSource;
|
|
4141
|
-
if (uvLockDir && pyprojectDir) {
|
|
4142
|
-
installationSource = "uv.lock";
|
|
4143
|
-
} else if (pyprojectDir) {
|
|
4144
|
-
installationSource = "pyproject.toml";
|
|
4145
|
-
} else if (pipfileLockDir) {
|
|
4146
|
-
installationSource = "Pipfile.lock";
|
|
4147
|
-
} else if (pipfileDir) {
|
|
4148
|
-
installationSource = "Pipfile";
|
|
4149
|
-
} else if (fsFiles[requirementsTxt] || fsFiles["requirements.txt"]) {
|
|
4150
|
-
installationSource = "requirements.txt";
|
|
4151
|
-
}
|
|
4152
|
-
if (installationSource) {
|
|
4153
|
-
console.log(
|
|
4154
|
-
`Installing required dependencies from ${installationSource}...`
|
|
4155
|
-
);
|
|
4156
|
-
} else {
|
|
4157
|
-
console.log("Installing required dependencies...");
|
|
4158
|
-
}
|
|
4159
|
-
let uvPath = null;
|
|
4387
|
+
fsFiles = await (0, import_build_utils7.glob)("**", workPath);
|
|
4388
|
+
const venvPath = (0, import_path5.join)(workPath, ".vercel", "python", ".venv");
|
|
4389
|
+
await ensureVenv({
|
|
4390
|
+
pythonPath: pythonVersion.pythonPath,
|
|
4391
|
+
venvPath
|
|
4392
|
+
});
|
|
4393
|
+
let uvPath;
|
|
4160
4394
|
try {
|
|
4161
4395
|
uvPath = await getUvBinaryOrInstall(pythonVersion.pythonPath);
|
|
4162
4396
|
console.log(`Using uv at "${uvPath}"`);
|
|
4163
4397
|
} catch (err) {
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
);
|
|
4169
|
-
}
|
|
4170
|
-
(0, import_build_utils8.debug)("Failed to install uv", err);
|
|
4398
|
+
console.log("Failed to install or locate uv");
|
|
4399
|
+
throw new Error(
|
|
4400
|
+
`uv is required for this project but failed to install: ${err instanceof Error ? err.message : String(err)}`
|
|
4401
|
+
);
|
|
4171
4402
|
}
|
|
4172
|
-
|
|
4403
|
+
const runtimeDependencies = framework === "flask" ? ["werkzeug>=1.0.1"] : ["werkzeug>=1.0.1", "uvicorn>=0.24"];
|
|
4404
|
+
const { projectDir } = await ensureUvProject({
|
|
4405
|
+
workPath,
|
|
4406
|
+
entryDirectory,
|
|
4407
|
+
fsFiles,
|
|
4173
4408
|
pythonPath: pythonVersion.pythonPath,
|
|
4174
4409
|
pipPath: pythonVersion.pipPath,
|
|
4175
4410
|
uvPath,
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
targetDir: vendorBaseDir,
|
|
4180
|
-
meta
|
|
4411
|
+
venvPath,
|
|
4412
|
+
meta,
|
|
4413
|
+
runtimeDependencies
|
|
4181
4414
|
});
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
workPath,
|
|
4190
|
-
targetDir: vendorBaseDir,
|
|
4191
|
-
meta
|
|
4192
|
-
});
|
|
4193
|
-
}
|
|
4194
|
-
let installedFromProjectFiles = false;
|
|
4195
|
-
if (uvLockDir) {
|
|
4196
|
-
(0, import_build_utils8.debug)('Found "uv.lock"');
|
|
4197
|
-
if (pyprojectDir) {
|
|
4198
|
-
const exportedReq = await exportRequirementsFromUv(pyprojectDir, uvPath, {
|
|
4199
|
-
locked: true
|
|
4200
|
-
});
|
|
4201
|
-
await installRequirementsFile({
|
|
4202
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4203
|
-
pipPath: pythonVersion.pipPath,
|
|
4204
|
-
uvPath,
|
|
4205
|
-
filePath: exportedReq,
|
|
4206
|
-
workPath,
|
|
4207
|
-
targetDir: vendorBaseDir,
|
|
4208
|
-
meta
|
|
4209
|
-
});
|
|
4210
|
-
installedFromProjectFiles = true;
|
|
4211
|
-
} else {
|
|
4212
|
-
(0, import_build_utils8.debug)('Skipping uv export because "pyproject.toml" was not found');
|
|
4213
|
-
}
|
|
4214
|
-
} else if (pyprojectDir) {
|
|
4215
|
-
(0, import_build_utils8.debug)('Found "pyproject.toml"');
|
|
4216
|
-
if (hasReqLocal || hasReqGlobal) {
|
|
4217
|
-
console.log(
|
|
4218
|
-
"Detected both pyproject.toml and requirements.txt but no lockfile; using pyproject.toml"
|
|
4219
|
-
);
|
|
4220
|
-
}
|
|
4221
|
-
const exportedReq = await exportRequirementsFromUv(pyprojectDir, uvPath, {
|
|
4222
|
-
locked: false
|
|
4223
|
-
});
|
|
4224
|
-
await installRequirementsFile({
|
|
4225
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4226
|
-
pipPath: pythonVersion.pipPath,
|
|
4227
|
-
uvPath,
|
|
4228
|
-
filePath: exportedReq,
|
|
4229
|
-
workPath,
|
|
4230
|
-
targetDir: vendorBaseDir,
|
|
4231
|
-
meta
|
|
4232
|
-
});
|
|
4233
|
-
installedFromProjectFiles = true;
|
|
4234
|
-
} else if (pipfileLockDir || pipfileDir) {
|
|
4235
|
-
(0, import_build_utils8.debug)(`Found ${pipfileLockDir ? '"Pipfile.lock"' : '"Pipfile"'}`);
|
|
4236
|
-
if (hasReqLocal || hasReqGlobal) {
|
|
4237
|
-
(0, import_build_utils8.debug)('Skipping Pipfile export because "requirements.txt" exists');
|
|
4238
|
-
} else {
|
|
4239
|
-
const exportedReq = await exportRequirementsFromPipfile({
|
|
4240
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4241
|
-
pipPath: pythonVersion.pipPath,
|
|
4242
|
-
uvPath,
|
|
4243
|
-
projectDir: pipfileLockDir || pipfileDir,
|
|
4244
|
-
meta
|
|
4245
|
-
});
|
|
4246
|
-
await installRequirementsFile({
|
|
4247
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4248
|
-
pipPath: pythonVersion.pipPath,
|
|
4249
|
-
uvPath,
|
|
4250
|
-
filePath: exportedReq,
|
|
4251
|
-
workPath,
|
|
4252
|
-
targetDir: vendorBaseDir,
|
|
4253
|
-
meta
|
|
4254
|
-
});
|
|
4255
|
-
installedFromProjectFiles = true;
|
|
4256
|
-
}
|
|
4257
|
-
}
|
|
4258
|
-
if (!installedFromProjectFiles && fsFiles[requirementsTxt]) {
|
|
4259
|
-
(0, import_build_utils8.debug)('Found local "requirements.txt"');
|
|
4260
|
-
const requirementsTxtPath = fsFiles[requirementsTxt].fsPath;
|
|
4261
|
-
await installRequirementsFile({
|
|
4262
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4263
|
-
pipPath: pythonVersion.pipPath,
|
|
4264
|
-
uvPath,
|
|
4265
|
-
filePath: requirementsTxtPath,
|
|
4266
|
-
workPath,
|
|
4267
|
-
targetDir: vendorBaseDir,
|
|
4268
|
-
meta
|
|
4269
|
-
});
|
|
4270
|
-
} else if (!installedFromProjectFiles && fsFiles["requirements.txt"]) {
|
|
4271
|
-
(0, import_build_utils8.debug)('Found global "requirements.txt"');
|
|
4272
|
-
const requirementsTxtPath = fsFiles["requirements.txt"].fsPath;
|
|
4273
|
-
await installRequirementsFile({
|
|
4274
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4275
|
-
pipPath: pythonVersion.pipPath,
|
|
4276
|
-
uvPath,
|
|
4277
|
-
filePath: requirementsTxtPath,
|
|
4278
|
-
workPath,
|
|
4279
|
-
targetDir: vendorBaseDir,
|
|
4280
|
-
meta
|
|
4281
|
-
});
|
|
4282
|
-
}
|
|
4283
|
-
if (pyprojectDir && repoRootPath) {
|
|
4284
|
-
await installUvWorkspaceDependencies({
|
|
4285
|
-
repoRootPath,
|
|
4286
|
-
pyprojectDir,
|
|
4287
|
-
pythonPath: pythonVersion.pythonPath,
|
|
4288
|
-
pipPath: pythonVersion.pipPath,
|
|
4289
|
-
uvPath,
|
|
4290
|
-
workPath,
|
|
4291
|
-
vendorBaseDir,
|
|
4292
|
-
meta
|
|
4293
|
-
});
|
|
4294
|
-
}
|
|
4295
|
-
const originalPyPath = (0, import_path6.join)(__dirname, "..", "vc_init.py");
|
|
4415
|
+
await runUvSync({
|
|
4416
|
+
uvPath,
|
|
4417
|
+
venvPath,
|
|
4418
|
+
projectDir,
|
|
4419
|
+
locked: true
|
|
4420
|
+
});
|
|
4421
|
+
const originalPyPath = (0, import_path5.join)(__dirname, "..", "vc_init.py");
|
|
4296
4422
|
const originalHandlerPyContents = await readFile(originalPyPath, "utf8");
|
|
4297
|
-
(0,
|
|
4423
|
+
(0, import_build_utils7.debug)("Entrypoint is", entrypoint);
|
|
4298
4424
|
const moduleName = entrypoint.replace(/\//g, ".").replace(/\.py$/i, "");
|
|
4299
4425
|
const vendorDir = resolveVendorDir();
|
|
4300
4426
|
const suffix = meta.isDev && !entrypoint.endsWith(".py") ? ".py" : "";
|
|
4301
4427
|
const entrypointWithSuffix = `${entrypoint}${suffix}`;
|
|
4302
|
-
(0,
|
|
4428
|
+
(0, import_build_utils7.debug)("Entrypoint with suffix is", entrypointWithSuffix);
|
|
4303
4429
|
const handlerPyContents = originalHandlerPyContents.replace(/__VC_HANDLER_MODULE_NAME/g, moduleName).replace(/__VC_HANDLER_ENTRYPOINT/g, entrypointWithSuffix).replace(/__VC_HANDLER_VENDOR_DIR/g, vendorDir);
|
|
4304
4430
|
const predefinedExcludes = [
|
|
4305
4431
|
".git/**",
|
|
@@ -4325,26 +4451,21 @@ var build = async ({
|
|
|
4325
4451
|
cwd: workPath,
|
|
4326
4452
|
ignore: config && typeof config.excludeFiles === "string" ? [...predefinedExcludes, config.excludeFiles] : predefinedExcludes
|
|
4327
4453
|
};
|
|
4328
|
-
const files = await (0,
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
}
|
|
4336
|
-
}
|
|
4337
|
-
} catch (err) {
|
|
4338
|
-
console.log("Failed to include cached vendor directory");
|
|
4339
|
-
throw err;
|
|
4454
|
+
const files = await (0, import_build_utils7.glob)("**", globOptions);
|
|
4455
|
+
const vendorFiles = await mirrorSitePackagesIntoVendor({
|
|
4456
|
+
venvPath,
|
|
4457
|
+
vendorDirName: vendorDir
|
|
4458
|
+
});
|
|
4459
|
+
for (const [p, f] of Object.entries(vendorFiles)) {
|
|
4460
|
+
files[p] = f;
|
|
4340
4461
|
}
|
|
4341
4462
|
const handlerPyFilename = "vc__handler__python";
|
|
4342
|
-
files[`${handlerPyFilename}.py`] = new
|
|
4463
|
+
files[`${handlerPyFilename}.py`] = new import_build_utils7.FileBlob({ data: handlerPyContents });
|
|
4343
4464
|
if (config.framework === "fasthtml") {
|
|
4344
4465
|
const { SESSKEY = "" } = process.env;
|
|
4345
|
-
files[".sesskey"] = new
|
|
4466
|
+
files[".sesskey"] = new import_build_utils7.FileBlob({ data: `"${SESSKEY}"` });
|
|
4346
4467
|
}
|
|
4347
|
-
const output = new
|
|
4468
|
+
const output = new import_build_utils7.Lambda({
|
|
4348
4469
|
files,
|
|
4349
4470
|
handler: `${handlerPyFilename}.vc_handler`,
|
|
4350
4471
|
runtime: pythonVersion.runtime,
|
|
@@ -4380,7 +4501,7 @@ var defaultShouldServe = ({
|
|
|
4380
4501
|
if (entrypoint === requestPath && hasProp(files, entrypoint)) {
|
|
4381
4502
|
return true;
|
|
4382
4503
|
}
|
|
4383
|
-
const { dir, name } = (0,
|
|
4504
|
+
const { dir, name } = (0, import_path5.parse)(entrypoint);
|
|
4384
4505
|
if (name === "index" && dir === requestPath && hasProp(files, entrypoint)) {
|
|
4385
4506
|
return true;
|
|
4386
4507
|
}
|