Skip to content

Commit 835027a

Browse files
authored
fix: support build targets with different name than its path filename (#82)
* test * fix: resolve correct binary name by parsing build target spec * fix: use correct path when looking for build target * test: fix compile error in fixture and add entry to probes
1 parent 89e5d68 commit 835027a

File tree

18 files changed

+1079
-10
lines changed

18 files changed

+1079
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ exclude = [
1313
"test/fixtures/02-with-utility",
1414
"test/fixtures/03-with-function",
1515
"test/fixtures/04-with-parameter",
16-
"test/fixtures/05-preconfigured-binary"
16+
"test/fixtures/05-with-similar-entrypaths"
1717
]

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
},
2222
"prettier": "@vercel/style-guide/prettier",
2323
"dependencies": {
24+
"@iarna/toml": "^2.2.5",
2425
"execa": "5",
2526
"typescript": "^4.9.4"
2627
},

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
import execa from 'execa';
1313
import { installRustToolchain } from './lib/rust-toolchain';
1414
import type { Runtime } from './lib/runtime';
15-
import { getCargoMetadata } from './lib/cargo';
15+
import { getCargoMetadata, findBinaryName, findCargoWorkspace } from './lib/cargo';
1616

1717
type RustEnv = Record<'RUSTFLAGS' | 'PATH', string>;
1818

@@ -75,12 +75,11 @@ async function buildHandler(options: BuildOptions): Promise<BuildResultV3> {
7575
RUSTFLAGS: [process.env.RUSTFLAGS].filter(Boolean).join(' '),
7676
};
7777

78-
// The binary name is the name of the entrypoint file
79-
// We assume each binary is specified correctly with `[[bin]]` in `Cargo.toml`
80-
const binaryName = path
81-
.basename(entryPath, '.rs')
82-
.replace('[', '_')
83-
.replace(']', '_');
78+
const cargoWorkspace = await findCargoWorkspace({
79+
env: rustEnv,
80+
cwd: path.dirname(entryPath),
81+
});
82+
const binaryName = findBinaryName(cargoWorkspace, entryPath);
8483

8584
await runUserScripts(workPath);
8685

src/lib/cargo.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import fs from 'node:fs';
2+
import path from 'node:path';
3+
import toml from '@iarna/toml';
14
import execa from 'execa';
25

36
export interface CargoMetadataRoot {
@@ -128,3 +131,54 @@ export async function getCargoMetadata(
128131

129132
return JSON.parse(cargoMetaData) as CargoMetadataRoot;
130133
}
134+
135+
interface CargoConfig {
136+
env: Record<string, any>;
137+
cwd: string;
138+
}
139+
140+
interface CargoBuildTarget {
141+
name?: string;
142+
path?: string;
143+
}
144+
145+
interface CargoToml {
146+
bin?: CargoBuildTarget[];
147+
}
148+
149+
interface CargoWorkspace {
150+
toml: CargoToml;
151+
root: string;
152+
}
153+
154+
export async function findCargoWorkspace(
155+
config: CargoConfig,
156+
): Promise<CargoWorkspace> {
157+
const { stdout: projectDescriptionStr } = await execa(
158+
'cargo',
159+
['locate-project'],
160+
config,
161+
);
162+
const projectDescription = JSON.parse(projectDescriptionStr) as {
163+
root: string;
164+
};
165+
return {
166+
toml: await toml.parse.stream(fs.createReadStream(projectDescription.root)),
167+
root: projectDescription.root,
168+
};
169+
}
170+
171+
export function findBinaryName(
172+
workspace: CargoWorkspace,
173+
entryPath: string,
174+
): string {
175+
const { bin } = workspace.toml;
176+
if (bin) {
177+
const relativePath = path.relative(path.dirname(workspace.root), entryPath);
178+
const entry = bin.find((binEntry) => binEntry.path === relativePath);
179+
if (entry?.name) {
180+
return entry.name;
181+
}
182+
}
183+
return path.basename(entryPath, '.rs').replace('[', '_').replace(']', '_');
184+
}

test/fixtures.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ interface Config {
1717
}
1818

1919
interface Probe {
20-
status: number;
2120
path: string;
22-
mustContain: string;
21+
status?: number;
22+
mustContain?: string;
2323
}
2424

2525
interface ProbesConf {
@@ -118,4 +118,7 @@ describe('vercel-rust', () => {
118118
it('deploy 04-with-parameter', async () => {
119119
await expect(testFixture('04-with-parameter')).resolves.toBe('ok');
120120
});
121+
it('deploy 05-with-similar-entrypaths', async () => {
122+
await expect(testFixture('05-with-similar-entrypaths')).resolves.toBe('ok');
123+
});
121124
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vercel
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vercel
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vercel
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vercel

0 commit comments

Comments
 (0)