@vercel/python-analysis 0.9.1 → 0.10.1
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 +281 -561
- package/dist/index.d.ts +4 -2
- package/dist/index.js +254 -536
- package/dist/manifest/package.d.ts +2 -0
- package/dist/manifest/pep508.d.ts +19 -0
- package/dist/manifest/pyproject/schema.zod.d.ts +46 -4
- package/dist/manifest/pyproject/types.d.ts +12 -2
- package/dist/manifest/python-specifiers.d.ts +2 -0
- package/dist/manifest/requirements-txt-parser.d.ts +18 -29
- package/dist/manifest/uv-config/schema.zod.d.ts +3 -0
- package/dist/manifest/uv-config/types.d.ts +5 -0
- package/dist/manifest/uv-lock-parser.d.ts +10 -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 +35 -0
- package/dist/wasm/vercel_python_analysis.js +3604 -748
- package/package.json +1 -2
package/dist/index.cjs
CHANGED
|
@@ -70,7 +70,9 @@ __export(src_exports, {
|
|
|
70
70
|
extendDistRecord: () => extendDistRecord,
|
|
71
71
|
getStringConstant: () => getStringConstant,
|
|
72
72
|
isPrivatePackageSource: () => isPrivatePackageSource,
|
|
73
|
+
isWheelCompatible: () => isWheelCompatible,
|
|
73
74
|
normalizePackageName: () => normalizePackageName2,
|
|
75
|
+
parsePep508: () => parsePep508,
|
|
74
76
|
parseUvLock: () => parseUvLock,
|
|
75
77
|
scanDistributions: () => scanDistributions,
|
|
76
78
|
selectPython: () => selectPython,
|
|
@@ -83,6 +85,84 @@ module.exports = __toCommonJS(src_exports);
|
|
|
83
85
|
var import_promises = require("fs/promises");
|
|
84
86
|
var import_node_module = require("module");
|
|
85
87
|
var import_node_path = require("path");
|
|
88
|
+
|
|
89
|
+
// src/wasm/host-utils.ts
|
|
90
|
+
var import_node_async_hooks = require("async_hooks");
|
|
91
|
+
var import_posix = require("path/posix");
|
|
92
|
+
var import_url = require("url");
|
|
93
|
+
var readFileStorage = new import_node_async_hooks.AsyncLocalStorage();
|
|
94
|
+
var WitResultError = class extends Error {
|
|
95
|
+
constructor(message) {
|
|
96
|
+
super(message);
|
|
97
|
+
this.payload = message;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function createHostUtils() {
|
|
101
|
+
return {
|
|
102
|
+
readFile(path4) {
|
|
103
|
+
const ctx = readFileStorage.getStore();
|
|
104
|
+
if (ctx?.readFile) {
|
|
105
|
+
const relative2 = stripWorkingDir(path4, ctx.workingDir);
|
|
106
|
+
if (relative2 != null) {
|
|
107
|
+
const result = ctx.readFile(relative2);
|
|
108
|
+
if (result != null)
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
throw new WitResultError(`File not found: ${path4}`);
|
|
113
|
+
},
|
|
114
|
+
domainToAscii(domain) {
|
|
115
|
+
try {
|
|
116
|
+
if (/[:#?/@[\]%\\\t\n\r]/.test(domain)) {
|
|
117
|
+
throw new Error("domain contains invalid characters");
|
|
118
|
+
}
|
|
119
|
+
const url = new URL(`http://${domain}/`);
|
|
120
|
+
if (url.hostname === "" && domain !== "") {
|
|
121
|
+
throw new Error("domain resolved to empty hostname");
|
|
122
|
+
}
|
|
123
|
+
return url.hostname;
|
|
124
|
+
} catch {
|
|
125
|
+
throw { payload: `Invalid domain: ${domain}` };
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
domainToUnicode(domain) {
|
|
129
|
+
const result = (0, import_url.domainToUnicode)(domain);
|
|
130
|
+
if (result !== "" || domain === "") {
|
|
131
|
+
return [result, true];
|
|
132
|
+
}
|
|
133
|
+
return [domain, false];
|
|
134
|
+
},
|
|
135
|
+
nfcNormalize(s) {
|
|
136
|
+
return s.normalize("NFC");
|
|
137
|
+
},
|
|
138
|
+
nfdNormalize(s) {
|
|
139
|
+
return s.normalize("NFD");
|
|
140
|
+
},
|
|
141
|
+
nfkcNormalize(s) {
|
|
142
|
+
return s.normalize("NFKC");
|
|
143
|
+
},
|
|
144
|
+
nfkdNormalize(s) {
|
|
145
|
+
return s.normalize("NFKD");
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function stripWorkingDir(path4, workingDir) {
|
|
150
|
+
const normalized = (0, import_posix.normalize)(path4);
|
|
151
|
+
if (!workingDir) {
|
|
152
|
+
return normalized;
|
|
153
|
+
}
|
|
154
|
+
const normalizedDir = (0, import_posix.normalize)(workingDir);
|
|
155
|
+
const prefix = normalizedDir.endsWith("/") ? normalizedDir : normalizedDir + "/";
|
|
156
|
+
if (normalized.startsWith(prefix)) {
|
|
157
|
+
return normalized.slice(prefix.length);
|
|
158
|
+
}
|
|
159
|
+
if (normalized === normalizedDir) {
|
|
160
|
+
return "";
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// src/wasm/load.ts
|
|
86
166
|
var WASI_SHIM_PATH = "@bytecodealliance/preview2-shim/instantiation";
|
|
87
167
|
var WASM_MODULE_PATH = "#wasm/vercel_python_analysis.js";
|
|
88
168
|
var wasmInstance = null;
|
|
@@ -110,7 +190,10 @@ async function importWasmModule() {
|
|
|
110
190
|
const wasiShimModule = await import(WASI_SHIM_PATH);
|
|
111
191
|
const WASIShim = wasiShimModule.WASIShim;
|
|
112
192
|
const wasmModule = await import(WASM_MODULE_PATH);
|
|
113
|
-
const imports =
|
|
193
|
+
const imports = {
|
|
194
|
+
...new WASIShim().getImportObject(),
|
|
195
|
+
"vercel:python-analysis/host-utils": createHostUtils()
|
|
196
|
+
};
|
|
114
197
|
const instance = await wasmModule.instantiate(getCoreModule, imports);
|
|
115
198
|
wasmInstance = instance;
|
|
116
199
|
return instance;
|
|
@@ -183,6 +266,41 @@ function mergeExtras(existing, additional) {
|
|
|
183
266
|
}
|
|
184
267
|
return result.size > 0 ? Array.from(result) : void 0;
|
|
185
268
|
}
|
|
269
|
+
function wasmEntryToRequirement(entry) {
|
|
270
|
+
const req = {
|
|
271
|
+
name: entry.name || ""
|
|
272
|
+
};
|
|
273
|
+
if (entry.versionSpec) {
|
|
274
|
+
req.version = entry.versionSpec;
|
|
275
|
+
}
|
|
276
|
+
if (entry.extras.length > 0) {
|
|
277
|
+
req.extras = entry.extras;
|
|
278
|
+
}
|
|
279
|
+
if (entry.markers) {
|
|
280
|
+
req.markers = entry.markers;
|
|
281
|
+
}
|
|
282
|
+
if (entry.url) {
|
|
283
|
+
req.url = entry.url;
|
|
284
|
+
}
|
|
285
|
+
return req;
|
|
286
|
+
}
|
|
287
|
+
async function parsePep508(depOrDeps) {
|
|
288
|
+
const wasm = await importWasmModule();
|
|
289
|
+
if (Array.isArray(depOrDeps)) {
|
|
290
|
+
return depOrDeps.map((dep) => {
|
|
291
|
+
try {
|
|
292
|
+
return wasmEntryToRequirement(wasm.parsePep508(dep));
|
|
293
|
+
} catch {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
return wasmEntryToRequirement(wasm.parsePep508(depOrDeps));
|
|
300
|
+
} catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
186
304
|
|
|
187
305
|
// src/manifest/dist-metadata.ts
|
|
188
306
|
async function readDistInfoFile(distInfoDir, filename) {
|
|
@@ -329,7 +447,7 @@ async function extendDistRecord(sitePackagesDir, packageName, paths) {
|
|
|
329
447
|
}
|
|
330
448
|
|
|
331
449
|
// src/manifest/package.ts
|
|
332
|
-
var
|
|
450
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
333
451
|
var import_minimatch = require("minimatch");
|
|
334
452
|
|
|
335
453
|
// src/util/config.ts
|
|
@@ -837,7 +955,8 @@ var uvIndexEntrySchema = import_zod3.z.object({
|
|
|
837
955
|
var uvConfigSchema = import_zod3.z.object({
|
|
838
956
|
sources: import_zod3.z.record(import_zod3.z.union([dependencySourceSchema, import_zod3.z.array(dependencySourceSchema)])).optional(),
|
|
839
957
|
index: import_zod3.z.array(uvIndexEntrySchema).optional(),
|
|
840
|
-
workspace: uvConfigWorkspaceSchema.optional()
|
|
958
|
+
workspace: uvConfigWorkspaceSchema.optional(),
|
|
959
|
+
"dev-dependencies": import_zod3.z.array(import_zod3.z.string()).optional()
|
|
841
960
|
});
|
|
842
961
|
|
|
843
962
|
// src/manifest/pyproject/schema.zod.ts
|
|
@@ -878,7 +997,16 @@ var pyProjectProjectSchema = import_zod4.z.object({
|
|
|
878
997
|
scripts: import_zod4.z.record(import_zod4.z.string()).optional(),
|
|
879
998
|
entry_points: import_zod4.z.record(import_zod4.z.record(import_zod4.z.string())).optional()
|
|
880
999
|
});
|
|
881
|
-
var
|
|
1000
|
+
var dependencyGroupIncludeSchema = import_zod4.z.object({
|
|
1001
|
+
"include-group": import_zod4.z.string()
|
|
1002
|
+
});
|
|
1003
|
+
var dependencyGroupEntrySchema = import_zod4.z.union([
|
|
1004
|
+
import_zod4.z.string(),
|
|
1005
|
+
dependencyGroupIncludeSchema
|
|
1006
|
+
]);
|
|
1007
|
+
var pyProjectDependencyGroupsSchema = import_zod4.z.record(
|
|
1008
|
+
import_zod4.z.array(dependencyGroupEntrySchema)
|
|
1009
|
+
);
|
|
882
1010
|
var pyProjectToolSectionSchema = import_zod4.z.object({
|
|
883
1011
|
uv: uvConfigSchema.optional()
|
|
884
1012
|
});
|
|
@@ -902,356 +1030,98 @@ var PyProjectToolSectionSchema = pyProjectToolSectionSchema.passthrough();
|
|
|
902
1030
|
var PyProjectTomlSchema = pyProjectTomlSchema.passthrough();
|
|
903
1031
|
|
|
904
1032
|
// src/manifest/requirements-txt-parser.ts
|
|
905
|
-
var
|
|
906
|
-
var import_pip_requirements_js = require("pip-requirements-js");
|
|
1033
|
+
var import_posix2 = require("path/posix");
|
|
907
1034
|
var PRIMARY_INDEX_NAME = "primary";
|
|
908
1035
|
var EXTRA_INDEX_PREFIX = "extra-";
|
|
909
1036
|
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);
|
|
1037
|
+
async function parseWithWasm(content, readFile4, workingDir) {
|
|
1038
|
+
const wasm = await importWasmModule();
|
|
1039
|
+
const resolvedDir = workingDir ?? "/";
|
|
1040
|
+
if (readFile4) {
|
|
1041
|
+
return readFileStorage.run(
|
|
1042
|
+
{ readFile: readFile4, workingDir: resolvedDir },
|
|
1043
|
+
() => wasm.parseRequirementsTxt(content, resolvedDir, void 0)
|
|
1044
|
+
);
|
|
933
1045
|
}
|
|
934
|
-
return
|
|
935
|
-
url: remaining,
|
|
936
|
-
ref,
|
|
937
|
-
egg
|
|
938
|
-
};
|
|
1046
|
+
return wasm.parseRequirementsTxt(content, workingDir ?? void 0, void 0);
|
|
939
1047
|
}
|
|
940
|
-
function
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
extraIndexUrls: []
|
|
948
|
-
};
|
|
949
|
-
const lines = fileContent.split(/\r?\n/);
|
|
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;
|
|
1048
|
+
function wasmEntryToNormalized(entry, editable) {
|
|
1049
|
+
let name = entry.name || "";
|
|
1050
|
+
if (!name && entry.url) {
|
|
1051
|
+
const urlPath = entry.url.replace(/^file:\/\//, "");
|
|
1052
|
+
const basename = urlPath.replace(/\/$/, "").split("/").pop();
|
|
1053
|
+
if (basename && !basename.includes(".")) {
|
|
1054
|
+
name = basename;
|
|
990
1055
|
}
|
|
991
1056
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
options,
|
|
995
|
-
pathRequirements,
|
|
996
|
-
editableRequirements
|
|
1057
|
+
const req = {
|
|
1058
|
+
name
|
|
997
1059
|
};
|
|
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
|
-
}
|
|
1060
|
+
if (entry.versionSpec) {
|
|
1061
|
+
req.version = entry.versionSpec;
|
|
1006
1062
|
}
|
|
1007
|
-
if (
|
|
1008
|
-
|
|
1009
|
-
if (path4) {
|
|
1010
|
-
options.constraintFiles.push(path4);
|
|
1011
|
-
return true;
|
|
1012
|
-
}
|
|
1063
|
+
if (entry.extras.length > 0) {
|
|
1064
|
+
req.extras = entry.extras;
|
|
1013
1065
|
}
|
|
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
|
-
}
|
|
1066
|
+
if (entry.markers) {
|
|
1067
|
+
req.markers = entry.markers;
|
|
1034
1068
|
}
|
|
1035
|
-
if (
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
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
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
if (stem === filename)
|
|
1158
|
-
return null;
|
|
1159
|
-
const parts = stem.split("-");
|
|
1160
|
-
let versionIdx = -1;
|
|
1161
|
-
for (let i = 1; i < parts.length; i++) {
|
|
1162
|
-
if (/^\d/.test(parts[i])) {
|
|
1163
|
-
versionIdx = i;
|
|
1164
|
-
break;
|
|
1069
|
+
if (entry.vcs) {
|
|
1070
|
+
const source = {
|
|
1071
|
+
git: entry.vcs.url
|
|
1072
|
+
};
|
|
1073
|
+
if (entry.vcs.rev) {
|
|
1074
|
+
source.rev = entry.vcs.rev;
|
|
1165
1075
|
}
|
|
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;
|
|
1076
|
+
if (editable) {
|
|
1077
|
+
source.editable = true;
|
|
1200
1078
|
}
|
|
1201
|
-
|
|
1202
|
-
const cleanPath = line.replace(/\/+$/, "");
|
|
1203
|
-
filename = cleanPath.split("/").pop() || "";
|
|
1204
|
-
}
|
|
1205
|
-
if (!filename)
|
|
1206
|
-
return null;
|
|
1207
|
-
let name;
|
|
1208
|
-
let version;
|
|
1209
|
-
const wheelParsed = parseWheelFilename(filename);
|
|
1210
|
-
if (wheelParsed) {
|
|
1211
|
-
name = wheelParsed.name;
|
|
1212
|
-
version = wheelParsed.version;
|
|
1079
|
+
req.source = source;
|
|
1213
1080
|
}
|
|
1214
|
-
if (
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1081
|
+
if (entry.url) {
|
|
1082
|
+
if (entry.url.startsWith("file://") && !entry.vcs) {
|
|
1083
|
+
const given = entry.givenUrl ?? entry.url;
|
|
1084
|
+
const path4 = given.startsWith("file://") ? given.slice("file://".length) : given;
|
|
1085
|
+
req.source = { path: path4, ...editable ? { editable: true } : {} };
|
|
1086
|
+
} else {
|
|
1087
|
+
req.url = entry.url;
|
|
1219
1088
|
}
|
|
1220
1089
|
}
|
|
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 };
|
|
1090
|
+
if (entry.hashes.length > 0) {
|
|
1091
|
+
req.hashes = entry.hashes;
|
|
1240
1092
|
}
|
|
1241
1093
|
return req;
|
|
1242
1094
|
}
|
|
1243
|
-
function
|
|
1095
|
+
function rebasePath(p, workingDir, packageRoot) {
|
|
1096
|
+
if (!workingDir || !packageRoot || workingDir === packageRoot)
|
|
1097
|
+
return p;
|
|
1098
|
+
if ((0, import_posix2.isAbsolute)(p))
|
|
1099
|
+
return p;
|
|
1100
|
+
const abs = (0, import_posix2.join)(workingDir, p);
|
|
1101
|
+
const rel = (0, import_posix2.relative)(packageRoot, abs);
|
|
1102
|
+
if ((0, import_posix2.isAbsolute)(rel))
|
|
1103
|
+
return rel;
|
|
1104
|
+
if (rel.startsWith(".."))
|
|
1105
|
+
return rel;
|
|
1106
|
+
return "./" + rel;
|
|
1107
|
+
}
|
|
1108
|
+
async function convertRequirementsToPyprojectToml(fileContent, options) {
|
|
1244
1109
|
const pyproject = {};
|
|
1245
|
-
const parsed = parseRequirementsFile(fileContent,
|
|
1110
|
+
const parsed = await parseRequirementsFile(fileContent, options);
|
|
1246
1111
|
const deps = [];
|
|
1247
1112
|
const sources = {};
|
|
1113
|
+
const { workingDir, packageRoot } = options ?? {};
|
|
1248
1114
|
for (const req of parsed.requirements) {
|
|
1249
1115
|
deps.push(formatPep508(req));
|
|
1250
1116
|
if (req.source) {
|
|
1117
|
+
const source = { ...req.source };
|
|
1118
|
+
if (source.path) {
|
|
1119
|
+
source.path = rebasePath(source.path, workingDir, packageRoot);
|
|
1120
|
+
}
|
|
1251
1121
|
if (Object.prototype.hasOwnProperty.call(sources, req.name)) {
|
|
1252
|
-
sources[req.name].push(
|
|
1122
|
+
sources[req.name].push(source);
|
|
1253
1123
|
} else {
|
|
1254
|
-
sources[req.name] = [
|
|
1124
|
+
sources[req.name] = [source];
|
|
1255
1125
|
}
|
|
1256
1126
|
}
|
|
1257
1127
|
}
|
|
@@ -1301,217 +1171,39 @@ function buildIndexEntries(pipOptions) {
|
|
|
1301
1171
|
}
|
|
1302
1172
|
return indexes;
|
|
1303
1173
|
}
|
|
1304
|
-
function parseRequirementsFile(fileContent,
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1174
|
+
async function parseRequirementsFile(fileContent, options) {
|
|
1175
|
+
const wasmResult = await parseWithWasm(
|
|
1176
|
+
fileContent,
|
|
1177
|
+
options?.readFile,
|
|
1178
|
+
options?.workingDir
|
|
1179
|
+
);
|
|
1180
|
+
return processWasmResult(wasmResult);
|
|
1307
1181
|
}
|
|
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);
|
|
1182
|
+
function processWasmResult(wasmResult) {
|
|
1312
1183
|
const normalized = [];
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1184
|
+
for (const entry of wasmResult.requirements) {
|
|
1185
|
+
normalized.push(wasmEntryToNormalized(entry, false));
|
|
1186
|
+
}
|
|
1187
|
+
for (const entry of wasmResult.editables) {
|
|
1188
|
+
const norm = wasmEntryToNormalized(entry, true);
|
|
1189
|
+
if (!norm.source && !entry.vcs) {
|
|
1190
|
+
norm.source = { path: entry.pep508, editable: true };
|
|
1191
|
+
} else if (norm.source && !norm.source.editable) {
|
|
1192
|
+
norm.source.editable = true;
|
|
1193
|
+
}
|
|
1194
|
+
normalized.push(norm);
|
|
1195
|
+
}
|
|
1196
|
+
const pipOptions = {
|
|
1197
|
+
indexUrl: wasmResult.indexUrl || void 0,
|
|
1198
|
+
extraIndexUrls: [...wasmResult.extraIndexUrls],
|
|
1199
|
+
findLinks: wasmResult.findLinks.length > 0 ? [...wasmResult.findLinks] : void 0,
|
|
1200
|
+
noIndex: wasmResult.noIndex || void 0
|
|
1320
1201
|
};
|
|
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
1202
|
return {
|
|
1408
1203
|
requirements: normalized,
|
|
1409
|
-
pipOptions
|
|
1204
|
+
pipOptions
|
|
1410
1205
|
};
|
|
1411
1206
|
}
|
|
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
|
|
1466
|
-
};
|
|
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
|
-
}
|
|
1515
1207
|
|
|
1516
1208
|
// src/manifest/uv-config/schema.ts
|
|
1517
1209
|
var UvConfigWorkspaceSchema = uvConfigWorkspaceSchema.passthrough();
|
|
@@ -1907,7 +1599,7 @@ async function discoverPythonPackage({
|
|
|
1907
1599
|
}) {
|
|
1908
1600
|
const entrypointPath = normalizePath(entrypointDir);
|
|
1909
1601
|
const rootPath = normalizePath(rootDir);
|
|
1910
|
-
let prefix =
|
|
1602
|
+
let prefix = import_node_path5.default.relative(rootPath, entrypointPath);
|
|
1911
1603
|
if (prefix.startsWith("..")) {
|
|
1912
1604
|
throw new PythonAnalysisError({
|
|
1913
1605
|
message: "Entrypoint directory outside of repository root",
|
|
@@ -1931,7 +1623,7 @@ async function discoverPythonPackage({
|
|
|
1931
1623
|
if (prefix === "" || prefix === ".") {
|
|
1932
1624
|
break;
|
|
1933
1625
|
}
|
|
1934
|
-
prefix =
|
|
1626
|
+
prefix = import_node_path5.default.dirname(prefix);
|
|
1935
1627
|
}
|
|
1936
1628
|
let entrypointManifest;
|
|
1937
1629
|
let workspaceManifest;
|
|
@@ -1953,8 +1645,8 @@ async function discoverPythonPackage({
|
|
|
1953
1645
|
configs = configs.filter(
|
|
1954
1646
|
(config) => Object.values(config).some(
|
|
1955
1647
|
(cfg) => cfg !== void 0 && isSubpath(
|
|
1956
|
-
|
|
1957
|
-
|
|
1648
|
+
import_node_path5.default.dirname(cfg.path),
|
|
1649
|
+
import_node_path5.default.dirname(entrypointWorkspaceManifest.path)
|
|
1958
1650
|
)
|
|
1959
1651
|
)
|
|
1960
1652
|
);
|
|
@@ -1981,7 +1673,8 @@ function computeRequiresPython(manifest, workspaceManifest, configs) {
|
|
|
1981
1673
|
constraints.push({
|
|
1982
1674
|
request: pythonVersionConfig.data,
|
|
1983
1675
|
source: pythonVersionConfig.path,
|
|
1984
|
-
prettySource: pythonVersionConfig.path
|
|
1676
|
+
prettySource: pythonVersionConfig.path,
|
|
1677
|
+
specifier: pythonVersionConfig.specifier
|
|
1985
1678
|
});
|
|
1986
1679
|
hasPythonVersionFile = true;
|
|
1987
1680
|
break;
|
|
@@ -1996,7 +1689,8 @@ function computeRequiresPython(manifest, workspaceManifest, configs) {
|
|
|
1996
1689
|
constraints.push({
|
|
1997
1690
|
request: [request],
|
|
1998
1691
|
source: manifest.path,
|
|
1999
|
-
prettySource: `"requires-python" key in ${manifest.path}
|
|
1692
|
+
prettySource: `"requires-python" key in ${manifest.path}`,
|
|
1693
|
+
specifier: manifestRequiresPython
|
|
2000
1694
|
});
|
|
2001
1695
|
}
|
|
2002
1696
|
} else {
|
|
@@ -2008,7 +1702,8 @@ function computeRequiresPython(manifest, workspaceManifest, configs) {
|
|
|
2008
1702
|
constraints.push({
|
|
2009
1703
|
request: [request],
|
|
2010
1704
|
source: workspaceManifest.path,
|
|
2011
|
-
prettySource: `"requires-python" key in ${workspaceManifest.path}
|
|
1705
|
+
prettySource: `"requires-python" key in ${workspaceManifest.path}`,
|
|
1706
|
+
specifier: workspaceRequiresPython
|
|
2012
1707
|
});
|
|
2013
1708
|
}
|
|
2014
1709
|
}
|
|
@@ -2034,9 +1729,9 @@ function findWorkspaceManifestFor(manifest, manifestStack) {
|
|
|
2034
1729
|
if (!Array.isArray(exclude)) {
|
|
2035
1730
|
exclude = [];
|
|
2036
1731
|
}
|
|
2037
|
-
const entrypointRelPath =
|
|
2038
|
-
|
|
2039
|
-
|
|
1732
|
+
const entrypointRelPath = import_node_path5.default.relative(
|
|
1733
|
+
import_node_path5.default.dirname(parentManifest.path),
|
|
1734
|
+
import_node_path5.default.dirname(manifest.path)
|
|
2040
1735
|
);
|
|
2041
1736
|
if (members.length > 0 && members.some(
|
|
2042
1737
|
(pat) => (0, import_minimatch.match)([entrypointRelPath], pat).length > 0
|
|
@@ -2071,7 +1766,7 @@ async function loadPythonManifest(root, prefix) {
|
|
|
2071
1766
|
"requirements-frozen.txt",
|
|
2072
1767
|
"requirements.txt",
|
|
2073
1768
|
"requirements.in",
|
|
2074
|
-
|
|
1769
|
+
import_node_path5.default.join("requirements", "prod.txt")
|
|
2075
1770
|
]) {
|
|
2076
1771
|
const requirementsTxtManifest = await maybeLoadRequirementsTxt(
|
|
2077
1772
|
root,
|
|
@@ -2090,14 +1785,14 @@ async function loadPythonManifest(root, prefix) {
|
|
|
2090
1785
|
return manifest;
|
|
2091
1786
|
}
|
|
2092
1787
|
async function maybeLoadLockFile(root, subdir) {
|
|
2093
|
-
const uvLockRelPath =
|
|
2094
|
-
const uvLockPath =
|
|
1788
|
+
const uvLockRelPath = import_node_path5.default.join(subdir, "uv.lock");
|
|
1789
|
+
const uvLockPath = import_node_path5.default.join(root, uvLockRelPath);
|
|
2095
1790
|
const uvLockContent = await readFileTextIfExists(uvLockPath);
|
|
2096
1791
|
if (uvLockContent != null) {
|
|
2097
1792
|
return { path: uvLockRelPath, kind: "uv.lock" /* UvLock */ };
|
|
2098
1793
|
}
|
|
2099
|
-
const pylockRelPath =
|
|
2100
|
-
const pylockPath =
|
|
1794
|
+
const pylockRelPath = import_node_path5.default.join(subdir, "pylock.toml");
|
|
1795
|
+
const pylockPath = import_node_path5.default.join(root, pylockRelPath);
|
|
2101
1796
|
const pylockContent = await readFileTextIfExists(pylockPath);
|
|
2102
1797
|
if (pylockContent != null) {
|
|
2103
1798
|
return { path: pylockRelPath, kind: "pylock.toml" /* PylockToml */ };
|
|
@@ -2105,8 +1800,8 @@ async function maybeLoadLockFile(root, subdir) {
|
|
|
2105
1800
|
return void 0;
|
|
2106
1801
|
}
|
|
2107
1802
|
async function maybeLoadPyProjectToml(root, subdir) {
|
|
2108
|
-
const pyprojectTomlRelPath =
|
|
2109
|
-
const pyprojectTomlPath =
|
|
1803
|
+
const pyprojectTomlRelPath = import_node_path5.default.join(subdir, "pyproject.toml");
|
|
1804
|
+
const pyprojectTomlPath = import_node_path5.default.join(root, pyprojectTomlRelPath);
|
|
2110
1805
|
let pyproject;
|
|
2111
1806
|
try {
|
|
2112
1807
|
pyproject = await readConfigIfExists(
|
|
@@ -2127,8 +1822,8 @@ async function maybeLoadPyProjectToml(root, subdir) {
|
|
|
2127
1822
|
if (pyproject == null) {
|
|
2128
1823
|
return null;
|
|
2129
1824
|
}
|
|
2130
|
-
const uvTomlRelPath =
|
|
2131
|
-
const uvTomlPath =
|
|
1825
|
+
const uvTomlRelPath = import_node_path5.default.join(subdir, "uv.toml");
|
|
1826
|
+
const uvTomlPath = import_node_path5.default.join(root, uvTomlRelPath);
|
|
2132
1827
|
let uvToml;
|
|
2133
1828
|
try {
|
|
2134
1829
|
uvToml = await readConfigIfExists(uvTomlPath, UvConfigSchema);
|
|
@@ -2158,8 +1853,8 @@ async function maybeLoadPyProjectToml(root, subdir) {
|
|
|
2158
1853
|
};
|
|
2159
1854
|
}
|
|
2160
1855
|
async function maybeLoadPipfile(root, subdir) {
|
|
2161
|
-
const pipfileRelPath =
|
|
2162
|
-
const pipfilePath =
|
|
1856
|
+
const pipfileRelPath = import_node_path5.default.join(subdir, "Pipfile");
|
|
1857
|
+
const pipfilePath = import_node_path5.default.join(root, pipfileRelPath);
|
|
2163
1858
|
let pipfile;
|
|
2164
1859
|
try {
|
|
2165
1860
|
pipfile = await readConfigIfExists(pipfilePath, PipfileLikeSchema, ".toml");
|
|
@@ -2188,8 +1883,8 @@ async function maybeLoadPipfile(root, subdir) {
|
|
|
2188
1883
|
};
|
|
2189
1884
|
}
|
|
2190
1885
|
async function maybeLoadPipfileLock(root, subdir) {
|
|
2191
|
-
const pipfileLockRelPath =
|
|
2192
|
-
const pipfileLockPath =
|
|
1886
|
+
const pipfileLockRelPath = import_node_path5.default.join(subdir, "Pipfile.lock");
|
|
1887
|
+
const pipfileLockPath = import_node_path5.default.join(root, pipfileLockRelPath);
|
|
2193
1888
|
let pipfileLock;
|
|
2194
1889
|
try {
|
|
2195
1890
|
pipfileLock = await readConfigIfExists(
|
|
@@ -2222,14 +1917,20 @@ async function maybeLoadPipfileLock(root, subdir) {
|
|
|
2222
1917
|
};
|
|
2223
1918
|
}
|
|
2224
1919
|
async function maybeLoadRequirementsTxt(root, subdir, fileName) {
|
|
2225
|
-
const requirementsTxtRelPath =
|
|
2226
|
-
const requirementsTxtPath =
|
|
1920
|
+
const requirementsTxtRelPath = import_node_path5.default.join(subdir, fileName);
|
|
1921
|
+
const requirementsTxtPath = import_node_path5.default.join(root, requirementsTxtRelPath);
|
|
2227
1922
|
const requirementsContent = await readFileTextIfExists(requirementsTxtPath);
|
|
2228
1923
|
if (requirementsContent == null) {
|
|
2229
1924
|
return null;
|
|
2230
1925
|
}
|
|
2231
1926
|
try {
|
|
2232
|
-
const pyproject = convertRequirementsToPyprojectToml(
|
|
1927
|
+
const pyproject = await convertRequirementsToPyprojectToml(
|
|
1928
|
+
requirementsContent,
|
|
1929
|
+
{
|
|
1930
|
+
workingDir: import_node_path5.default.join(root, subdir),
|
|
1931
|
+
packageRoot: root
|
|
1932
|
+
}
|
|
1933
|
+
);
|
|
2233
1934
|
return {
|
|
2234
1935
|
path: requirementsTxtRelPath,
|
|
2235
1936
|
data: pyproject,
|
|
@@ -2263,8 +1964,8 @@ async function loadPythonConfigs(root, prefix) {
|
|
|
2263
1964
|
return configs;
|
|
2264
1965
|
}
|
|
2265
1966
|
async function maybeLoadPythonRequest(root, subdir) {
|
|
2266
|
-
const dotPythonVersionRelPath =
|
|
2267
|
-
const dotPythonVersionPath =
|
|
1967
|
+
const dotPythonVersionRelPath = import_node_path5.default.join(subdir, ".python-version");
|
|
1968
|
+
const dotPythonVersionPath = import_node_path5.default.join(
|
|
2268
1969
|
root,
|
|
2269
1970
|
dotPythonVersionRelPath
|
|
2270
1971
|
);
|
|
@@ -2283,7 +1984,8 @@ async function maybeLoadPythonRequest(root, subdir) {
|
|
|
2283
1984
|
return {
|
|
2284
1985
|
kind: ".python-version" /* PythonVersion */,
|
|
2285
1986
|
path: dotPythonVersionRelPath,
|
|
2286
|
-
data: pyreq
|
|
1987
|
+
data: pyreq,
|
|
1988
|
+
specifier: data.trim()
|
|
2287
1989
|
};
|
|
2288
1990
|
}
|
|
2289
1991
|
|
|
@@ -2327,7 +2029,9 @@ function parseUvLock(content, path4) {
|
|
|
2327
2029
|
const packages = (parsed.package ?? []).filter((pkg) => pkg.name && pkg.version).map((pkg) => ({
|
|
2328
2030
|
name: pkg.name,
|
|
2329
2031
|
version: pkg.version,
|
|
2330
|
-
source: pkg.source
|
|
2032
|
+
source: pkg.source,
|
|
2033
|
+
wheels: (pkg.wheels ?? []).map((w) => ({ url: w.url })),
|
|
2034
|
+
...pkg.dependencies ? { dependencies: pkg.dependencies } : {}
|
|
2331
2035
|
}));
|
|
2332
2036
|
return { version: parsed.version, packages };
|
|
2333
2037
|
}
|
|
@@ -2383,6 +2087,20 @@ function classifyPackages(options) {
|
|
|
2383
2087
|
return { privatePackages, publicPackages, packageVersions };
|
|
2384
2088
|
}
|
|
2385
2089
|
|
|
2090
|
+
// src/manifest/wheel-compat.ts
|
|
2091
|
+
async function isWheelCompatible(wheelFilename, pythonMajor, pythonMinor, osName, archName, osMajor, osMinor) {
|
|
2092
|
+
const mod = await importWasmModule();
|
|
2093
|
+
return mod.isWheelCompatible(
|
|
2094
|
+
wheelFilename,
|
|
2095
|
+
pythonMajor,
|
|
2096
|
+
pythonMinor,
|
|
2097
|
+
osName,
|
|
2098
|
+
archName,
|
|
2099
|
+
osMajor,
|
|
2100
|
+
osMinor
|
|
2101
|
+
);
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2386
2104
|
// src/manifest/python-selector.ts
|
|
2387
2105
|
function selectPython(constraints, available) {
|
|
2388
2106
|
const warnings = [];
|
|
@@ -2696,7 +2414,9 @@ var HashDigestSchema = hashDigestSchema;
|
|
|
2696
2414
|
extendDistRecord,
|
|
2697
2415
|
getStringConstant,
|
|
2698
2416
|
isPrivatePackageSource,
|
|
2417
|
+
isWheelCompatible,
|
|
2699
2418
|
normalizePackageName,
|
|
2419
|
+
parsePep508,
|
|
2700
2420
|
parseUvLock,
|
|
2701
2421
|
scanDistributions,
|
|
2702
2422
|
selectPython,
|