Skip to content

Commit f09d7e5

Browse files
feat: allow ignore pattern for copy task
1 parent b571354 commit f09d7e5

23 files changed

+915
-33
lines changed

src/compiler/output-targets/copy/assets-copy-tasks.ts

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const getComponentAssetsCopyTasks = (
2727
src: assetsMeta.absolutePath,
2828
dest: join(dest, assetsMeta.cmpRelativePath),
2929
warn: false,
30+
ignore: undefined,
3031
keepDirStructure: false,
3132
});
3233
});
@@ -37,6 +38,7 @@ export const getComponentAssetsCopyTasks = (
3738
src: assetsMeta.absolutePath,
3839
dest: collectionDirDestination,
3940
warn: false,
41+
ignore: undefined,
4042
keepDirStructure: false,
4143
});
4244
});

src/compiler/output-targets/copy/output-copy.ts

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ import type * as d from '../../../declarations';
55
import { canSkipAssetsCopy, getComponentAssetsCopyTasks } from './assets-copy-tasks';
66
import { getDestAbsPath, getSrcAbsPath } from './local-copy-tasks';
77

8+
const DEFAULT_IGNORE = [
9+
'**/__mocks__/**', '**/__fixtures__/**', '**/dist/**', '**/.{idea,git,cache,output,temp}/**',
10+
'**/.ds_store', '**/.gitignore', '**/desktop.ini', '**/thumbs.db'
11+
]
12+
813
export const outputCopy = async (config: d.ValidatedConfig, compilerCtx: d.CompilerCtx, buildCtx: d.BuildCtx) => {
914
const outputTargets = config.outputTargets.filter(isOutputTargetCopy);
1015
if (outputTargets.length === 0) {
@@ -83,6 +88,7 @@ const transformToAbs = (copyTask: d.CopyTask, dest: string): Required<d.CopyTask
8388
return {
8489
src: copyTask.src,
8590
dest: getDestAbsPath(copyTask.src, dest, copyTask.dest),
91+
ignore: copyTask.ignore || DEFAULT_IGNORE,
8692
keepDirStructure:
8793
typeof copyTask.keepDirStructure === 'boolean' ? copyTask.keepDirStructure : copyTask.dest == null,
8894
warn: copyTask.warn !== false,

src/declarations/stencil-public-compiler.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1646,6 +1646,11 @@ export interface CopyTask {
16461646
* the output target for which this copy operation is configured.
16471647
*/
16481648
dest?: string;
1649+
/**
1650+
* An optional array of glob patterns to exclude from the copy operation.
1651+
* @default ['**\/__mocks__/**', '**\/__fixtures__/**', '**\/dist/**', '**\/.{idea,git,cache,output,temp}/**', '.ds_store', '.gitignore', 'desktop.ini', 'thumbs.db']
1652+
*/
1653+
ignore?: string[];
16491654
/**
16501655
* Whether or not Stencil should issue warnings if it cannot find the
16511656
* specified source files or directories. Defaults to `false`.

src/sys/node/node-copy-tasks.ts

+12-33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { buildError, catchError, flatOne, isGlob, normalizePath } from '@utils';
2-
import { glob } from 'glob';
2+
import { glob, type GlobOptions } from 'glob';
33
import path from 'path';
44

55
import type * as d from '../../declarations';
@@ -13,7 +13,7 @@ export async function nodeCopyTasks(copyTasks: Required<d.CopyTask>[], srcDir: s
1313
};
1414

1515
try {
16-
copyTasks = flatOne(await Promise.all(copyTasks.map((task) => processGlobs(task, srcDir))));
16+
copyTasks = flatOne(await Promise.all(copyTasks.map((task) => processGlobTask(task, srcDir))));
1717

1818
const allCopyTasks: d.CopyTask[] = [];
1919

@@ -44,30 +44,15 @@ export async function nodeCopyTasks(copyTasks: Required<d.CopyTask>[], srcDir: s
4444
return results;
4545
}
4646

47-
async function processGlobs(copyTask: Required<d.CopyTask>, srcDir: string): Promise<Required<d.CopyTask>[]> {
48-
return isGlob(copyTask.src)
49-
? await processGlobTask(copyTask, srcDir)
50-
: [
51-
{
52-
src: getSrcAbsPath(srcDir, copyTask.src),
53-
dest: copyTask.keepDirStructure ? path.join(copyTask.dest, copyTask.src) : copyTask.dest,
54-
warn: copyTask.warn,
55-
keepDirStructure: copyTask.keepDirStructure,
56-
},
57-
];
58-
}
59-
60-
function getSrcAbsPath(srcDir: string, src: string) {
61-
if (path.isAbsolute(src)) {
62-
return src;
63-
}
64-
return path.join(srcDir, src);
65-
}
66-
6747
async function processGlobTask(copyTask: Required<d.CopyTask>, srcDir: string): Promise<Required<d.CopyTask>[]> {
68-
const files = await asyncGlob(copyTask.src, {
48+
const pattern = isGlob(copyTask.src)
49+
? copyTask.src
50+
: path.join(copyTask.src, '**');
51+
52+
const files = await asyncGlob(pattern, {
6953
cwd: srcDir,
7054
nodir: true,
55+
ignore: copyTask.ignore,
7156
});
7257
return files.map((globRelPath) => createGlobCopyTask(copyTask, srcDir, globRelPath));
7358
}
@@ -77,6 +62,7 @@ function createGlobCopyTask(copyTask: Required<d.CopyTask>, srcDir: string, glob
7762
return {
7863
src: path.join(srcDir, globRelPath),
7964
dest,
65+
ignore: copyTask.ignore,
8066
warn: copyTask.warn,
8167
keepDirStructure: copyTask.keepDirStructure,
8268
};
@@ -96,7 +82,7 @@ async function processCopyTask(results: d.CopyResults, allCopyTasks: d.CopyTask[
9682
}
9783

9884
await processCopyTaskDirectory(results, allCopyTasks, copyTask);
99-
} else if (!shouldIgnore(copyTask.src)) {
85+
} else {
10086
// this is a file we should copy
10187
if (!results.filePaths.includes(copyTask.dest)) {
10288
results.filePaths.push(copyTask.dest);
@@ -169,13 +155,6 @@ function addMkDir(mkDirs: string[], destDir: string) {
169155

170156
const ROOT_DIR = normalizePath(path.resolve('/'));
171157

172-
function shouldIgnore(filePath: string) {
173-
filePath = filePath.trim().toLowerCase();
174-
return IGNORE.some((ignoreFile) => filePath.endsWith(ignoreFile));
175-
}
176-
177-
const IGNORE = ['.ds_store', '.gitignore', 'desktop.ini', 'thumbs.db'];
178-
179-
export function asyncGlob(pattern: string, opts: any) {
180-
return glob(pattern, opts);
158+
export async function asyncGlob(pattern: string, opts: GlobOptions): Promise<string[]> {
159+
return glob(pattern, { ...opts, withFileTypes: false });
181160
}

test/copy-task/README.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
Copy Task Tests
2+
===============
3+
4+
This directory aims to test and validate the behavior for Stencils [Copy Task for Output Targets](https://stenciljs.com/docs/copy-tasks#copy-tasks-for-output-targets). It has a copy task defined in `test/copy-task/stencil.config.ts` and builds this starter projects to then validate if the right files where copies.
5+
6+
## Given
7+
8+
We have a copy task defined as part of an output target, e.g.
9+
10+
```ts
11+
{
12+
type: 'dist-custom-elements',
13+
copy: [{
14+
src: './utils',
15+
dest: './dist/utilsExtra',
16+
}]
17+
}
18+
```
19+
20+
I expect that a `utilsExtra` directory is created that does __not__ copy the following entries:
21+
22+
- files in `__fixtures__` and `__mocks__` directories
23+
- as well as files named `desktop.ini`
24+
25+
Furthermore I expect that no JS files are copied over within the collection directory.

0 commit comments

Comments
 (0)