Files
vercel/packages/client/tests/unit.utils.test.ts
Nathan Rajlich 9a27ccbe6d [cli][client] Handle --repo linked in vc deploy --prebuilt (#11309)
`vc deploy --prebuilt` has not properly worked for projects linked with
`vc link --repo` ever since
https://github.com/vercel/vercel/issues/11077.

To fix, don't mutate `cwd` to be the project subdir (so that `cwd` is
always the monorepo root), and instead pass in a new property to
`@vercel/client` that represents the `.vercel/output` file path. A lot
of the code is just passing this new variable through the multiple
layers of indirection in CLI before it finally reaches `@vercel/client.

Fixes https://github.com/vercel/vercel/issues/11097.
2024-03-29 17:23:24 -07:00

208 lines
6.3 KiB
TypeScript

import { join, resolve } from 'path';
import fs from 'fs-extra';
import { buildFileTree } from '../src/utils';
const fixture = (name: string) => resolve(__dirname, 'fixtures', name);
const noop = () => {};
const normalizeWindowsPaths = (files: string[]) => {
if (process.platform === 'win32') {
return files.map(f => f.replace(/\\/g, '/'));
}
return files;
};
const toAbsolutePaths = (cwd: string, files: string[]) =>
files.map(p => join(cwd, p));
describe('buildFileTree()', () => {
it('should exclude files using `.nowignore` blocklist', async () => {
const cwd = fixture('nowignore');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{ isDirectory: true },
noop
);
const expectedFileList = toAbsolutePaths(cwd, [
'.nowignore',
'folder',
'index.txt',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = [
'ignore.txt',
'folder/ignore.txt',
'node_modules',
];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
it('should include symlinked files and directories', async () => {
const cwd = fixture('symlinks');
// Also add an empty directory to make sure it's included
await fs.mkdirp(join(cwd, 'empty'));
const { fileList } = await buildFileTree(cwd, { isDirectory: true }, noop);
const expectedFileList = toAbsolutePaths(cwd, [
'empty',
'folder-link',
'folder/text.txt',
'index.txt',
'index-link.txt',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const [folderLinkPath, indexLinkPath] = await Promise.all([
fs.lstat(join(cwd, 'folder-link')),
fs.lstat(join(cwd, 'index-link.txt')),
]);
expect(folderLinkPath.isSymbolicLink());
expect(folderLinkPath.isDirectory());
expect(indexLinkPath.isSymbolicLink());
});
it('should include the node_modules using `.vercelignore` allowlist', async () => {
const cwd = fixture('vercelignore-allow-nodemodules');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{ isDirectory: true },
noop
);
const expected = toAbsolutePaths(cwd, [
'node_modules/one.txt',
'sub/node_modules/two.txt',
'sub/include.txt',
'.vercelignore',
'hello.txt',
]);
expect(normalizeWindowsPaths(expected).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = ['.env.local', 'exclude.txt'];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
it('should find root files but ignore `.vercel/output` files when prebuilt=false', async () => {
const cwd = fixture('file-system-api');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{ isDirectory: true, prebuilt: false },
noop
);
const expectedFileList = toAbsolutePaths(cwd, ['foo.txt', 'sub/bar.txt']);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = ['.gitignore', '.vercel'];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
it('should find `.vercel/output` files but ignore other files when prebuilt=true', async () => {
const cwd = fixture('file-system-api');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{
isDirectory: true,
prebuilt: true,
vercelOutputDir: join(cwd, '.vercel/output'),
},
noop
);
const expectedFileList = toAbsolutePaths(cwd, [
'.vercel/output/functions/api/another.func/.vc-config.json',
'.vercel/output/functions/api/example.func/.vc-config.json',
'.vercel/output/static/baz.txt',
'.vercel/output/static/sub/qux.txt',
'node_modules/another/index.js',
'node_modules/example/index.js',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = ['.gitignore', 'foo.txt', 'sub'];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
it('monorepo - should find root files but ignore `.vercel/output` files when prebuilt=false', async () => {
const cwd = fixture('monorepo-boa');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{ isDirectory: true, prebuilt: false },
noop
);
const expectedFileList = toAbsolutePaths(cwd, [
'foo.txt',
'sub/bar.txt',
'apps/blog/foo.txt',
'apps/blog/sub/bar.txt',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = ['apps/blog/.gitignore', 'apps/blog/.vercel'];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
it('monorepo - should find `.vercel/output` files but ignore other files when prebuilt=true', async () => {
const cwd = fixture('monorepo-boa');
const { fileList, ignoreList } = await buildFileTree(
cwd,
{
isDirectory: true,
prebuilt: true,
vercelOutputDir: join(cwd, 'apps/blog/.vercel/output'),
},
noop
);
const expectedFileList = toAbsolutePaths(cwd, [
'apps/blog/.vercel/output/functions/api/another.func/.vc-config.json',
'apps/blog/.vercel/output/functions/api/example.func/.vc-config.json',
'apps/blog/.vercel/output/static/baz.txt',
'apps/blog/.vercel/output/static/sub/qux.txt',
'node_modules/another/index.js',
'node_modules/example/index.js',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort()
);
const expectedIgnoreList = [
'apps/blog/.gitignore',
'apps/blog/foo.txt',
'apps/blog/sub',
'foo.txt',
'sub',
];
expect(normalizeWindowsPaths(expectedIgnoreList).sort()).toEqual(
normalizeWindowsPaths(ignoreList).sort()
);
});
});