mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-06 12:57:46 +00:00
[cli] Normalize "src" property in vc build (#7943)
This matches the production behavior.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import dotenv from 'dotenv';
|
||||
import { join, relative } from 'path';
|
||||
import { join, normalize, relative } from 'path';
|
||||
import {
|
||||
detectBuilders,
|
||||
normalizePath,
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
BuildResultV2,
|
||||
BuildResultV2Typical,
|
||||
BuildResultV3,
|
||||
NowBuildError,
|
||||
} from '@vercel/build-utils';
|
||||
import minimatch from 'minimatch';
|
||||
import {
|
||||
@@ -475,17 +476,33 @@ export default async function main(client: Client): Promise<number> {
|
||||
}
|
||||
|
||||
function expandBuild(files: string[], build: Builder): Builder[] {
|
||||
if (!build.src) return [];
|
||||
if (!build.use) {
|
||||
throw new NowBuildError({
|
||||
code: `invalid_build_specification`,
|
||||
message: 'Field `use` is missing in build specification',
|
||||
link: 'https://vercel.com/docs/configuration#project/builds',
|
||||
action: 'View Documentation',
|
||||
});
|
||||
}
|
||||
|
||||
let pattern = build.src;
|
||||
if (pattern[0] === '/') {
|
||||
let src = normalize(build.src || '**');
|
||||
if (src === '.' || src === './') {
|
||||
throw new NowBuildError({
|
||||
code: `invalid_build_specification`,
|
||||
message: 'A build `src` path resolves to an empty string',
|
||||
link: 'https://vercel.com/docs/configuration#project/builds',
|
||||
action: 'View Documentation',
|
||||
});
|
||||
}
|
||||
|
||||
if (src[0] === '/') {
|
||||
// Remove a leading slash so that the globbing is relative
|
||||
// to `cwd` instead of the root of the filesystem.
|
||||
pattern = pattern.substring(1);
|
||||
src = src.substring(1);
|
||||
}
|
||||
|
||||
const matches = files.filter(
|
||||
name => name === pattern || minimatch(name, pattern, { dot: true })
|
||||
name => name === src || minimatch(name, src, { dot: true })
|
||||
);
|
||||
|
||||
return matches.map(m => {
|
||||
|
||||
7
packages/cli/test/fixtures/unit/commands/build/normalize-src/.vercel/project.json
vendored
Normal file
7
packages/cli/test/fixtures/unit/commands/build/normalize-src/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"orgId": ".",
|
||||
"projectId": ".",
|
||||
"settings": {
|
||||
"framework": null
|
||||
}
|
||||
}
|
||||
1
packages/cli/test/fixtures/unit/commands/build/normalize-src/server.js
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/normalize-src/server.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = (req, res) => res.end('Vercel');
|
||||
15
packages/cli/test/fixtures/unit/commands/build/normalize-src/vercel.json
vendored
Normal file
15
packages/cli/test/fixtures/unit/commands/build/normalize-src/vercel.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "./server.js",
|
||||
"use": "@vercel/node"
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"src": "/(.*)",
|
||||
"dest": "/server.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -111,6 +111,56 @@ describe('build', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('should normalize "src" path in `vercel.json`', async () => {
|
||||
const cwd = fixture('normalize-src');
|
||||
const output = join(cwd, '.vercel/output');
|
||||
try {
|
||||
process.chdir(cwd);
|
||||
const exitCode = await build(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
|
||||
// `builds.json` says that "@vercel/node" was run
|
||||
const builds = await fs.readJSON(join(output, 'builds.json'));
|
||||
expect(builds).toMatchObject({
|
||||
target: 'preview',
|
||||
builds: [
|
||||
{
|
||||
require: '@vercel/node',
|
||||
apiVersion: 3,
|
||||
use: '@vercel/node',
|
||||
src: 'server.js',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// `config.json` includes "route" from `vercel.json`
|
||||
const config = await fs.readJSON(join(output, 'config.json'));
|
||||
expect(config).toMatchObject({
|
||||
version: 3,
|
||||
routes: [
|
||||
{
|
||||
src: '^/(.*)$',
|
||||
dest: '/server.js',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// "static" directory is empty
|
||||
const hasStaticFiles = await fs.pathExists(join(output, 'static'));
|
||||
expect(
|
||||
hasStaticFiles,
|
||||
'Expected ".vercel/output/static" to not exist'
|
||||
).toEqual(false);
|
||||
|
||||
// "functions" directory has output Function
|
||||
const functions = await fs.readdir(join(output, 'functions'));
|
||||
expect(functions.sort()).toEqual(['server.js.func']);
|
||||
} finally {
|
||||
process.chdir(originalCwd);
|
||||
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||
}
|
||||
});
|
||||
|
||||
it('should build with 3rd party Builder', async () => {
|
||||
const cwd = fixture('third-party-builder');
|
||||
const output = join(cwd, '.vercel/output');
|
||||
|
||||
Reference in New Issue
Block a user