Skip to content

Commit

Permalink
feat: added ability to use array in src property
Browse files Browse the repository at this point in the history
  • Loading branch information
kshutkin committed Jun 18, 2023
1 parent 018bbb4 commit bfd87eb
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 20 deletions.
6 changes: 6 additions & 0 deletions .changeset/quiet-seahorses-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rollup-extras/plugin-copy": minor
---

improvement: read / copy files in parallel
added ability to use array in `src` property
8 changes: 6 additions & 2 deletions plugin-copy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ copy(['assets/*'])
copy({ src: 'assets/*' })
```

```javascript
copy({ src: ['assets/*'] })
```

```javascript
copy([{ src: 'assets/*' }])
```
Expand Down Expand Up @@ -105,7 +109,7 @@ copy({ src: 'assets/*', flatten: true })

// or

copy({ targets: ['assets/*'], flattern: true })
copy({ targets: ['assets/*'], flatten: true })
```

To add hashes to file names use `exactFileNames` = `false`, tweak `assetFileNames` option in rollup config if needed. Files with the same content will be deduplicated by `rollup` in this mode.
Expand Down Expand Up @@ -156,7 +160,7 @@ copy({ targets: [{ src: 'assets/*', dest: 'fonts', exclude: '*.json' }] })

```typescript
type SingleTargetDesc = {
src: string,
src: string | string[],
exclude?: string | string[],
dest?: string;
};
Expand Down
34 changes: 19 additions & 15 deletions plugin-copy/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@ export default function(options: CopyPluginOptions) {
name: pluginName,

async [hookName]() {
const results = await Promise.all((targets as SingleTargetDesc[]).map(target => glob(target.src, { ignore: target.exclude })
.then(result => ({
src: result,
dest: target.dest ? target.dest : '',
parent: globParent(target.src)
}))));
const results = await Promise.all((targets as SingleTargetDesc[])
.flatMap(target => Array.isArray(target.src) ? target.src.map(itemSrc => ({
...target,
src: itemSrc
})) : target)
.map(target => glob(target.src, { ignore: target.exclude })
.then(result => ({
src: result,
dest: target.dest ? target.dest : '',
parent: globParent(target.src as string)
}))));

for (const result of results) {
for (const file of result.src) {
Expand Down Expand Up @@ -90,12 +95,12 @@ export default function(options: CopyPluginOptions) {
(result: number | string[]) => `copied ${typeof result == 'number' ? result + ' files' : result.join(', ')}`
);
logger.start('coping files', verbose ? LogLevel.info : LogLevel.verbose);
for (const [fileName, fileDesc] of files) {
await Promise.all([...files].map(async ([fileName, fileDesc]) => {
let source: Buffer | undefined;
try {
const fileStat = await fs.stat(fileName);
if (!fileStat.isFile() && !fileStat.isSymbolicLink()) {
continue;
return;
}
const timestamp = fileStat.mtime.getTime();
if (timestamp > fileDesc.timestamp) {
Expand All @@ -105,10 +110,10 @@ export default function(options: CopyPluginOptions) {
if (emitFiles) {
source = await fs.readFile(fileName);
}
} catch (e: any) { // eslint-disable-line @typescript-eslint/no-explicit-any
const loglevel: number | undefined = e['code'] === 'ENOENT' ? undefined : LogLevel.warn;
} catch (e: unknown) {
const loglevel: number | undefined = (e as { code: string })['code'] === 'ENOENT' ? undefined : LogLevel.warn;
logger(`error reading file ${fileName}`, loglevel, e);
continue;
return;
}
for (const dest of fileDesc.dest) {
if (copyOnce && fileDesc.copied.includes(dest)) {
Expand Down Expand Up @@ -137,7 +142,7 @@ export default function(options: CopyPluginOptions) {
logger(`error copying file ${fileName}${destFileName}`, LogLevel.warn, e);
}
}
}
}));
logger.finish(statisticsCollector() as string);
}
};
Expand All @@ -150,9 +155,8 @@ function normalizeSlash(dir: string): string {
return dir;
}

function targets(options: CopyPluginOptions, field: string) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let targets: SingleTargetDesc[] = (options as never as any)[field];
function targets(options: CopyPluginOptions, field: keyof CopyPluginOptions) {
let targets: SingleTargetDesc[] = options[field];
if (targets == null) {
targets = [options] as SingleTargetDesc[];
}
Expand Down
2 changes: 1 addition & 1 deletion plugin-copy/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export type SingleTargetDesc = {
src: string,
src: string | string[],
exclude?: string | string[],
dest?: string;
};
Expand Down
36 changes: 34 additions & 2 deletions plugin-copy/tests/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,38 @@ describe('@rollup-extras/plugin-copy', () => {
}));
});

it('object without targets as a parameter but src is array', async () => {
const pluginInstance = plugin({ src: ['assets/**/*.json'] });
await (pluginInstance as any).buildStart.apply(rollupContextMock);
expect(rollupContextMock.addWatchFile).toBeCalledWith('assets/aFolder/test.json');
expect(rollupContextMock.emitFile).toBeCalledWith(expect.objectContaining({
fileName: 'aFolder/test.json',
source: '',
type: 'asset'
}));
expect(rollupContextMock.emitFile).toBeCalledWith(expect.objectContaining({
fileName: 'aFolder/test2.json',
source: '',
type: 'asset'
}));
});

it('object without targets as a parameter + dest', async () => {
const pluginInstance = plugin({ src: 'assets/**/*.json', dest: 'vendor' });
await (pluginInstance as any).buildStart.apply(rollupContextMock);
expect(rollupContextMock.addWatchFile).toBeCalledWith('assets/aFolder/test.json');
expect(rollupContextMock.emitFile).toBeCalledWith(expect.objectContaining({
fileName: 'vendor/aFolder/test.json',
source: '',
type: 'asset'
}));
expect(rollupContextMock.emitFile).toBeCalledWith(expect.objectContaining({
fileName: 'vendor/aFolder/test2.json',
source: '',
type: 'asset'
}));
});

it('empty array', async () => {
const pluginInstance = plugin([]);
await (pluginInstance as any).buildStart.apply(rollupContextMock);
Expand Down Expand Up @@ -227,7 +259,7 @@ describe('@rollup-extras/plugin-copy', () => {
expect(glob).toBeCalledWith('assets/**/*.json', { ignore: 'assets/**' });
});

it('falttern', async () => {
it('flatten', async () => {
const pluginInstance = plugin({ src: 'assets/**/*.json', flatten: true });
await (pluginInstance as any).buildStart.apply(rollupContextMock);
expect(rollupContextMock.addWatchFile).toBeCalledWith('assets/aFolder/test.json');
Expand All @@ -243,7 +275,7 @@ describe('@rollup-extras/plugin-copy', () => {
}));
});

it('dest with slash and flattern', async () => {
it('dest with slash and flatten', async () => {
const pluginInstance = plugin({
targets: [{ src: 'assets/**/*.json', dest: 'folder' }, { src: 'assets/**/*.json', dest: 'folder/' }],
flatten: true
Expand Down

0 comments on commit bfd87eb

Please sign in to comment.