@vercel/rust 1.2.0 → 1.4.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.js +307 -74
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
build: () => build,
|
|
34
|
+
diagnostics: () => diagnostics,
|
|
34
35
|
prepareCache: () => prepareCache,
|
|
35
36
|
shouldServe: () => shouldServe,
|
|
36
37
|
startDevServer: () => startDevServer2,
|
|
@@ -38,7 +39,7 @@ __export(src_exports, {
|
|
|
38
39
|
});
|
|
39
40
|
module.exports = __toCommonJS(src_exports);
|
|
40
41
|
var import_node_path4 = __toESM(require("path"));
|
|
41
|
-
var
|
|
42
|
+
var import_build_utils7 = require("@vercel/build-utils");
|
|
42
43
|
var import_execa4 = __toESM(require("execa"));
|
|
43
44
|
|
|
44
45
|
// src/lib/rust-toolchain.ts
|
|
@@ -74,12 +75,11 @@ var import_node_fs = require("fs");
|
|
|
74
75
|
var import_node_path = __toESM(require("path"));
|
|
75
76
|
var import_smol_toml = require("smol-toml");
|
|
76
77
|
var import_execa2 = __toESM(require("execa"));
|
|
77
|
-
async function getCargoMetadata(options) {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
78
|
+
async function getCargoMetadata(options, filterPlatform) {
|
|
79
|
+
const args = ["metadata", "--format-version", "1"];
|
|
80
|
+
if (filterPlatform)
|
|
81
|
+
args.push("--filter-platform", filterPlatform);
|
|
82
|
+
const { stdout: cargoMetaData } = await (0, import_execa2.default)("cargo", args, options);
|
|
83
83
|
return JSON.parse(cargoMetaData);
|
|
84
84
|
}
|
|
85
85
|
async function findCargoWorkspace(config) {
|
|
@@ -158,6 +158,7 @@ async function gatherExtraFiles(globMatcher, workPath) {
|
|
|
158
158
|
// src/lib/start-dev-server.ts
|
|
159
159
|
var import_child_process = require("child_process");
|
|
160
160
|
var import_events = require("events");
|
|
161
|
+
var import_get_port = __toESM(require("get-port"));
|
|
161
162
|
var import_build_utils5 = require("@vercel/build-utils");
|
|
162
163
|
|
|
163
164
|
// src/lib/dev-build.ts
|
|
@@ -213,7 +214,7 @@ async function buildExecutableForDev(workPath, entrypoint) {
|
|
|
213
214
|
|
|
214
215
|
// src/lib/dev-server.ts
|
|
215
216
|
var import_build_utils4 = require("@vercel/build-utils");
|
|
216
|
-
function createDevServerEnv(baseEnv, meta = {}) {
|
|
217
|
+
function createDevServerEnv(baseEnv, meta = {}, port) {
|
|
217
218
|
const devEnv = {
|
|
218
219
|
// Base environment
|
|
219
220
|
...Object.fromEntries(
|
|
@@ -225,6 +226,9 @@ function createDevServerEnv(baseEnv, meta = {}) {
|
|
|
225
226
|
// Runtime environment from meta
|
|
226
227
|
...meta.env || {}
|
|
227
228
|
};
|
|
229
|
+
if (typeof port === "number" && Number.isInteger(port)) {
|
|
230
|
+
devEnv.VERCEL_DEV_PORT = String(port);
|
|
231
|
+
}
|
|
228
232
|
Object.keys(devEnv).forEach((key) => {
|
|
229
233
|
if (devEnv[key] === void 0) {
|
|
230
234
|
delete devEnv[key];
|
|
@@ -235,49 +239,147 @@ function createDevServerEnv(baseEnv, meta = {}) {
|
|
|
235
239
|
}
|
|
236
240
|
|
|
237
241
|
// src/lib/start-dev-server.ts
|
|
242
|
+
var SHUTDOWN_TIMEOUT = 35e3;
|
|
243
|
+
var ADDR_IN_USE_RE = /address (already )?in use|AddrInUse|EADDRINUSE/i;
|
|
244
|
+
var MAX_STDERR_CAPTURE = 8192;
|
|
245
|
+
var RUNNING_DEV_SERVERS = /* @__PURE__ */ new Set();
|
|
246
|
+
var cleanupHandlersInstalled = false;
|
|
247
|
+
function installGlobalCleanupHandlers() {
|
|
248
|
+
if (cleanupHandlersInstalled)
|
|
249
|
+
return;
|
|
250
|
+
cleanupHandlersInstalled = true;
|
|
251
|
+
const onSignal = () => {
|
|
252
|
+
for (const child of RUNNING_DEV_SERVERS) {
|
|
253
|
+
try {
|
|
254
|
+
child.kill("SIGTERM");
|
|
255
|
+
} catch (err) {
|
|
256
|
+
(0, import_build_utils5.debug)(`Error sending SIGTERM to Rust dev server on signal: ${err}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
process.on("SIGINT", onSignal);
|
|
261
|
+
process.on("SIGTERM", onSignal);
|
|
262
|
+
process.on("SIGHUP", onSignal);
|
|
263
|
+
process.on("exit", () => {
|
|
264
|
+
for (const child of RUNNING_DEV_SERVERS) {
|
|
265
|
+
if (child.pid) {
|
|
266
|
+
try {
|
|
267
|
+
process.kill(child.pid, "SIGKILL");
|
|
268
|
+
} catch {
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
RUNNING_DEV_SERVERS.clear();
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function trackDevServer(child) {
|
|
276
|
+
installGlobalCleanupHandlers();
|
|
277
|
+
RUNNING_DEV_SERVERS.add(child);
|
|
278
|
+
const untrack = () => {
|
|
279
|
+
RUNNING_DEV_SERVERS.delete(child);
|
|
280
|
+
};
|
|
281
|
+
child.once("exit", untrack);
|
|
282
|
+
child.once("close", untrack);
|
|
283
|
+
}
|
|
284
|
+
var RustDevServerError = class extends Error {
|
|
285
|
+
constructor(message) {
|
|
286
|
+
super(message);
|
|
287
|
+
this.name = "RustDevServerError";
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
function terminate(child) {
|
|
291
|
+
return new Promise((resolve) => {
|
|
292
|
+
if (!child.pid || child.exitCode !== null || child.signalCode !== null) {
|
|
293
|
+
resolve();
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
let timer;
|
|
297
|
+
let settled = false;
|
|
298
|
+
const done = () => {
|
|
299
|
+
if (settled)
|
|
300
|
+
return;
|
|
301
|
+
settled = true;
|
|
302
|
+
if (timer)
|
|
303
|
+
clearTimeout(timer);
|
|
304
|
+
resolve();
|
|
305
|
+
};
|
|
306
|
+
child.once("exit", done);
|
|
307
|
+
child.once("close", done);
|
|
308
|
+
try {
|
|
309
|
+
child.kill("SIGTERM");
|
|
310
|
+
} catch (err) {
|
|
311
|
+
(0, import_build_utils5.debug)(`Error sending SIGTERM to Rust dev server: ${err}`);
|
|
312
|
+
done();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
timer = setTimeout(() => {
|
|
316
|
+
(0, import_build_utils5.debug)(
|
|
317
|
+
`Rust dev server did not exit within ${SHUTDOWN_TIMEOUT}ms, sending SIGKILL`
|
|
318
|
+
);
|
|
319
|
+
try {
|
|
320
|
+
child.kill("SIGKILL");
|
|
321
|
+
} catch (err) {
|
|
322
|
+
(0, import_build_utils5.debug)(`Error sending SIGKILL to Rust dev server: ${err}`);
|
|
323
|
+
}
|
|
324
|
+
}, SHUTDOWN_TIMEOUT);
|
|
325
|
+
timer.unref?.();
|
|
326
|
+
});
|
|
327
|
+
}
|
|
238
328
|
var startDevServer = async (opts) => {
|
|
239
|
-
const { entrypoint, workPath, meta = {} } = opts;
|
|
329
|
+
const { entrypoint, workPath, meta = {}, onStdout, onStderr } = opts;
|
|
240
330
|
try {
|
|
241
331
|
await installRustToolchain();
|
|
242
332
|
const executablePath = await buildExecutableForDev(workPath, entrypoint);
|
|
243
|
-
|
|
244
|
-
const
|
|
333
|
+
const requestedPort = typeof meta.port === "number" ? meta.port : meta.env?.VERCEL_DEV_PORT ? Number(meta.env.VERCEL_DEV_PORT) : void 0;
|
|
334
|
+
const port = typeof requestedPort === "number" && Number.isInteger(requestedPort) ? requestedPort : await (0, import_get_port.default)();
|
|
335
|
+
(0, import_build_utils5.debug)(`Starting Rust dev server: ${executablePath} (port=${port})`);
|
|
336
|
+
const devEnv = createDevServerEnv(process.env, meta, port);
|
|
245
337
|
const child = (0, import_child_process.spawn)(executablePath, [], {
|
|
246
338
|
cwd: workPath,
|
|
247
339
|
env: devEnv,
|
|
248
340
|
stdio: ["pipe", "pipe", "pipe"]
|
|
249
341
|
});
|
|
250
342
|
if (!child.pid) {
|
|
251
|
-
throw new Error("Failed to start dev server process");
|
|
343
|
+
throw new Error("Failed to start Rust dev server process");
|
|
252
344
|
}
|
|
253
|
-
(
|
|
345
|
+
trackDevServer(child);
|
|
346
|
+
(0, import_build_utils5.debug)(`Rust dev server process started with PID: ${child.pid}`);
|
|
254
347
|
let buffer = "";
|
|
255
348
|
let portEmitted = false;
|
|
349
|
+
let stderrTail = "";
|
|
256
350
|
child.stdout?.on("data", (data) => {
|
|
257
|
-
const
|
|
258
|
-
buffer +=
|
|
259
|
-
if (!portEmitted
|
|
260
|
-
const
|
|
261
|
-
if (
|
|
262
|
-
const port = parseInt(portMatch[1], 10);
|
|
263
|
-
(0, import_build_utils5.debug)(
|
|
264
|
-
`Rust dev server detected port ${port}, emitting message event`
|
|
265
|
-
);
|
|
266
|
-
child.emit("message", { port }, null);
|
|
351
|
+
const chunk = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
352
|
+
buffer += chunk.toString();
|
|
353
|
+
if (!portEmitted) {
|
|
354
|
+
const match = buffer.match(/Dev server listening:\s*(\d+)/);
|
|
355
|
+
if (match) {
|
|
267
356
|
portEmitted = true;
|
|
357
|
+
const reportedPort = parseInt(match[1], 10);
|
|
358
|
+
(0, import_build_utils5.debug)(`Rust dev server reported ready on port ${reportedPort}`);
|
|
359
|
+
child.emit("message", { port: reportedPort }, null);
|
|
360
|
+
buffer = "";
|
|
268
361
|
}
|
|
269
|
-
buffer = "";
|
|
270
362
|
}
|
|
271
|
-
|
|
363
|
+
if (onStdout) {
|
|
364
|
+
onStdout(chunk);
|
|
365
|
+
} else {
|
|
366
|
+
process.stdout.write(chunk.toString());
|
|
367
|
+
}
|
|
272
368
|
});
|
|
273
369
|
child.stderr?.on("data", (data) => {
|
|
274
|
-
|
|
370
|
+
const chunk = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
|
371
|
+
stderrTail = (stderrTail + chunk.toString()).slice(-MAX_STDERR_CAPTURE);
|
|
372
|
+
if (onStderr) {
|
|
373
|
+
onStderr(chunk);
|
|
374
|
+
} else {
|
|
375
|
+
process.stderr.write(chunk.toString());
|
|
376
|
+
}
|
|
275
377
|
});
|
|
276
378
|
child.on("error", (err) => {
|
|
277
|
-
(0, import_build_utils5.debug)(`
|
|
379
|
+
(0, import_build_utils5.debug)(`Rust dev server error: ${err}`);
|
|
278
380
|
});
|
|
279
|
-
child.on("exit", (code,
|
|
280
|
-
(0, import_build_utils5.debug)(`
|
|
381
|
+
child.on("exit", (code, signal2) => {
|
|
382
|
+
(0, import_build_utils5.debug)(`Rust dev server exited with code ${code}, signal ${signal2}`);
|
|
281
383
|
});
|
|
282
384
|
const onMessage = (0, import_events.once)(child, "message");
|
|
283
385
|
const onExit = (0, import_events.once)(child, "close");
|
|
@@ -287,40 +389,150 @@ var startDevServer = async (opts) => {
|
|
|
287
389
|
return { state: "message", value: messageData };
|
|
288
390
|
}),
|
|
289
391
|
onExit.then((args) => {
|
|
290
|
-
const [code,
|
|
291
|
-
return { state: "exit", value: [code,
|
|
392
|
+
const [code, signal2] = args;
|
|
393
|
+
return { state: "exit", value: [code, signal2] };
|
|
292
394
|
})
|
|
293
395
|
]);
|
|
294
396
|
if (result.state === "message") {
|
|
295
|
-
const
|
|
296
|
-
(0, import_build_utils5.debug)(`Rust dev server ready on port ${
|
|
397
|
+
const readyPort = typeof result.value?.port === "number" ? result.value.port : port;
|
|
398
|
+
(0, import_build_utils5.debug)(`Rust dev server ready on port ${readyPort} (pid ${child.pid})`);
|
|
297
399
|
if (!child.pid) {
|
|
298
400
|
throw new Error("Child process has no PID");
|
|
299
401
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
402
|
+
return {
|
|
403
|
+
port: readyPort,
|
|
404
|
+
pid: child.pid,
|
|
405
|
+
// Wait for exit so the port is released before `vercel dev` continues.
|
|
406
|
+
shutdown: () => terminate(child)
|
|
306
407
|
};
|
|
307
|
-
return { port, pid: child.pid, shutdown };
|
|
308
|
-
} else {
|
|
309
|
-
const [exitCode, signal] = result.value;
|
|
310
|
-
const reason = signal ? `"${signal}" signal` : `exit code ${exitCode}`;
|
|
311
|
-
throw new Error(`Rust dev server failed with ${reason}`);
|
|
312
408
|
}
|
|
409
|
+
const [exitCode, signal] = result.value;
|
|
410
|
+
const reason = signal ? `"${signal}" signal` : `exit code ${exitCode}`;
|
|
411
|
+
const stderr = stderrTail.trim();
|
|
412
|
+
if (ADDR_IN_USE_RE.test(stderr)) {
|
|
413
|
+
throw new RustDevServerError(
|
|
414
|
+
`Rust dev server failed to bind port ${port} ("address already in use"). A previous dev server instance may not have shut down yet. Please retry, or ensure no other process is using that port.`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
(0, import_build_utils5.debug)(
|
|
418
|
+
`Rust dev server exited before becoming ready (${reason}). Falling back to build-and-invoke mode.` + (stderr ? ` stderr:
|
|
419
|
+
${stderr}` : "")
|
|
420
|
+
);
|
|
421
|
+
return null;
|
|
313
422
|
} catch (error) {
|
|
314
|
-
(0, import_build_utils5.debug)(`Failed to start dev server: ${error}`);
|
|
423
|
+
(0, import_build_utils5.debug)(`Failed to start Rust dev server: ${error}`);
|
|
424
|
+
if (error instanceof RustDevServerError) {
|
|
425
|
+
throw error;
|
|
426
|
+
}
|
|
315
427
|
return null;
|
|
316
428
|
}
|
|
317
429
|
};
|
|
318
430
|
|
|
431
|
+
// src/diagnostics.ts
|
|
432
|
+
var import_build_utils6 = require("@vercel/build-utils");
|
|
433
|
+
function parseSource(source) {
|
|
434
|
+
if (!source)
|
|
435
|
+
return { include: false };
|
|
436
|
+
if (source.startsWith("path+file:"))
|
|
437
|
+
return { include: false };
|
|
438
|
+
if (source.startsWith("registry+https://github.com/rust-lang/crates.io-index")) {
|
|
439
|
+
return {
|
|
440
|
+
include: true,
|
|
441
|
+
source: "registry",
|
|
442
|
+
sourceUrl: "https://crates.io"
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
if (source.startsWith("registry+")) {
|
|
446
|
+
const url = source.slice("registry+".length).split(/[?#]/)[0];
|
|
447
|
+
return { include: true, source: "registry", sourceUrl: url };
|
|
448
|
+
}
|
|
449
|
+
if (source.startsWith("git+")) {
|
|
450
|
+
const url = source.slice("git+".length).split(/[?#]/)[0];
|
|
451
|
+
return { include: true, source: "git", sourceUrl: url };
|
|
452
|
+
}
|
|
453
|
+
return { include: true };
|
|
454
|
+
}
|
|
455
|
+
async function generateProjectManifest({
|
|
456
|
+
workPath,
|
|
457
|
+
cargoMetadata,
|
|
458
|
+
framework,
|
|
459
|
+
serviceType,
|
|
460
|
+
runtimeVersion
|
|
461
|
+
}) {
|
|
462
|
+
try {
|
|
463
|
+
const { packages, resolve } = cargoMetadata;
|
|
464
|
+
const pkgById = new Map(packages.map((p) => [p.id, p]));
|
|
465
|
+
const rootId = resolve.root;
|
|
466
|
+
const rootNode = resolve.nodes.find((n) => n.id === rootId);
|
|
467
|
+
if (!rootNode)
|
|
468
|
+
return;
|
|
469
|
+
const rootPkg = pkgById.get(rootId);
|
|
470
|
+
const directMap = /* @__PURE__ */ new Map();
|
|
471
|
+
for (const dep of rootNode.deps) {
|
|
472
|
+
const scopes = dep.dep_kinds.map(
|
|
473
|
+
(dk) => dk.kind === "dev" ? "dev" : dk.kind === "build" ? "build" : "prod"
|
|
474
|
+
);
|
|
475
|
+
const depPkg = pkgById.get(dep.pkg);
|
|
476
|
+
const req = rootPkg?.dependencies.find((d) => d.name === depPkg?.name)?.req;
|
|
477
|
+
directMap.set(dep.pkg, {
|
|
478
|
+
scopes: [...new Set(scopes)].sort(),
|
|
479
|
+
requested: req
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
const directEntries = [];
|
|
483
|
+
const transitiveEntries = [];
|
|
484
|
+
for (const node of resolve.nodes) {
|
|
485
|
+
if (node.id === rootId)
|
|
486
|
+
continue;
|
|
487
|
+
const pkg = pkgById.get(node.id);
|
|
488
|
+
if (!pkg)
|
|
489
|
+
continue;
|
|
490
|
+
const sourceInfo = parseSource(pkg.source);
|
|
491
|
+
if (!sourceInfo.include)
|
|
492
|
+
continue;
|
|
493
|
+
const directInfo = directMap.get(node.id);
|
|
494
|
+
const entry = {
|
|
495
|
+
name: pkg.name,
|
|
496
|
+
type: directInfo ? "direct" : "transitive",
|
|
497
|
+
// Transitive scope would require full graph traversal to trace which
|
|
498
|
+
// root-level scope pulled this in. 'prod' is a safe default — accurate
|
|
499
|
+
// scope propagation for transitives is left to future work.
|
|
500
|
+
scopes: directInfo ? directInfo.scopes : ["prod"],
|
|
501
|
+
resolved: pkg.version
|
|
502
|
+
};
|
|
503
|
+
if (directInfo?.requested)
|
|
504
|
+
entry.requested = directInfo.requested;
|
|
505
|
+
if (sourceInfo.source)
|
|
506
|
+
entry.source = sourceInfo.source;
|
|
507
|
+
if (sourceInfo.sourceUrl)
|
|
508
|
+
entry.sourceUrl = sourceInfo.sourceUrl;
|
|
509
|
+
if (directInfo)
|
|
510
|
+
directEntries.push(entry);
|
|
511
|
+
else
|
|
512
|
+
transitiveEntries.push(entry);
|
|
513
|
+
}
|
|
514
|
+
const manifest = {
|
|
515
|
+
version: import_build_utils6.MANIFEST_VERSION,
|
|
516
|
+
runtime: "rust",
|
|
517
|
+
...framework ? { framework } : {},
|
|
518
|
+
...serviceType ? { serviceType } : {},
|
|
519
|
+
...runtimeVersion ? { runtimeVersion } : {},
|
|
520
|
+
dependencies: [
|
|
521
|
+
...directEntries.sort((a, b) => a.name.localeCompare(b.name)),
|
|
522
|
+
...transitiveEntries.sort((a, b) => a.name.localeCompare(b.name))
|
|
523
|
+
]
|
|
524
|
+
};
|
|
525
|
+
await (0, import_build_utils6.writeProjectManifest)(manifest, workPath, "rust");
|
|
526
|
+
} catch {
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
var diagnostics = (0, import_build_utils6.createDiagnostics)("rust");
|
|
530
|
+
|
|
319
531
|
// src/index.ts
|
|
320
532
|
async function buildHandler(options) {
|
|
321
533
|
const BUILDER_DEBUG = Boolean(process.env.VERCEL_BUILDER_DEBUG ?? false);
|
|
322
534
|
const isVercelBuild = Boolean(process.env.VERCEL_BUILD_IMAGE ?? false);
|
|
323
|
-
const { files, entrypoint, workPath, config, meta } = options;
|
|
535
|
+
const { files, entrypoint, workPath, config, meta, service } = options;
|
|
324
536
|
const crossCompilationEnabled = !isVercelBuild && !meta?.isDev;
|
|
325
537
|
if (crossCompilationEnabled && process.platform === "win32") {
|
|
326
538
|
throw new Error(
|
|
@@ -328,8 +540,8 @@ async function buildHandler(options) {
|
|
|
328
540
|
);
|
|
329
541
|
}
|
|
330
542
|
await installRustToolchain();
|
|
331
|
-
(0,
|
|
332
|
-
const downloadedFiles = await (0,
|
|
543
|
+
(0, import_build_utils7.debug)("Creating file system");
|
|
544
|
+
const downloadedFiles = await (0, import_build_utils7.download)(files, workPath, meta);
|
|
333
545
|
const entryPath = downloadedFiles[entrypoint].fsPath;
|
|
334
546
|
const HOME = process.platform === "win32" ? assertEnv("USERPROFILE") : assertEnv("HOME");
|
|
335
547
|
const PATH = assertEnv("PATH");
|
|
@@ -345,25 +557,23 @@ async function buildHandler(options) {
|
|
|
345
557
|
const cargoBuildConfiguration = await findCargoBuildConfiguration(cargoWorkspace);
|
|
346
558
|
await runUserScripts(workPath);
|
|
347
559
|
const extraFiles = await gatherExtraFiles(config.includeFiles, workPath);
|
|
348
|
-
const lambdaOptions = await (0,
|
|
560
|
+
const lambdaOptions = await (0, import_build_utils7.getLambdaOptionsFromFunction)({
|
|
349
561
|
sourceFile: entrypoint,
|
|
350
562
|
config
|
|
351
563
|
});
|
|
352
564
|
const architecture = lambdaOptions?.architecture || "x86_64";
|
|
353
565
|
const buildVariant = meta?.isDev ? "debug" : "release";
|
|
354
566
|
const buildTarget = cargoBuildConfiguration?.build.target ?? "";
|
|
567
|
+
const targetTriple = architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu";
|
|
355
568
|
try {
|
|
356
|
-
const args = crossCompilationEnabled ? [
|
|
357
|
-
"
|
|
358
|
-
"--
|
|
359
|
-
|
|
360
|
-
"--bin",
|
|
361
|
-
binaryName
|
|
362
|
-
].concat(BUILDER_DEBUG ? ["--verbose"] : ["--quiet"], ["--release"]) : ["build", "--bin", binaryName].concat(
|
|
569
|
+
const args = crossCompilationEnabled ? ["zigbuild", "--target", targetTriple, "--bin", binaryName].concat(
|
|
570
|
+
BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
|
|
571
|
+
["--release"]
|
|
572
|
+
) : ["build", "--bin", binaryName].concat(
|
|
363
573
|
BUILDER_DEBUG ? ["--verbose"] : ["--quiet"],
|
|
364
574
|
meta?.isDev ? [] : ["--release"]
|
|
365
575
|
);
|
|
366
|
-
(0,
|
|
576
|
+
(0, import_build_utils7.debug)(
|
|
367
577
|
`Running \`cargo build\` for \`${binaryName}\` (\`${architecture}\`)`
|
|
368
578
|
);
|
|
369
579
|
await (0, import_execa4.default)("cargo", args, {
|
|
@@ -371,21 +581,19 @@ async function buildHandler(options) {
|
|
|
371
581
|
env: rustEnv
|
|
372
582
|
});
|
|
373
583
|
} catch (err) {
|
|
374
|
-
(0,
|
|
584
|
+
(0, import_build_utils7.debug)(`Running \`cargo build\` for \`${binaryName}\` failed`);
|
|
375
585
|
throw err;
|
|
376
586
|
}
|
|
377
|
-
(0,
|
|
587
|
+
(0, import_build_utils7.debug)(
|
|
378
588
|
`Building \`${binaryName}\` for \`${process.platform}\` (\`${architecture}\`) completed`
|
|
379
589
|
);
|
|
380
|
-
|
|
381
|
-
cwd: workPath,
|
|
382
|
-
|
|
383
|
-
|
|
590
|
+
const cargoMetadata = await getCargoMetadata(
|
|
591
|
+
{ cwd: workPath, env: rustEnv },
|
|
592
|
+
targetTriple
|
|
593
|
+
);
|
|
594
|
+
let { target_directory: targetDirectory } = cargoMetadata;
|
|
384
595
|
if (crossCompilationEnabled) {
|
|
385
|
-
targetDirectory = import_node_path4.default.join(
|
|
386
|
-
targetDirectory,
|
|
387
|
-
architecture === "x86_64" ? "x86_64-unknown-linux-gnu" : "aarch64-unknown-linux-gnu"
|
|
388
|
-
);
|
|
596
|
+
targetDirectory = import_node_path4.default.join(targetDirectory, targetTriple);
|
|
389
597
|
}
|
|
390
598
|
targetDirectory = import_node_path4.default.join(targetDirectory, buildTarget);
|
|
391
599
|
const bin = import_node_path4.default.join(
|
|
@@ -394,8 +602,8 @@ async function buildHandler(options) {
|
|
|
394
602
|
getExecutableName(binaryName)
|
|
395
603
|
);
|
|
396
604
|
const handler = getExecutableName("executable");
|
|
397
|
-
const executableFile = new
|
|
398
|
-
const lambda = new
|
|
605
|
+
const executableFile = new import_build_utils7.FileFsRef({ mode: 493, fsPath: bin });
|
|
606
|
+
const lambda = new import_build_utils7.Lambda({
|
|
399
607
|
...lambdaOptions,
|
|
400
608
|
files: {
|
|
401
609
|
...extraFiles,
|
|
@@ -408,7 +616,31 @@ async function buildHandler(options) {
|
|
|
408
616
|
runtimeLanguage: "rust"
|
|
409
617
|
});
|
|
410
618
|
lambda.zipBuffer = await lambda.createZip();
|
|
411
|
-
|
|
619
|
+
let resolvedRustVersion;
|
|
620
|
+
try {
|
|
621
|
+
const { stdout: rustcOut } = await (0, import_execa4.default)("rustc", ["--version"], {
|
|
622
|
+
env: rustEnv,
|
|
623
|
+
cwd: workPath
|
|
624
|
+
});
|
|
625
|
+
resolvedRustVersion = rustcOut.split(" ")[1];
|
|
626
|
+
} catch {
|
|
627
|
+
(0, import_build_utils7.debug)("Failed to determine rustc version");
|
|
628
|
+
}
|
|
629
|
+
const rootPkg = cargoMetadata.packages.find(
|
|
630
|
+
(p) => p.id === cargoMetadata.resolve.root
|
|
631
|
+
);
|
|
632
|
+
const requestedRustVersion = rootPkg?.rust_version || void 0;
|
|
633
|
+
await generateProjectManifest({
|
|
634
|
+
workPath,
|
|
635
|
+
cargoMetadata,
|
|
636
|
+
framework: config?.framework ?? void 0,
|
|
637
|
+
serviceType: service ? (0, import_build_utils7.getReportedServiceType)(service) : void 0,
|
|
638
|
+
runtimeVersion: resolvedRustVersion ? {
|
|
639
|
+
...requestedRustVersion ? { requested: requestedRustVersion } : {},
|
|
640
|
+
resolved: resolvedRustVersion
|
|
641
|
+
} : void 0
|
|
642
|
+
});
|
|
643
|
+
(0, import_build_utils7.debug)(`generating function for \`${entrypoint}\``);
|
|
412
644
|
return {
|
|
413
645
|
output: lambda
|
|
414
646
|
};
|
|
@@ -417,8 +649,8 @@ var runtime = {
|
|
|
417
649
|
version: 3,
|
|
418
650
|
build: buildHandler,
|
|
419
651
|
prepareCache: async ({ workPath }) => {
|
|
420
|
-
(0,
|
|
421
|
-
const cacheFiles = await (0,
|
|
652
|
+
(0, import_build_utils7.debug)(`Caching \`${workPath}\``);
|
|
653
|
+
const cacheFiles = await (0, import_build_utils7.glob)("target/**", workPath);
|
|
422
654
|
for (const f of Object.keys(cacheFiles)) {
|
|
423
655
|
const accept = /(?:^|\/)target\/release\/\.fingerprint\//.test(f) || /(?:^|\/)target\/release\/build\//.test(f) || /(?:^|\/)target\/release\/deps\//.test(f) || /(?:^|\/)target\/debug\/\.fingerprint\//.test(f) || /(?:^|\/)target\/debug\/build\//.test(f) || /(?:^|\/)target\/debug\/deps\//.test(f);
|
|
424
656
|
if (!accept) {
|
|
@@ -429,10 +661,10 @@ var runtime = {
|
|
|
429
661
|
},
|
|
430
662
|
startDevServer,
|
|
431
663
|
shouldServe: async (options) => {
|
|
432
|
-
(0,
|
|
664
|
+
(0, import_build_utils7.debug)(`Requested ${options.requestPath} for ${options.entrypoint}`);
|
|
433
665
|
const entrypointWithoutExt = options.entrypoint.replace(/\.rs$/, "");
|
|
434
666
|
const matches = options.requestPath === options.entrypoint || options.requestPath === entrypointWithoutExt;
|
|
435
|
-
(0,
|
|
667
|
+
(0, import_build_utils7.debug)(
|
|
436
668
|
`shouldServe: ${matches} (entrypointWithoutExt: ${entrypointWithoutExt})`
|
|
437
669
|
);
|
|
438
670
|
return Promise.resolve(matches);
|
|
@@ -442,6 +674,7 @@ var { version, build, prepareCache, startDevServer: startDevServer2, shouldServe
|
|
|
442
674
|
// Annotate the CommonJS export names for ESM import in node:
|
|
443
675
|
0 && (module.exports = {
|
|
444
676
|
build,
|
|
677
|
+
diagnostics,
|
|
445
678
|
prepareCache,
|
|
446
679
|
shouldServe,
|
|
447
680
|
startDevServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/rust",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/index",
|
|
6
6
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/rust",
|
|
@@ -14,27 +14,28 @@
|
|
|
14
14
|
],
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"smol-toml": "1.5.2",
|
|
17
|
-
"execa": "5"
|
|
17
|
+
"execa": "5",
|
|
18
|
+
"get-port": "5.1.1"
|
|
18
19
|
},
|
|
19
20
|
"devDependencies": {
|
|
20
|
-
"@types/jest": "^29.4.0",
|
|
21
21
|
"@types/ms": "^0.7.31",
|
|
22
22
|
"@types/node": "20.11.0",
|
|
23
23
|
"@vercel/style-guide": "^4.0.2",
|
|
24
24
|
"eslint": "^8.35.0",
|
|
25
25
|
"husky": "^8.0.3",
|
|
26
|
-
"jest": "^29.5.0",
|
|
27
26
|
"ms": "^2.1.3",
|
|
28
27
|
"prettier": "^2.8.4",
|
|
29
28
|
"rimraf": "^4.1.1",
|
|
30
|
-
"
|
|
31
|
-
"@vercel/
|
|
32
|
-
"@vercel/
|
|
29
|
+
"vitest": "2.0.3",
|
|
30
|
+
"@vercel/build-utils": "13.32.2",
|
|
31
|
+
"@vercel/routing-utils": "6.4.0"
|
|
33
32
|
},
|
|
34
33
|
"scripts": {
|
|
35
34
|
"build": "node ../../utils/build-builder.mjs",
|
|
36
|
-
"test": "
|
|
35
|
+
"test": "vitest run --config ../../vitest.config.mts",
|
|
37
36
|
"test-e2e": "pnpm test",
|
|
38
|
-
"type-check": "tsc --noEmit"
|
|
37
|
+
"type-check": "tsc --noEmit",
|
|
38
|
+
"vitest-run": "vitest -c ../../vitest.config.mts",
|
|
39
|
+
"vitest-e2e": "glob --absolute 'test/**/*.test.js' 'test/**/*.test.ts' 'tests/**/*.test.js' 'tests/**/*.test.ts'"
|
|
39
40
|
}
|
|
40
41
|
}
|