Skip to content

Commit 0fd2dd3

Browse files
eight04kumar303
authored andcommitted
fix: The default value of --ignore-files no longer causes build to create empty zip files when --source-dir is a sub directory of --artifacts-dir (#790)
1 parent bbfb253 commit 0fd2dd3

File tree

5 files changed

+71
-70
lines changed

5 files changed

+71
-70
lines changed

src/util/file-filter.js

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,25 @@ import {createLogger} from './logger';
77

88
const log = createLogger(__filename);
99

10-
// Use this function to mimic path.resolve without resolving to absolute path.
11-
export const normalizeResolve = (file: string): string => {
12-
// normalize
13-
file = path.normalize(file);
14-
15-
// trim trailing slash
16-
if (path.parse(file).base && file.endsWith(path.sep)) {
17-
return file.slice(0, -1);
10+
// check if target is a sub directory of src
11+
export const isSubPath = (src: string, target: string): boolean => {
12+
const relate = path.relative(src, target);
13+
// same dir
14+
if (!relate) {
15+
return false;
1816
}
19-
return file;
17+
if (relate === '..') {
18+
return false;
19+
}
20+
return !relate.startsWith(`..${path.sep}`);
2021
};
2122

2223
// FileFilter types and implementation.
2324

2425
export type FileFilterOptions = {|
2526
baseIgnoredPatterns?: Array<string>,
2627
ignoreFiles?: Array<string>,
27-
sourceDir?: string,
28+
sourceDir: string,
2829
artifactsDir?: string,
2930
|};
3031

@@ -33,7 +34,7 @@ export type FileFilterOptions = {|
3334
*/
3435
export class FileFilter {
3536
filesToIgnore: Array<string>;
36-
sourceDir: ?string;
37+
sourceDir: string;
3738

3839
constructor({
3940
baseIgnoredPatterns = [
@@ -48,6 +49,7 @@ export class FileFilter {
4849
sourceDir,
4950
artifactsDir,
5051
}: FileFilterOptions = {}) {
52+
sourceDir = path.resolve(sourceDir);
5153

5254
this.filesToIgnore = [];
5355
this.sourceDir = sourceDir;
@@ -56,7 +58,12 @@ export class FileFilter {
5658
if (ignoreFiles) {
5759
this.addToIgnoreList(ignoreFiles);
5860
}
59-
if (artifactsDir) {
61+
if (artifactsDir && isSubPath(sourceDir, artifactsDir)) {
62+
artifactsDir = path.resolve(artifactsDir);
63+
log.debug(
64+
`Ignoring artifacts directory "${artifactsDir}" ` +
65+
'and all its subdirectories'
66+
);
6067
this.addToIgnoreList([
6168
artifactsDir,
6269
path.join(artifactsDir, '**', '*'),
@@ -65,26 +72,23 @@ export class FileFilter {
6572
}
6673

6774
/**
68-
* Resolve relative path to absolute path if sourceDir is setted.
75+
* Resolve relative path to absolute path with sourceDir.
6976
*/
70-
resolve(file: string): string {
71-
if (this.sourceDir) {
72-
const resolvedPath = path.resolve(this.sourceDir, file);
73-
log.debug(
74-
`Resolved path ${file} with sourceDir ${this.sourceDir || ''} ` +
75-
`to ${resolvedPath}`
76-
);
77-
return resolvedPath;
78-
}
79-
return normalizeResolve(file);
77+
resolveWithSourceDir(file: string): string {
78+
const resolvedPath = path.resolve(this.sourceDir, file);
79+
log.debug(
80+
`Resolved path ${file} with sourceDir ${this.sourceDir} ` +
81+
`to ${resolvedPath}`
82+
);
83+
return resolvedPath;
8084
}
8185

8286
/**
8387
* Insert more files into filesToIgnore array.
8488
*/
8589
addToIgnoreList(files: Array<string>) {
8690
for (const file of files) {
87-
this.filesToIgnore.push(this.resolve(file));
91+
this.filesToIgnore.push(this.resolveWithSourceDir(file));
8892
}
8993
}
9094

@@ -99,7 +103,7 @@ export class FileFilter {
99103
* file in the folder that is being archived.
100104
*/
101105
wantFile(filePath: string): boolean {
102-
const resolvedPath = this.resolve(filePath);
106+
const resolvedPath = this.resolveWithSourceDir(filePath);
103107
for (const test of this.filesToIgnore) {
104108
if (minimatch(resolvedPath, test)) {
105109
log.debug(

src/watcher.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import Watchpack from 'watchpack';
33
import debounce from 'debounce';
44

55
import {createLogger} from './util/logger';
6-
import {FileFilter} from './util/file-filter';
76

87

98
const log = createLogger(__filename);
@@ -19,7 +18,7 @@ export type OnSourceChangeParams = {|
1918
sourceDir: string,
2019
artifactsDir: string,
2120
onChange: OnChangeFn,
22-
shouldWatchFile?: ShouldWatchFn,
21+
shouldWatchFile: ShouldWatchFn,
2322
|};
2423

2524
// NOTE: this fix an issue with flow and default exports (which currently
@@ -59,16 +58,12 @@ export type ProxyFileChangesParams = {|
5958
artifactsDir: string,
6059
onChange: OnChangeFn,
6160
filePath: string,
62-
shouldWatchFile?: ShouldWatchFn,
61+
shouldWatchFile: ShouldWatchFn,
6362
|};
6463

6564
export function proxyFileChanges(
6665
{artifactsDir, onChange, filePath, shouldWatchFile}: ProxyFileChangesParams
6766
): void {
68-
if (!shouldWatchFile) {
69-
const fileFilter = new FileFilter();
70-
shouldWatchFile = (...args) => fileFilter.wantFile(...args);
71-
}
7267
if (filePath.indexOf(artifactsDir) === 0 || !shouldWatchFile(filePath)) {
7368
log.debug(`Ignoring change to: ${filePath}`);
7469
} else {

tests/unit/test-cmd/test.build.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ describe('build', () => {
224224
it('asks FileFilter what files to include in the ZIP', () => {
225225
const zipFile = new ZipFile();
226226
const fileFilter = new FileFilter({
227+
sourceDir: '.',
227228
baseIgnoredPatterns: ['**/background-script.js'],
228229
});
229230

@@ -244,11 +245,11 @@ describe('build', () => {
244245

245246
it('lets you rebuild when files change', () => withTempDir(
246247
(tmpDir) => {
247-
const fileFilter = new FileFilter();
248-
sinon.spy(fileFilter, 'wantFile');
249-
const onSourceChange = sinon.spy(() => {});
250248
const sourceDir = fixturePath('minimal-web-ext');
251249
const artifactsDir = tmpDir.path();
250+
const fileFilter = new FileFilter({sourceDir, artifactsDir});
251+
sinon.spy(fileFilter, 'wantFile');
252+
const onSourceChange = sinon.spy(() => {});
252253
return build({
253254
sourceDir, artifactsDir, asNeeded: true,
254255
}, {

tests/unit/test-util/test.file-filter.js

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
/* @flow */
2-
import path from 'path';
3-
42
import {describe, it} from 'mocha';
53
import {assert} from 'chai';
64

7-
import {FileFilter, normalizeResolve} from '../../../src/util/file-filter';
5+
import {FileFilter, isSubPath} from '../../../src/util/file-filter';
86

97
describe('util/file-filter', () => {
108

9+
const newFileFilter = (params = {}) => {
10+
return new FileFilter({
11+
sourceDir: '.',
12+
...params,
13+
});
14+
};
15+
1116
describe('default', () => {
12-
const defaultFilter = new FileFilter();
17+
const defaultFilter = newFileFilter();
1318

1419
it('ignores long XPI paths', () => {
1520
assert.equal(defaultFilter.wantFile('path/to/some.xpi'), false);
@@ -57,38 +62,47 @@ describe('util/file-filter', () => {
5762
describe('options', () => {
5863

5964
it('override the defaults with baseIgnoredPatterns', () => {
60-
const filter = new FileFilter({
65+
const filter = newFileFilter({
6166
baseIgnoredPatterns: ['manifest.json'],
6267
});
6368
assert.equal(filter.wantFile('some.xpi'), true);
6469
assert.equal(filter.wantFile('manifest.json'), false);
6570
});
6671

6772
it('add more files to ignore with ignoreFiles', () => {
68-
const filter = new FileFilter({
73+
const filter = newFileFilter({
6974
ignoreFiles: ['*.log'],
7075
});
7176
assert.equal(filter.wantFile('some.xpi'), false);
7277
assert.equal(filter.wantFile('some.log'), false);
7378
});
7479

7580
it('ignore artifactsDir and its content', () => {
76-
const filter = new FileFilter({
81+
const filter = newFileFilter({
7782
artifactsDir: 'artifacts',
7883
});
7984
assert.equal(filter.wantFile('artifacts'), false);
8085
assert.equal(filter.wantFile('artifacts/some.js'), false);
8186
});
8287

88+
it('does not ignore an artifactsDir outside of sourceDir', () => {
89+
const filter = newFileFilter({
90+
artifactsDir: '.',
91+
sourceDir: 'dist',
92+
});
93+
assert.equal(filter.wantFile('file'), true);
94+
assert.equal(filter.wantFile('dist/file'), true);
95+
});
96+
8397
it('resolve relative path', () => {
84-
const filter = new FileFilter({
98+
const filter = newFileFilter({
8599
sourceDir: '/src',
86100
artifactsDir: 'artifacts',
87101
ignoreFiles: [
88102
'ignore-dir/', 'some.js', '**/some.log', 'ignore/dir/content/**/*',
89103
],
90104
});
91-
assert.equal(filter.wantFile('/src/artifacts'), false);
105+
assert.equal(filter.wantFile('/src/artifacts'), true);
92106
assert.equal(filter.wantFile('/src/ignore-dir'), false);
93107
assert.equal(filter.wantFile('/src/ignore-dir/some.css'), true);
94108
assert.equal(filter.wantFile('/src/some.js'), false);
@@ -103,22 +117,17 @@ describe('util/file-filter', () => {
103117

104118
});
105119

106-
describe('normalizeResolve', () => {
107-
const paths = [
108-
'file', 'dir/',
109-
'path/to/file', 'path/to/dir/', 'path/to/../file', 'path/to/../dir/',
110-
'path/to/dir/.', 'path/to/dir/..',
111-
];
112-
113-
it('mimic path.resolve', () => {
114-
const src = '/src/';
115-
116-
paths.forEach((file) => {
117-
assert.equal(
118-
path.resolve(src, file),
119-
path.join(path.resolve(src), normalizeResolve(file))
120-
);
121-
});
120+
describe('isSubPath', () => {
121+
it('test if target is a sub directory of src', () => {
122+
assert.equal(isSubPath('dist', '.'), false);
123+
assert.equal(isSubPath('.', 'artifacts'), true);
124+
assert.equal(isSubPath('.', '.'), false);
125+
assert.equal(isSubPath('/src/dist', '/src'), false);
126+
assert.equal(isSubPath('/src', '/src/artifacts'), true);
127+
assert.equal(isSubPath('/src', '/src'), false);
128+
assert.equal(isSubPath('/firstroot', '/secondroot'), false);
129+
assert.equal(isSubPath('/src', '/src/.dir'), true);
130+
assert.equal(isSubPath('/src', '/src/..dir'), true);
122131
});
123132
});
124133

tests/unit/test.watcher.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('watcher', () => {
3131
sourceDir: tmpDir.path(),
3232
artifactsDir,
3333
onChange,
34+
shouldWatchFile: () => true,
3435
});
3536
})
3637
.then((watcher) => {
@@ -56,6 +57,7 @@ describe('watcher', () => {
5657
const defaults = {
5758
artifactsDir: '/some/artifacts/dir/',
5859
onChange: () => {},
60+
shouldWatchFile: () => true,
5961
};
6062

6163
it('proxies file changes', () => {
@@ -103,16 +105,6 @@ describe('watcher', () => {
103105

104106
});
105107

106-
it('filters out commonly unwanted files by default', () => {
107-
const conf = {
108-
...defaults,
109-
shouldWatchFile: undefined,
110-
onChange: sinon.spy(() => {}),
111-
};
112-
proxyFileChanges({...conf, filePath: '/somewhere/.git'});
113-
assert.equal(conf.onChange.called, false);
114-
});
115-
116108
});
117109

118110
});

0 commit comments

Comments
 (0)