@vercel/python-analysis 0.9.0 → 0.10.0
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.cjs +223 -555
- package/dist/index.d.ts +2 -1
- package/dist/index.js +197 -530
- package/dist/manifest/requirements-txt-parser.d.ts +18 -29
- package/dist/manifest/uv-lock-parser.d.ts +7 -0
- package/dist/manifest/wheel-compat.d.ts +16 -0
- package/dist/wasm/host-utils.d.ts +23 -0
- package/dist/wasm/interfaces/vercel-python-analysis-host-utils.d.ts +4 -0
- package/dist/wasm/interfaces/wasi-clocks-wall-clock.d.ts +5 -0
- package/dist/wasm/interfaces/wasi-filesystem-preopens.d.ts +3 -0
- package/dist/wasm/interfaces/wasi-filesystem-types.d.ts +142 -0
- package/dist/wasm/vercel_python_analysis.core.wasm +0 -0
- package/dist/wasm/vercel_python_analysis.core2.wasm +0 -0
- package/dist/wasm/vercel_python_analysis.core3.wasm +0 -0
- package/dist/wasm/vercel_python_analysis.d.ts +34 -0
- package/dist/wasm/vercel_python_analysis.js +2746 -108
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -70,6 +70,7 @@ __export(src_exports, {
|
|
|
70
70
|
extendDistRecord: () => extendDistRecord,
|
|
71
71
|
getStringConstant: () => getStringConstant,
|
|
72
72
|
isPrivatePackageSource: () => isPrivatePackageSource,
|
|
73
|
+
isWheelCompatible: () => isWheelCompatible,
|
|
73
74
|
normalizePackageName: () => normalizePackageName2,
|
|
74
75
|
parseUvLock: () => parseUvLock,
|
|
75
76
|
scanDistributions: () => scanDistributions,
|
|
@@ -83,6 +84,84 @@ module.exports = __toCommonJS(src_exports);
|
|
|
83
84
|
var import_promises = require("fs/promises");
|
|
84
85
|
var import_node_module = require("module");
|
|
85
86
|
var import_node_path = require("path");
|
|
87
|
+
|
|
88
|
+
// src/wasm/host-utils.ts
|
|
89
|
+
var import_node_async_hooks = require("async_hooks");
|
|
90
|
+
var import_posix = require("path/posix");
|
|
91
|
+
var import_url = require("url");
|
|
92
|
+
var readFileStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
93
|
+
var WitResultError = class extends Error {
|
|
94
|
+
constructor(message) {
|
|
95
|
+
super(message);
|
|
96
|
+
this.payload = message;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function createHostUtils() {
|
|
100
|
+
return {
|
|
101
|
+
readFile(path4) {
|
|
102
|
+
const ctx = readFileStorage.getStore();
|
|
103
|
+
if (ctx?.readFile) {
|
|
104
|
+
const relative2 = stripWorkingDir(path4, ctx.workingDir);
|
|
105
|
+
if (relative2 != null) {
|
|
106
|
+
const result = ctx.readFile(relative2);
|
|
107
|
+
if (result != null)
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
throw new WitResultError(`File not found: ${path4}`);
|
|
112
|
+
},
|
|
113
|
+
domainToAscii(domain) {
|
|
114
|
+
try {
|
|
115
|
+
if (/[:#?/@[\]%\\\t\n\r]/.test(domain)) {
|
|
116
|
+
throw new Error("domain contains invalid characters");
|
|
117
|
+
}
|
|
118
|
+
const url = new URL(`http://${domain}/`);
|
|
119
|
+
if (url.hostname === "" && domain !== "") {
|
|
120
|
+
throw new Error("domain resolved to empty hostname");
|
|
121
|
+
}
|
|
122
|
+
return url.hostname;
|
|
123
|
+
} catch {
|
|
124
|
+
throw { payload: `Invalid domain: ${domain}` };
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
domainToUnicode(domain) {
|
|
128
|
+
const result = (0, import_url.domainToUnicode)(domain);
|
|
129
|
+
if (result !== "" || domain === "") {
|
|
130
|
+
return [result, true];
|
|
131
|
+
}
|
|
132
|
+
return [domain, false];
|
|
133
|
+
},
|
|
134
|
+
nfcNormalize(s) {
|
|
135
|
+
return s.normalize("NFC");
|
|
136
|
+
},
|
|
137
|
+
nfdNormalize(s) {
|
|
138
|
+
return s.normalize("NFD");
|
|
139
|
+
},
|
|
140
|
+
nfkcNormalize(s) {
|
|
141
|
+
return s.normalize("NFKC");
|
|
142
|
+
},
|
|
143
|
+
nfkdNormalize(s) {
|
|
144
|
+
return s.normalize("NFKD");
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function stripWorkingDir(path4, workingDir) {
|
|
149
|
+
const normalized = (0, import_posix.normalize)(path4);
|
|
150
|
+
if (!workingDir) {
|
|
151
|
+
return normalized;
|
|
152
|
+
}
|
|
153
|
+
const normalizedDir = (0, import_posix.normalize)(workingDir);
|
|
154
|
+
const prefix = normalizedDir.endsWith("/") ? normalizedDir : normalizedDir + "/";
|
|
155
|
+
if (normalized.startsWith(prefix)) {
|
|
156
|
+
return normalized.slice(prefix.length);
|
|
157
|
+
}
|
|
158
|
+
if (normalized === normalizedDir) {
|
|
159
|
+
return "";
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/wasm/load.ts
|
|
86
165
|
var WASI_SHIM_PATH = "@bytecodealliance/preview2-shim/instantiation";
|
|
87
166
|
var WASM_MODULE_PATH = "#wasm/vercel_python_analysis.js";
|
|
88
167
|
var wasmInstance = null;
|
|
@@ -110,7 +189,10 @@ async function importWasmModule() {
|
|
|
110
189
|
const wasiShimModule = await import(WASI_SHIM_PATH);
|
|
111
190
|
const WASIShim = wasiShimModule.WASIShim;
|
|
112
191
|
const wasmModule = await import(WASM_MODULE_PATH);
|
|
113
|
-
const imports =
|
|
192
|
+
const imports = {
|
|
193
|
+
...new WASIShim().getImportObject(),
|
|
194
|
+
"vercel:python-analysis/host-utils": createHostUtils()
|
|
195
|
+
};
|
|
114
196
|
const instance = await wasmModule.instantiate(getCoreModule, imports);
|
|
115
197
|
wasmInstance = instance;
|
|
116
198
|
return instance;
|
|
@@ -329,7 +411,7 @@ async function extendDistRecord(sitePackagesDir, packageName, paths) {
|
|
|
329
411
|
}
|
|
330
412
|
|
|
331
413
|
// src/manifest/package.ts
|
|
332
|
-
var
|
|
414
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
333
415
|
var import_minimatch = require("minimatch");
|
|
334
416
|
|
|
335
417
|
// src/util/config.ts
|
|
@@ -902,356 +984,98 @@ var PyProjectToolSectionSchema = pyProjectToolSectionSchema.passthrough();
|
|
|
902
984
|
var PyProjectTomlSchema = pyProjectTomlSchema.passthrough();
|
|
903
985
|
|
|
904
986
|
// src/manifest/requirements-txt-parser.ts
|
|
905
|
-
var
|
|
906
|
-
var import_pip_requirements_js = require("pip-requirements-js");
|
|
987
|
+
var import_posix2 = require("path/posix");
|
|
907
988
|
var PRIMARY_INDEX_NAME = "primary";
|
|
908
989
|
var EXTRA_INDEX_PREFIX = "extra-";
|
|
909
990
|
var FIND_LINKS_PREFIX = "find-links-";
|
|
910
|
-
function
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
const fragment = remaining.slice(fragmentIdx + 1);
|
|
919
|
-
remaining = remaining.slice(0, fragmentIdx);
|
|
920
|
-
for (const part of fragment.split("&")) {
|
|
921
|
-
const [key, value] = part.split("=");
|
|
922
|
-
if (key === "egg" && value) {
|
|
923
|
-
egg = value;
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
}
|
|
927
|
-
let ref;
|
|
928
|
-
const lastSlashIdx = remaining.lastIndexOf("/");
|
|
929
|
-
const atIdx = remaining.indexOf("@", lastSlashIdx > 0 ? lastSlashIdx : 0);
|
|
930
|
-
if (atIdx !== -1 && atIdx > remaining.indexOf("://")) {
|
|
931
|
-
ref = remaining.slice(atIdx + 1);
|
|
932
|
-
remaining = remaining.slice(0, atIdx);
|
|
991
|
+
async function parseWithWasm(content, readFile4, workingDir) {
|
|
992
|
+
const wasm = await importWasmModule();
|
|
993
|
+
const resolvedDir = workingDir ?? "/";
|
|
994
|
+
if (readFile4) {
|
|
995
|
+
return readFileStorage.run(
|
|
996
|
+
{ readFile: readFile4, workingDir: resolvedDir },
|
|
997
|
+
() => wasm.parseRequirementsTxt(content, resolvedDir, void 0)
|
|
998
|
+
);
|
|
933
999
|
}
|
|
934
|
-
return
|
|
935
|
-
url: remaining,
|
|
936
|
-
ref,
|
|
937
|
-
egg
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
function isGitUrl(url) {
|
|
941
|
-
return url.startsWith("git+");
|
|
1000
|
+
return wasm.parseRequirementsTxt(content, workingDir ?? void 0, void 0);
|
|
942
1001
|
}
|
|
943
|
-
function
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
const cleanedLines = [];
|
|
951
|
-
const pathRequirements = [];
|
|
952
|
-
const editableRequirements = [];
|
|
953
|
-
for (let i = 0; i < lines.length; i++) {
|
|
954
|
-
const line = lines[i];
|
|
955
|
-
const trimmed = line.trim();
|
|
956
|
-
if (trimmed === "" || trimmed.startsWith("#")) {
|
|
957
|
-
cleanedLines.push(line);
|
|
958
|
-
continue;
|
|
959
|
-
}
|
|
960
|
-
let fullLine = trimmed;
|
|
961
|
-
let linesConsumed = 0;
|
|
962
|
-
while (fullLine.endsWith("\\") && i + linesConsumed + 1 < lines.length) {
|
|
963
|
-
linesConsumed++;
|
|
964
|
-
fullLine = fullLine.slice(0, -1) + lines[i + linesConsumed].trim();
|
|
965
|
-
}
|
|
966
|
-
const extracted = tryExtractPipArgument(fullLine, options);
|
|
967
|
-
if (extracted === true) {
|
|
968
|
-
i += linesConsumed;
|
|
969
|
-
} else if (typeof extracted === "object" && extracted.editable) {
|
|
970
|
-
editableRequirements.push(extracted.editable);
|
|
971
|
-
i += linesConsumed;
|
|
972
|
-
} else {
|
|
973
|
-
if (/^-[a-zA-Z]/.test(fullLine) && !fullLine.startsWith("-r") && !fullLine.startsWith("-c")) {
|
|
974
|
-
i += linesConsumed;
|
|
975
|
-
continue;
|
|
976
|
-
}
|
|
977
|
-
const strippedLine = stripInlineHashes(fullLine);
|
|
978
|
-
const effectiveLine = (strippedLine !== fullLine ? strippedLine : fullLine).trim();
|
|
979
|
-
if (isPathOrUrlRequirement(effectiveLine)) {
|
|
980
|
-
pathRequirements.push(effectiveLine);
|
|
981
|
-
} else if (strippedLine !== fullLine) {
|
|
982
|
-
cleanedLines.push(strippedLine);
|
|
983
|
-
} else {
|
|
984
|
-
cleanedLines.push(line);
|
|
985
|
-
for (let j = 1; j <= linesConsumed; j++) {
|
|
986
|
-
cleanedLines.push(lines[i + j]);
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
i += linesConsumed;
|
|
1002
|
+
function wasmEntryToNormalized(entry, editable) {
|
|
1003
|
+
let name = entry.name || "";
|
|
1004
|
+
if (!name && entry.url) {
|
|
1005
|
+
const urlPath = entry.url.replace(/^file:\/\//, "");
|
|
1006
|
+
const basename = urlPath.replace(/\/$/, "").split("/").pop();
|
|
1007
|
+
if (basename && !basename.includes(".")) {
|
|
1008
|
+
name = basename;
|
|
990
1009
|
}
|
|
991
1010
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
options,
|
|
995
|
-
pathRequirements,
|
|
996
|
-
editableRequirements
|
|
1011
|
+
const req = {
|
|
1012
|
+
name
|
|
997
1013
|
};
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
if (line.startsWith("--requirement")) {
|
|
1001
|
-
const path4 = extractArgValue(line, "--requirement");
|
|
1002
|
-
if (path4) {
|
|
1003
|
-
options.requirementFiles.push(path4);
|
|
1004
|
-
return true;
|
|
1005
|
-
}
|
|
1014
|
+
if (entry.versionSpec) {
|
|
1015
|
+
req.version = entry.versionSpec;
|
|
1006
1016
|
}
|
|
1007
|
-
if (
|
|
1008
|
-
|
|
1009
|
-
if (path4) {
|
|
1010
|
-
options.constraintFiles.push(path4);
|
|
1011
|
-
return true;
|
|
1012
|
-
}
|
|
1017
|
+
if (entry.extras.length > 0) {
|
|
1018
|
+
req.extras = entry.extras;
|
|
1013
1019
|
}
|
|
1014
|
-
if (
|
|
1015
|
-
|
|
1016
|
-
if (url) {
|
|
1017
|
-
options.indexUrl = url;
|
|
1018
|
-
return true;
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
if (line.startsWith("-i ") || line === "-i") {
|
|
1022
|
-
const match = line.match(/^-i\s+(\S+)/);
|
|
1023
|
-
if (match) {
|
|
1024
|
-
options.indexUrl = match[1];
|
|
1025
|
-
return true;
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
if (line.startsWith("--extra-index-url")) {
|
|
1029
|
-
const url = extractArgValue(line, "--extra-index-url");
|
|
1030
|
-
if (url) {
|
|
1031
|
-
options.extraIndexUrls.push(url);
|
|
1032
|
-
return true;
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
if (line.startsWith("--editable")) {
|
|
1036
|
-
const path4 = extractArgValue(line, "--editable");
|
|
1037
|
-
if (path4) {
|
|
1038
|
-
return { editable: path4 };
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
if (line.startsWith("-e ") || line.startsWith("-e ")) {
|
|
1042
|
-
const path4 = line.slice(2).trim();
|
|
1043
|
-
if (path4) {
|
|
1044
|
-
return { editable: path4 };
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
if (line.startsWith("--find-links")) {
|
|
1048
|
-
const url = extractArgValue(line, "--find-links");
|
|
1049
|
-
if (url) {
|
|
1050
|
-
if (!options.findLinks)
|
|
1051
|
-
options.findLinks = [];
|
|
1052
|
-
options.findLinks.push(url);
|
|
1053
|
-
return true;
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
if (line.startsWith("-f ") || line.startsWith("-f ")) {
|
|
1057
|
-
const match = line.match(/^-f\s+(\S+)/);
|
|
1058
|
-
if (match) {
|
|
1059
|
-
if (!options.findLinks)
|
|
1060
|
-
options.findLinks = [];
|
|
1061
|
-
options.findLinks.push(match[1]);
|
|
1062
|
-
return true;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1065
|
-
if (line === "--no-index" || line.startsWith("--no-index ")) {
|
|
1066
|
-
options.noIndex = true;
|
|
1067
|
-
return true;
|
|
1068
|
-
}
|
|
1069
|
-
if (line.startsWith("--no-binary") || line.startsWith("--only-binary")) {
|
|
1070
|
-
return true;
|
|
1071
|
-
}
|
|
1072
|
-
if (line.startsWith("--")) {
|
|
1073
|
-
return true;
|
|
1074
|
-
}
|
|
1075
|
-
return false;
|
|
1076
|
-
}
|
|
1077
|
-
function stripInlineHashes(line) {
|
|
1078
|
-
return line.replace(/\s+--hash=\S+/g, "").trim();
|
|
1079
|
-
}
|
|
1080
|
-
function extractInlineHashes(line) {
|
|
1081
|
-
const hashes = [];
|
|
1082
|
-
const hashRegex = /--hash=(\S+)/g;
|
|
1083
|
-
let match;
|
|
1084
|
-
while ((match = hashRegex.exec(line)) != null) {
|
|
1085
|
-
hashes.push(match[1]);
|
|
1086
|
-
}
|
|
1087
|
-
return hashes;
|
|
1088
|
-
}
|
|
1089
|
-
function extractArgValue(line, option) {
|
|
1090
|
-
let value = null;
|
|
1091
|
-
if (line.startsWith(`${option}=`)) {
|
|
1092
|
-
value = line.slice(option.length + 1).trim();
|
|
1093
|
-
} else if (line.startsWith(`${option} `) || line.startsWith(`${option} `)) {
|
|
1094
|
-
value = line.slice(option.length).trim();
|
|
1095
|
-
}
|
|
1096
|
-
if (!value)
|
|
1097
|
-
return null;
|
|
1098
|
-
const commentIdx = value.indexOf(" #");
|
|
1099
|
-
if (commentIdx !== -1) {
|
|
1100
|
-
value = value.slice(0, commentIdx).trim();
|
|
1101
|
-
}
|
|
1102
|
-
return value || null;
|
|
1103
|
-
}
|
|
1104
|
-
function isPathOrUrlRequirement(line) {
|
|
1105
|
-
if (line.startsWith("./") || line.startsWith("../"))
|
|
1106
|
-
return true;
|
|
1107
|
-
if (line.startsWith("/"))
|
|
1108
|
-
return true;
|
|
1109
|
-
if (line.startsWith("~/"))
|
|
1110
|
-
return true;
|
|
1111
|
-
if (/^(https?|ftp|file):\/\//i.test(line))
|
|
1112
|
-
return true;
|
|
1113
|
-
if (isBareArchiveFilename(line))
|
|
1114
|
-
return true;
|
|
1115
|
-
return false;
|
|
1116
|
-
}
|
|
1117
|
-
function isBareArchiveFilename(line) {
|
|
1118
|
-
if (line.includes(" @ "))
|
|
1119
|
-
return false;
|
|
1120
|
-
let check = line;
|
|
1121
|
-
const commentIdx = check.indexOf(" #");
|
|
1122
|
-
if (commentIdx !== -1)
|
|
1123
|
-
check = check.slice(0, commentIdx);
|
|
1124
|
-
const markerIdx = check.indexOf(" ;");
|
|
1125
|
-
if (markerIdx !== -1)
|
|
1126
|
-
check = check.slice(0, markerIdx);
|
|
1127
|
-
const extrasIdx = check.indexOf("[");
|
|
1128
|
-
if (extrasIdx !== -1)
|
|
1129
|
-
check = check.slice(0, extrasIdx);
|
|
1130
|
-
check = check.trim();
|
|
1131
|
-
return /\.(whl|tar\.gz|tar\.bz2|tar\.xz|zip)$/i.test(check);
|
|
1132
|
-
}
|
|
1133
|
-
function parseWheelFilename(filename) {
|
|
1134
|
-
if (!filename.endsWith(".whl"))
|
|
1135
|
-
return null;
|
|
1136
|
-
const stem = filename.slice(0, -4);
|
|
1137
|
-
const parts = stem.split("-");
|
|
1138
|
-
if (parts.length < 5 || parts.length > 6)
|
|
1139
|
-
return null;
|
|
1140
|
-
const name = parts[0];
|
|
1141
|
-
const version = parts[1];
|
|
1142
|
-
if (!name || !version)
|
|
1143
|
-
return null;
|
|
1144
|
-
return {
|
|
1145
|
-
name: name.replace(/_/g, "-"),
|
|
1146
|
-
version
|
|
1147
|
-
};
|
|
1148
|
-
}
|
|
1149
|
-
function parseSdistFilename(filename) {
|
|
1150
|
-
let stem = filename;
|
|
1151
|
-
for (const ext of [".tar.gz", ".tar.bz2", ".tar.xz", ".zip"]) {
|
|
1152
|
-
if (stem.endsWith(ext)) {
|
|
1153
|
-
stem = stem.slice(0, -ext.length);
|
|
1154
|
-
break;
|
|
1155
|
-
}
|
|
1020
|
+
if (entry.markers) {
|
|
1021
|
+
req.markers = entry.markers;
|
|
1156
1022
|
}
|
|
1157
|
-
if (
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
versionIdx = i;
|
|
1164
|
-
break;
|
|
1023
|
+
if (entry.vcs) {
|
|
1024
|
+
const source = {
|
|
1025
|
+
git: entry.vcs.url
|
|
1026
|
+
};
|
|
1027
|
+
if (entry.vcs.rev) {
|
|
1028
|
+
source.rev = entry.vcs.rev;
|
|
1165
1029
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
return null;
|
|
1169
|
-
return {
|
|
1170
|
-
name: parts.slice(0, versionIdx).join("-"),
|
|
1171
|
-
version: parts.slice(versionIdx).join("-")
|
|
1172
|
-
};
|
|
1173
|
-
}
|
|
1174
|
-
function normalizePathRequirement(rawLine) {
|
|
1175
|
-
let line = rawLine;
|
|
1176
|
-
const commentIdx = line.indexOf(" #");
|
|
1177
|
-
if (commentIdx !== -1) {
|
|
1178
|
-
line = line.slice(0, commentIdx).trim();
|
|
1179
|
-
}
|
|
1180
|
-
let markers;
|
|
1181
|
-
const markerIdx = line.indexOf(" ;");
|
|
1182
|
-
if (markerIdx !== -1) {
|
|
1183
|
-
markers = line.slice(markerIdx + 2).trim();
|
|
1184
|
-
line = line.slice(0, markerIdx).trim();
|
|
1185
|
-
}
|
|
1186
|
-
let extras;
|
|
1187
|
-
const extrasMatch = line.match(/\[([^\]]+)\]$/);
|
|
1188
|
-
if (extrasMatch) {
|
|
1189
|
-
extras = extrasMatch[1].split(",").map((e) => e.trim());
|
|
1190
|
-
line = line.slice(0, extrasMatch.index).trim();
|
|
1191
|
-
}
|
|
1192
|
-
const isUrl = /^(https?|ftp|file):\/\//i.test(line);
|
|
1193
|
-
let filename;
|
|
1194
|
-
if (isUrl) {
|
|
1195
|
-
try {
|
|
1196
|
-
const url = new URL(line);
|
|
1197
|
-
filename = url.pathname.split("/").pop() || "";
|
|
1198
|
-
} catch {
|
|
1199
|
-
return null;
|
|
1030
|
+
if (editable) {
|
|
1031
|
+
source.editable = true;
|
|
1200
1032
|
}
|
|
1201
|
-
|
|
1202
|
-
const cleanPath = line.replace(/\/+$/, "");
|
|
1203
|
-
filename = cleanPath.split("/").pop() || "";
|
|
1033
|
+
req.source = source;
|
|
1204
1034
|
}
|
|
1205
|
-
if (
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
version = wheelParsed.version;
|
|
1213
|
-
}
|
|
1214
|
-
if (!name) {
|
|
1215
|
-
const sdistParsed = parseSdistFilename(filename);
|
|
1216
|
-
if (sdistParsed) {
|
|
1217
|
-
name = sdistParsed.name;
|
|
1218
|
-
version = sdistParsed.version;
|
|
1035
|
+
if (entry.url) {
|
|
1036
|
+
if (entry.url.startsWith("file://") && !entry.vcs) {
|
|
1037
|
+
const given = entry.givenUrl ?? entry.url;
|
|
1038
|
+
const path4 = given.startsWith("file://") ? given.slice("file://".length) : given;
|
|
1039
|
+
req.source = { path: path4, ...editable ? { editable: true } : {} };
|
|
1040
|
+
} else {
|
|
1041
|
+
req.url = entry.url;
|
|
1219
1042
|
}
|
|
1220
1043
|
}
|
|
1221
|
-
if (
|
|
1222
|
-
|
|
1223
|
-
}
|
|
1224
|
-
if (!name)
|
|
1225
|
-
return null;
|
|
1226
|
-
const req = { name };
|
|
1227
|
-
if (version) {
|
|
1228
|
-
req.version = `==${version}`;
|
|
1229
|
-
}
|
|
1230
|
-
if (extras && extras.length > 0) {
|
|
1231
|
-
req.extras = extras;
|
|
1232
|
-
}
|
|
1233
|
-
if (markers) {
|
|
1234
|
-
req.markers = markers;
|
|
1235
|
-
}
|
|
1236
|
-
if (isUrl) {
|
|
1237
|
-
req.url = line;
|
|
1238
|
-
} else {
|
|
1239
|
-
req.source = { path: line };
|
|
1044
|
+
if (entry.hashes.length > 0) {
|
|
1045
|
+
req.hashes = entry.hashes;
|
|
1240
1046
|
}
|
|
1241
1047
|
return req;
|
|
1242
1048
|
}
|
|
1243
|
-
function
|
|
1049
|
+
function rebasePath(p, workingDir, packageRoot) {
|
|
1050
|
+
if (!workingDir || !packageRoot || workingDir === packageRoot)
|
|
1051
|
+
return p;
|
|
1052
|
+
if ((0, import_posix2.isAbsolute)(p))
|
|
1053
|
+
return p;
|
|
1054
|
+
const abs = (0, import_posix2.join)(workingDir, p);
|
|
1055
|
+
const rel = (0, import_posix2.relative)(packageRoot, abs);
|
|
1056
|
+
if ((0, import_posix2.isAbsolute)(rel))
|
|
1057
|
+
return rel;
|
|
1058
|
+
if (rel.startsWith(".."))
|
|
1059
|
+
return rel;
|
|
1060
|
+
return "./" + rel;
|
|
1061
|
+
}
|
|
1062
|
+
async function convertRequirementsToPyprojectToml(fileContent, options) {
|
|
1244
1063
|
const pyproject = {};
|
|
1245
|
-
const parsed = parseRequirementsFile(fileContent,
|
|
1064
|
+
const parsed = await parseRequirementsFile(fileContent, options);
|
|
1246
1065
|
const deps = [];
|
|
1247
1066
|
const sources = {};
|
|
1067
|
+
const { workingDir, packageRoot } = options ?? {};
|
|
1248
1068
|
for (const req of parsed.requirements) {
|
|
1249
1069
|
deps.push(formatPep508(req));
|
|
1250
1070
|
if (req.source) {
|
|
1071
|
+
const source = { ...req.source };
|
|
1072
|
+
if (source.path) {
|
|
1073
|
+
source.path = rebasePath(source.path, workingDir, packageRoot);
|
|
1074
|
+
}
|
|
1251
1075
|
if (Object.prototype.hasOwnProperty.call(sources, req.name)) {
|
|
1252
|
-
sources[req.name].push(
|
|
1076
|
+
sources[req.name].push(source);
|
|
1253
1077
|
} else {
|
|
1254
|
-
sources[req.name] = [
|
|
1078
|
+
sources[req.name] = [source];
|
|
1255
1079
|
}
|
|
1256
1080
|
}
|
|
1257
1081
|
}
|
|
@@ -1301,216 +1125,38 @@ function buildIndexEntries(pipOptions) {
|
|
|
1301
1125
|
}
|
|
1302
1126
|
return indexes;
|
|
1303
1127
|
}
|
|
1304
|
-
function parseRequirementsFile(fileContent,
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1128
|
+
async function parseRequirementsFile(fileContent, options) {
|
|
1129
|
+
const wasmResult = await parseWithWasm(
|
|
1130
|
+
fileContent,
|
|
1131
|
+
options?.readFile,
|
|
1132
|
+
options?.workingDir
|
|
1133
|
+
);
|
|
1134
|
+
return processWasmResult(wasmResult);
|
|
1307
1135
|
}
|
|
1308
|
-
function
|
|
1309
|
-
const { cleanedContent, options, pathRequirements, editableRequirements } = extractPipArguments(fileContent);
|
|
1310
|
-
const hashMap = buildHashMap(fileContent);
|
|
1311
|
-
const requirements = (0, import_pip_requirements_js.parsePipRequirementsFile)(cleanedContent);
|
|
1136
|
+
function processWasmResult(wasmResult) {
|
|
1312
1137
|
const normalized = [];
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1138
|
+
for (const entry of wasmResult.requirements) {
|
|
1139
|
+
normalized.push(wasmEntryToNormalized(entry, false));
|
|
1140
|
+
}
|
|
1141
|
+
for (const entry of wasmResult.editables) {
|
|
1142
|
+
const norm = wasmEntryToNormalized(entry, true);
|
|
1143
|
+
if (!norm.source && !entry.vcs) {
|
|
1144
|
+
norm.source = { path: entry.pep508, editable: true };
|
|
1145
|
+
} else if (norm.source && !norm.source.editable) {
|
|
1146
|
+
norm.source.editable = true;
|
|
1147
|
+
}
|
|
1148
|
+
normalized.push(norm);
|
|
1149
|
+
}
|
|
1150
|
+
const pipOptions = {
|
|
1151
|
+
indexUrl: wasmResult.indexUrl || void 0,
|
|
1152
|
+
extraIndexUrls: [...wasmResult.extraIndexUrls],
|
|
1153
|
+
findLinks: wasmResult.findLinks.length > 0 ? [...wasmResult.findLinks] : void 0,
|
|
1154
|
+
noIndex: wasmResult.noIndex || void 0
|
|
1320
1155
|
};
|
|
1321
|
-
for (const req of requirements) {
|
|
1322
|
-
if (req.type === "RequirementsFile") {
|
|
1323
|
-
mergedOptions.requirementFiles.push(req.path);
|
|
1324
|
-
continue;
|
|
1325
|
-
}
|
|
1326
|
-
if (req.type === "ConstraintsFile") {
|
|
1327
|
-
mergedOptions.constraintFiles.push(req.path);
|
|
1328
|
-
continue;
|
|
1329
|
-
}
|
|
1330
|
-
const norm = normalizeRequirement(req);
|
|
1331
|
-
if (norm != null) {
|
|
1332
|
-
const hashes = hashMap.get(norm.name.toLowerCase());
|
|
1333
|
-
if (hashes && hashes.length > 0) {
|
|
1334
|
-
norm.hashes = hashes;
|
|
1335
|
-
}
|
|
1336
|
-
normalized.push(norm);
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
|
-
for (const rawPath of pathRequirements) {
|
|
1340
|
-
const norm = normalizePathRequirement(rawPath);
|
|
1341
|
-
if (norm != null) {
|
|
1342
|
-
normalized.push(norm);
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
for (const rawPath of editableRequirements) {
|
|
1346
|
-
const norm = normalizePathRequirement(rawPath);
|
|
1347
|
-
if (norm != null) {
|
|
1348
|
-
if (norm.source) {
|
|
1349
|
-
norm.source.editable = true;
|
|
1350
|
-
} else {
|
|
1351
|
-
norm.source = { path: rawPath, editable: true };
|
|
1352
|
-
}
|
|
1353
|
-
normalized.push(norm);
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
if (readFile4) {
|
|
1357
|
-
for (const refPath of mergedOptions.requirementFiles) {
|
|
1358
|
-
const refPathKey = (0, import_node_path5.normalize)(refPath);
|
|
1359
|
-
if (visited.has(refPathKey)) {
|
|
1360
|
-
continue;
|
|
1361
|
-
}
|
|
1362
|
-
visited.add(refPathKey);
|
|
1363
|
-
const refContent = readFile4(refPath);
|
|
1364
|
-
if (refContent != null) {
|
|
1365
|
-
const refParsed = parseRequirementsFileInternal(
|
|
1366
|
-
refContent,
|
|
1367
|
-
readFile4,
|
|
1368
|
-
visited
|
|
1369
|
-
);
|
|
1370
|
-
const existingNames = new Set(
|
|
1371
|
-
normalized.map((r) => r.name.toLowerCase())
|
|
1372
|
-
);
|
|
1373
|
-
for (const req of refParsed.requirements) {
|
|
1374
|
-
if (!existingNames.has(req.name.toLowerCase())) {
|
|
1375
|
-
normalized.push(req);
|
|
1376
|
-
existingNames.add(req.name.toLowerCase());
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
if (refParsed.pipOptions.indexUrl) {
|
|
1380
|
-
mergedOptions.indexUrl = refParsed.pipOptions.indexUrl;
|
|
1381
|
-
}
|
|
1382
|
-
for (const url of refParsed.pipOptions.extraIndexUrls) {
|
|
1383
|
-
if (!mergedOptions.extraIndexUrls.includes(url)) {
|
|
1384
|
-
mergedOptions.extraIndexUrls.push(url);
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
for (const constraintPath of refParsed.pipOptions.constraintFiles) {
|
|
1388
|
-
if (!mergedOptions.constraintFiles.includes(constraintPath)) {
|
|
1389
|
-
mergedOptions.constraintFiles.push(constraintPath);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
if (refParsed.pipOptions.findLinks) {
|
|
1393
|
-
if (!mergedOptions.findLinks)
|
|
1394
|
-
mergedOptions.findLinks = [];
|
|
1395
|
-
for (const fl of refParsed.pipOptions.findLinks) {
|
|
1396
|
-
if (!mergedOptions.findLinks.includes(fl)) {
|
|
1397
|
-
mergedOptions.findLinks.push(fl);
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
if (refParsed.pipOptions.noIndex) {
|
|
1402
|
-
mergedOptions.noIndex = true;
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
1156
|
return {
|
|
1408
1157
|
requirements: normalized,
|
|
1409
|
-
pipOptions
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
function buildHashMap(fileContent) {
|
|
1413
|
-
const hashMap = /* @__PURE__ */ new Map();
|
|
1414
|
-
const lines = fileContent.split(/\r?\n/);
|
|
1415
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1416
|
-
let line = lines[i].trim();
|
|
1417
|
-
if (line === "" || line.startsWith("#") || line.startsWith("-")) {
|
|
1418
|
-
continue;
|
|
1419
|
-
}
|
|
1420
|
-
while (line.endsWith("\\") && i + 1 < lines.length) {
|
|
1421
|
-
i++;
|
|
1422
|
-
line = line.slice(0, -1) + lines[i].trim();
|
|
1423
|
-
}
|
|
1424
|
-
const hashes = extractInlineHashes(line);
|
|
1425
|
-
if (hashes.length === 0) {
|
|
1426
|
-
continue;
|
|
1427
|
-
}
|
|
1428
|
-
const packageMatch = line.match(/^([a-zA-Z0-9][-a-zA-Z0-9._]*)/);
|
|
1429
|
-
if (packageMatch) {
|
|
1430
|
-
const packageName = packageMatch[1].toLowerCase();
|
|
1431
|
-
hashMap.set(packageName, hashes);
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
return hashMap;
|
|
1435
|
-
}
|
|
1436
|
-
function normalizeRequirement(req) {
|
|
1437
|
-
if (req.type === "RequirementsFile" || req.type === "ConstraintsFile") {
|
|
1438
|
-
return null;
|
|
1439
|
-
}
|
|
1440
|
-
if (req.type === "ProjectURL") {
|
|
1441
|
-
return normalizeProjectURLRequirement(req);
|
|
1442
|
-
}
|
|
1443
|
-
if (req.type === "ProjectName") {
|
|
1444
|
-
return normalizeProjectNameRequirement(req);
|
|
1445
|
-
}
|
|
1446
|
-
return null;
|
|
1447
|
-
}
|
|
1448
|
-
function normalizeProjectNameRequirement(req) {
|
|
1449
|
-
const normalized = {
|
|
1450
|
-
name: req.name
|
|
1451
|
-
};
|
|
1452
|
-
if (req.extras && req.extras.length > 0) {
|
|
1453
|
-
normalized.extras = req.extras;
|
|
1454
|
-
}
|
|
1455
|
-
if (req.versionSpec && req.versionSpec.length > 0) {
|
|
1456
|
-
normalized.version = req.versionSpec.map((spec) => `${spec.operator}${spec.version}`).join(",");
|
|
1457
|
-
}
|
|
1458
|
-
if (req.environmentMarkerTree) {
|
|
1459
|
-
normalized.markers = formatEnvironmentMarkers(req.environmentMarkerTree);
|
|
1460
|
-
}
|
|
1461
|
-
return normalized;
|
|
1462
|
-
}
|
|
1463
|
-
function normalizeProjectURLRequirement(req) {
|
|
1464
|
-
const normalized = {
|
|
1465
|
-
name: req.name
|
|
1158
|
+
pipOptions
|
|
1466
1159
|
};
|
|
1467
|
-
if (req.extras && req.extras.length > 0) {
|
|
1468
|
-
normalized.extras = req.extras;
|
|
1469
|
-
}
|
|
1470
|
-
if (req.environmentMarkerTree) {
|
|
1471
|
-
normalized.markers = formatEnvironmentMarkers(req.environmentMarkerTree);
|
|
1472
|
-
}
|
|
1473
|
-
if (isGitUrl(req.url)) {
|
|
1474
|
-
const parsed = parseGitUrl(req.url);
|
|
1475
|
-
if (parsed) {
|
|
1476
|
-
const source = {
|
|
1477
|
-
git: parsed.url
|
|
1478
|
-
};
|
|
1479
|
-
if (parsed.ref) {
|
|
1480
|
-
source.rev = parsed.ref;
|
|
1481
|
-
}
|
|
1482
|
-
if (parsed.editable) {
|
|
1483
|
-
source.editable = true;
|
|
1484
|
-
}
|
|
1485
|
-
normalized.source = source;
|
|
1486
|
-
}
|
|
1487
|
-
}
|
|
1488
|
-
normalized.url = req.url;
|
|
1489
|
-
return normalized;
|
|
1490
|
-
}
|
|
1491
|
-
function formatEnvironmentMarkers(marker) {
|
|
1492
|
-
if (isEnvironmentMarkerNode(marker)) {
|
|
1493
|
-
const left = formatEnvironmentMarkers(marker.left);
|
|
1494
|
-
const right = formatEnvironmentMarkers(marker.right);
|
|
1495
|
-
return `(${left}) ${marker.operator} (${right})`;
|
|
1496
|
-
}
|
|
1497
|
-
const leaf = marker;
|
|
1498
|
-
const leftStr = formatMarkerValue(leaf.left);
|
|
1499
|
-
const rightStr = formatMarkerValue(leaf.right);
|
|
1500
|
-
return `${leftStr} ${leaf.operator} ${rightStr}`;
|
|
1501
|
-
}
|
|
1502
|
-
function isEnvironmentMarkerNode(marker) {
|
|
1503
|
-
if (typeof marker !== "object" || marker == null) {
|
|
1504
|
-
return false;
|
|
1505
|
-
}
|
|
1506
|
-
const op = marker.operator;
|
|
1507
|
-
return op === "and" || op === "or";
|
|
1508
|
-
}
|
|
1509
|
-
function formatMarkerValue(value) {
|
|
1510
|
-
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
1511
|
-
return value;
|
|
1512
|
-
}
|
|
1513
|
-
return value;
|
|
1514
1160
|
}
|
|
1515
1161
|
|
|
1516
1162
|
// src/manifest/uv-config/schema.ts
|
|
@@ -1907,7 +1553,7 @@ async function discoverPythonPackage({
|
|
|
1907
1553
|
}) {
|
|
1908
1554
|
const entrypointPath = normalizePath(entrypointDir);
|
|
1909
1555
|
const rootPath = normalizePath(rootDir);
|
|
1910
|
-
let prefix =
|
|
1556
|
+
let prefix = import_node_path5.default.relative(rootPath, entrypointPath);
|
|
1911
1557
|
if (prefix.startsWith("..")) {
|
|
1912
1558
|
throw new PythonAnalysisError({
|
|
1913
1559
|
message: "Entrypoint directory outside of repository root",
|
|
@@ -1931,7 +1577,7 @@ async function discoverPythonPackage({
|
|
|
1931
1577
|
if (prefix === "" || prefix === ".") {
|
|
1932
1578
|
break;
|
|
1933
1579
|
}
|
|
1934
|
-
prefix =
|
|
1580
|
+
prefix = import_node_path5.default.dirname(prefix);
|
|
1935
1581
|
}
|
|
1936
1582
|
let entrypointManifest;
|
|
1937
1583
|
let workspaceManifest;
|
|
@@ -1953,8 +1599,8 @@ async function discoverPythonPackage({
|
|
|
1953
1599
|
configs = configs.filter(
|
|
1954
1600
|
(config) => Object.values(config).some(
|
|
1955
1601
|
(cfg) => cfg !== void 0 && isSubpath(
|
|
1956
|
-
|
|
1957
|
-
|
|
1602
|
+
import_node_path5.default.dirname(cfg.path),
|
|
1603
|
+
import_node_path5.default.dirname(entrypointWorkspaceManifest.path)
|
|
1958
1604
|
)
|
|
1959
1605
|
)
|
|
1960
1606
|
);
|
|
@@ -2034,9 +1680,9 @@ function findWorkspaceManifestFor(manifest, manifestStack) {
|
|
|
2034
1680
|
if (!Array.isArray(exclude)) {
|
|
2035
1681
|
exclude = [];
|
|
2036
1682
|
}
|
|
2037
|
-
const entrypointRelPath =
|
|
2038
|
-
|
|
2039
|
-
|
|
1683
|
+
const entrypointRelPath = import_node_path5.default.relative(
|
|
1684
|
+
import_node_path5.default.dirname(parentManifest.path),
|
|
1685
|
+
import_node_path5.default.dirname(manifest.path)
|
|
2040
1686
|
);
|
|
2041
1687
|
if (members.length > 0 && members.some(
|
|
2042
1688
|
(pat) => (0, import_minimatch.match)([entrypointRelPath], pat).length > 0
|
|
@@ -2071,7 +1717,7 @@ async function loadPythonManifest(root, prefix) {
|
|
|
2071
1717
|
"requirements-frozen.txt",
|
|
2072
1718
|
"requirements.txt",
|
|
2073
1719
|
"requirements.in",
|
|
2074
|
-
|
|
1720
|
+
import_node_path5.default.join("requirements", "prod.txt")
|
|
2075
1721
|
]) {
|
|
2076
1722
|
const requirementsTxtManifest = await maybeLoadRequirementsTxt(
|
|
2077
1723
|
root,
|
|
@@ -2090,14 +1736,14 @@ async function loadPythonManifest(root, prefix) {
|
|
|
2090
1736
|
return manifest;
|
|
2091
1737
|
}
|
|
2092
1738
|
async function maybeLoadLockFile(root, subdir) {
|
|
2093
|
-
const uvLockRelPath =
|
|
2094
|
-
const uvLockPath =
|
|
1739
|
+
const uvLockRelPath = import_node_path5.default.join(subdir, "uv.lock");
|
|
1740
|
+
const uvLockPath = import_node_path5.default.join(root, uvLockRelPath);
|
|
2095
1741
|
const uvLockContent = await readFileTextIfExists(uvLockPath);
|
|
2096
1742
|
if (uvLockContent != null) {
|
|
2097
1743
|
return { path: uvLockRelPath, kind: "uv.lock" /* UvLock */ };
|
|
2098
1744
|
}
|
|
2099
|
-
const pylockRelPath =
|
|
2100
|
-
const pylockPath =
|
|
1745
|
+
const pylockRelPath = import_node_path5.default.join(subdir, "pylock.toml");
|
|
1746
|
+
const pylockPath = import_node_path5.default.join(root, pylockRelPath);
|
|
2101
1747
|
const pylockContent = await readFileTextIfExists(pylockPath);
|
|
2102
1748
|
if (pylockContent != null) {
|
|
2103
1749
|
return { path: pylockRelPath, kind: "pylock.toml" /* PylockToml */ };
|
|
@@ -2105,8 +1751,8 @@ async function maybeLoadLockFile(root, subdir) {
|
|
|
2105
1751
|
return void 0;
|
|
2106
1752
|
}
|
|
2107
1753
|
async function maybeLoadPyProjectToml(root, subdir) {
|
|
2108
|
-
const pyprojectTomlRelPath =
|
|
2109
|
-
const pyprojectTomlPath =
|
|
1754
|
+
const pyprojectTomlRelPath = import_node_path5.default.join(subdir, "pyproject.toml");
|
|
1755
|
+
const pyprojectTomlPath = import_node_path5.default.join(root, pyprojectTomlRelPath);
|
|
2110
1756
|
let pyproject;
|
|
2111
1757
|
try {
|
|
2112
1758
|
pyproject = await readConfigIfExists(
|
|
@@ -2127,8 +1773,8 @@ async function maybeLoadPyProjectToml(root, subdir) {
|
|
|
2127
1773
|
if (pyproject == null) {
|
|
2128
1774
|
return null;
|
|
2129
1775
|
}
|
|
2130
|
-
const uvTomlRelPath =
|
|
2131
|
-
const uvTomlPath =
|
|
1776
|
+
const uvTomlRelPath = import_node_path5.default.join(subdir, "uv.toml");
|
|
1777
|
+
const uvTomlPath = import_node_path5.default.join(root, uvTomlRelPath);
|
|
2132
1778
|
let uvToml;
|
|
2133
1779
|
try {
|
|
2134
1780
|
uvToml = await readConfigIfExists(uvTomlPath, UvConfigSchema);
|
|
@@ -2158,8 +1804,8 @@ async function maybeLoadPyProjectToml(root, subdir) {
|
|
|
2158
1804
|
};
|
|
2159
1805
|
}
|
|
2160
1806
|
async function maybeLoadPipfile(root, subdir) {
|
|
2161
|
-
const pipfileRelPath =
|
|
2162
|
-
const pipfilePath =
|
|
1807
|
+
const pipfileRelPath = import_node_path5.default.join(subdir, "Pipfile");
|
|
1808
|
+
const pipfilePath = import_node_path5.default.join(root, pipfileRelPath);
|
|
2163
1809
|
let pipfile;
|
|
2164
1810
|
try {
|
|
2165
1811
|
pipfile = await readConfigIfExists(pipfilePath, PipfileLikeSchema, ".toml");
|
|
@@ -2188,8 +1834,8 @@ async function maybeLoadPipfile(root, subdir) {
|
|
|
2188
1834
|
};
|
|
2189
1835
|
}
|
|
2190
1836
|
async function maybeLoadPipfileLock(root, subdir) {
|
|
2191
|
-
const pipfileLockRelPath =
|
|
2192
|
-
const pipfileLockPath =
|
|
1837
|
+
const pipfileLockRelPath = import_node_path5.default.join(subdir, "Pipfile.lock");
|
|
1838
|
+
const pipfileLockPath = import_node_path5.default.join(root, pipfileLockRelPath);
|
|
2193
1839
|
let pipfileLock;
|
|
2194
1840
|
try {
|
|
2195
1841
|
pipfileLock = await readConfigIfExists(
|
|
@@ -2222,14 +1868,20 @@ async function maybeLoadPipfileLock(root, subdir) {
|
|
|
2222
1868
|
};
|
|
2223
1869
|
}
|
|
2224
1870
|
async function maybeLoadRequirementsTxt(root, subdir, fileName) {
|
|
2225
|
-
const requirementsTxtRelPath =
|
|
2226
|
-
const requirementsTxtPath =
|
|
1871
|
+
const requirementsTxtRelPath = import_node_path5.default.join(subdir, fileName);
|
|
1872
|
+
const requirementsTxtPath = import_node_path5.default.join(root, requirementsTxtRelPath);
|
|
2227
1873
|
const requirementsContent = await readFileTextIfExists(requirementsTxtPath);
|
|
2228
1874
|
if (requirementsContent == null) {
|
|
2229
1875
|
return null;
|
|
2230
1876
|
}
|
|
2231
1877
|
try {
|
|
2232
|
-
const pyproject = convertRequirementsToPyprojectToml(
|
|
1878
|
+
const pyproject = await convertRequirementsToPyprojectToml(
|
|
1879
|
+
requirementsContent,
|
|
1880
|
+
{
|
|
1881
|
+
workingDir: import_node_path5.default.join(root, subdir),
|
|
1882
|
+
packageRoot: root
|
|
1883
|
+
}
|
|
1884
|
+
);
|
|
2233
1885
|
return {
|
|
2234
1886
|
path: requirementsTxtRelPath,
|
|
2235
1887
|
data: pyproject,
|
|
@@ -2263,8 +1915,8 @@ async function loadPythonConfigs(root, prefix) {
|
|
|
2263
1915
|
return configs;
|
|
2264
1916
|
}
|
|
2265
1917
|
async function maybeLoadPythonRequest(root, subdir) {
|
|
2266
|
-
const dotPythonVersionRelPath =
|
|
2267
|
-
const dotPythonVersionPath =
|
|
1918
|
+
const dotPythonVersionRelPath = import_node_path5.default.join(subdir, ".python-version");
|
|
1919
|
+
const dotPythonVersionPath = import_node_path5.default.join(
|
|
2268
1920
|
root,
|
|
2269
1921
|
dotPythonVersionRelPath
|
|
2270
1922
|
);
|
|
@@ -2327,7 +1979,8 @@ function parseUvLock(content, path4) {
|
|
|
2327
1979
|
const packages = (parsed.package ?? []).filter((pkg) => pkg.name && pkg.version).map((pkg) => ({
|
|
2328
1980
|
name: pkg.name,
|
|
2329
1981
|
version: pkg.version,
|
|
2330
|
-
source: pkg.source
|
|
1982
|
+
source: pkg.source,
|
|
1983
|
+
wheels: (pkg.wheels ?? []).map((w) => ({ url: w.url }))
|
|
2331
1984
|
}));
|
|
2332
1985
|
return { version: parsed.version, packages };
|
|
2333
1986
|
}
|
|
@@ -2383,6 +2036,20 @@ function classifyPackages(options) {
|
|
|
2383
2036
|
return { privatePackages, publicPackages, packageVersions };
|
|
2384
2037
|
}
|
|
2385
2038
|
|
|
2039
|
+
// src/manifest/wheel-compat.ts
|
|
2040
|
+
async function isWheelCompatible(wheelFilename, pythonMajor, pythonMinor, osName, archName, osMajor, osMinor) {
|
|
2041
|
+
const mod = await importWasmModule();
|
|
2042
|
+
return mod.isWheelCompatible(
|
|
2043
|
+
wheelFilename,
|
|
2044
|
+
pythonMajor,
|
|
2045
|
+
pythonMinor,
|
|
2046
|
+
osName,
|
|
2047
|
+
archName,
|
|
2048
|
+
osMajor,
|
|
2049
|
+
osMinor
|
|
2050
|
+
);
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2386
2053
|
// src/manifest/python-selector.ts
|
|
2387
2054
|
function selectPython(constraints, available) {
|
|
2388
2055
|
const warnings = [];
|
|
@@ -2696,6 +2363,7 @@ var HashDigestSchema = hashDigestSchema;
|
|
|
2696
2363
|
extendDistRecord,
|
|
2697
2364
|
getStringConstant,
|
|
2698
2365
|
isPrivatePackageSource,
|
|
2366
|
+
isWheelCompatible,
|
|
2699
2367
|
normalizePackageName,
|
|
2700
2368
|
parseUvLock,
|
|
2701
2369
|
scanDistributions,
|