Skip to content

Commit be62a54

Browse files
eight04kumar303
authored andcommitted
feat: Added --ignore-files option and made build ignore the artifacts directory (#753)
1 parent c8402e4 commit be62a54

File tree

10 files changed

+374
-121
lines changed

10 files changed

+374
-121
lines changed

src/cmd/build.js

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import path from 'path';
33
import {createWriteStream} from 'fs';
44

5-
import minimatch from 'minimatch';
65
import {fs} from 'mz';
76
import parseJSON from 'parse-json';
87
import eventToPromise from 'event-to-promise';
@@ -13,9 +12,14 @@ import getValidatedManifest, {getManifestId} from '../util/manifest';
1312
import {prepareArtifactsDir} from '../util/artifacts';
1413
import {createLogger} from '../util/logger';
1514
import {UsageError} from '../errors';
15+
import {
16+
createFileFilter as defaultFileFilterCreator,
17+
FileFilter,
18+
} from '../util/file-filter';
1619
// Import flow types.
1720
import type {OnSourceChangeFn} from '../watcher';
1821
import type {ExtensionManifest} from '../util/manifest';
22+
import type {FileFilterCreatorFn} from '../util/file-filter';
1923

2024
const log = createLogger(__filename);
2125

@@ -139,25 +143,34 @@ export type BuildCmdParams = {|
139143
sourceDir: string,
140144
artifactsDir: string,
141145
asNeeded?: boolean,
146+
ignoreFiles?: Array<string>,
142147
|};
143148

144149
export type BuildCmdOptions = {|
145150
manifestData?: ExtensionManifest,
146151
fileFilter?: FileFilter,
147152
onSourceChange?: OnSourceChangeFn,
148153
packageCreator?: PackageCreatorFn,
149-
showReadyMessage?: boolean
154+
showReadyMessage?: boolean,
155+
createFileFilter?: FileFilterCreatorFn,
150156
|};
151157

152158
export default async function build(
153-
{sourceDir, artifactsDir, asNeeded = false}: BuildCmdParams,
159+
{sourceDir, artifactsDir, asNeeded = false, ignoreFiles = []}: BuildCmdParams,
154160
{
155-
manifestData, fileFilter = new FileFilter(),
161+
manifestData,
162+
createFileFilter = defaultFileFilterCreator,
163+
fileFilter = createFileFilter({
164+
sourceDir,
165+
artifactsDir,
166+
ignoreFiles,
167+
}),
156168
onSourceChange = defaultSourceWatcher,
157169
packageCreator = defaultPackageCreator,
158170
showReadyMessage = true,
159171
}: BuildCmdOptions = {}
160172
): Promise<ExtensionBuildResult> {
173+
161174
const rebuildAsNeeded = asNeeded; // alias for `build --as-needed`
162175
log.info(`Building web extension from ${sourceDir}`);
163176

@@ -185,42 +198,3 @@ export default async function build(
185198

186199
return result;
187200
}
188-
189-
190-
// FileFilter types and implementation.
191-
192-
export type FileFilterOptions = {|
193-
filesToIgnore?: Array<string>,
194-
|};
195-
196-
/*
197-
* Allows or ignores files when creating a ZIP archive.
198-
*/
199-
export class FileFilter {
200-
filesToIgnore: Array<string>;
201-
202-
constructor({filesToIgnore}: FileFilterOptions = {}) {
203-
this.filesToIgnore = filesToIgnore || [
204-
'**/*.xpi',
205-
'**/*.zip',
206-
'**/.*', // any hidden file
207-
'**/node_modules',
208-
];
209-
}
210-
211-
/*
212-
* Returns true if the file is wanted for the ZIP archive.
213-
*
214-
* This is called by zipdir as wantFile(path, stat) for each
215-
* file in the folder that is being archived.
216-
*/
217-
wantFile(path: string): boolean {
218-
for (const test of this.filesToIgnore) {
219-
if (minimatch(path, test)) {
220-
log.debug(`FileFilter: ignoring file ${path}`);
221-
return false;
222-
}
223-
}
224-
return true;
225-
}
226-
}

src/cmd/lint.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
import {createInstance as defaultLinterCreator} from 'addons-linter';
33

44
import {createLogger} from '../util/logger';
5-
import {FileFilter} from './build';
6-
5+
import {
6+
createFileFilter as defaultFileFilterCreator,
7+
} from '../util/file-filter';
8+
// import flow types
9+
import type {FileFilterCreatorFn} from '../util/file-filter';
710

811
const log = createLogger(__filename);
912

@@ -46,23 +49,27 @@ export type LintCmdParams = {|
4649
metadata?: boolean,
4750
pretty?: boolean,
4851
warningsAsErrors?: boolean,
52+
ignoreFiles?: Array<string>,
53+
artifactsDir?: string,
4954
|};
5055

5156
export type LintCmdOptions = {|
5257
createLinter?: LinterCreatorFn,
53-
fileFilter?: FileFilter,
58+
createFileFilter?: FileFilterCreatorFn,
5459
|};
5560

5661
export default function lint(
5762
{
5863
verbose, sourceDir, selfHosted, boring, output,
59-
metadata, pretty, warningsAsErrors,
64+
metadata, pretty, warningsAsErrors, ignoreFiles, artifactsDir,
6065
}: LintCmdParams,
6166
{
6267
createLinter = defaultLinterCreator,
63-
fileFilter = new FileFilter(),
68+
createFileFilter = defaultFileFilterCreator,
6469
}: LintCmdOptions = {}
6570
): Promise<void> {
71+
const fileFilter = createFileFilter({sourceDir, ignoreFiles, artifactsDir});
72+
6673
log.debug(`Running addons-linter on ${sourceDir}`);
6774
const linter = createLinter({
6875
config: {

src/cmd/run.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import {
1515
import {createLogger} from '../util/logger';
1616
import getValidatedManifest, {getManifestId} from '../util/manifest';
1717
import defaultSourceWatcher from '../watcher';
18+
import {
19+
createFileFilter as defaultFileFilterCreator,
20+
} from '../util/file-filter';
1821
// Import objects that are only used as Flow types.
1922
import type {FirefoxPreferences} from '../firefox/preferences';
2023
import type {OnSourceChangeFn} from '../watcher';
@@ -26,6 +29,7 @@ import type {
2629
FirefoxRDPResponseAddon,
2730
} from '../firefox/remote';
2831
import type {ExtensionManifest} from '../util/manifest';
32+
import type {FileFilterCreatorFn} from '../util/file-filter';
2933

3034
const log = createLogger(__filename);
3135

@@ -38,18 +42,23 @@ export type WatcherCreatorParams = {|
3842
artifactsDir: string,
3943
onSourceChange?: OnSourceChangeFn,
4044
desktopNotifications?: typeof defaultDesktopNotifications,
45+
ignoreFiles?: Array<string>,
46+
createFileFilter?: FileFilterCreatorFn,
4147
|};
4248

43-
4449
export type WatcherCreatorFn = (params: WatcherCreatorParams) => Watchpack;
4550

4651
export function defaultWatcherCreator(
4752
{
48-
addonId, client, sourceDir, artifactsDir,
53+
addonId, client, sourceDir, artifactsDir, ignoreFiles,
4954
onSourceChange = defaultSourceWatcher,
5055
desktopNotifications = defaultDesktopNotifications,
56+
createFileFilter = defaultFileFilterCreator,
5157
}: WatcherCreatorParams
5258
): Watchpack {
59+
const fileFilter = createFileFilter(
60+
{sourceDir, artifactsDir, ignoreFiles}
61+
);
5362
return onSourceChange({
5463
sourceDir,
5564
artifactsDir,
@@ -67,6 +76,7 @@ export function defaultWatcherCreator(
6776
throw error;
6877
});
6978
},
79+
shouldWatchFile: (file) => fileFilter.wantFile(file),
7080
});
7181
}
7282

@@ -80,22 +90,25 @@ export type ReloadStrategyParams = {|
8090
profile: FirefoxProfile,
8191
sourceDir: string,
8292
artifactsDir: string,
93+
ignoreFiles?: Array<string>,
8394
|};
8495

8596
export type ReloadStrategyOptions = {|
8697
createWatcher?: WatcherCreatorFn,
98+
createFileFilter?: FileFilterCreatorFn,
8799
|};
88100

89101
export function defaultReloadStrategy(
90102
{
91-
addonId, firefoxProcess, client, profile, sourceDir, artifactsDir,
103+
addonId, firefoxProcess, client, profile,
104+
sourceDir, artifactsDir, ignoreFiles,
92105
}: ReloadStrategyParams,
93106
{
94107
createWatcher = defaultWatcherCreator,
95108
}: ReloadStrategyOptions = {}
96109
): void {
97110
const watcher: Watchpack = (
98-
createWatcher({addonId, client, sourceDir, artifactsDir})
111+
createWatcher({addonId, client, sourceDir, artifactsDir, ignoreFiles})
99112
);
100113

101114
firefoxProcess.on('close', () => {
@@ -165,6 +178,7 @@ export type CmdRunParams = {|
165178
browserConsole: boolean,
166179
customPrefs?: FirefoxPreferences,
167180
startUrl?: string | Array<string>,
181+
ignoreFiles?: Array<string>,
168182
|};
169183

170184
export type CmdRunOptions = {|
@@ -177,7 +191,7 @@ export default async function run(
177191
{
178192
sourceDir, artifactsDir, firefox, firefoxProfile,
179193
preInstall = false, noReload = false,
180-
browserConsole = false, customPrefs, startUrl,
194+
browserConsole = false, customPrefs, startUrl, ignoreFiles,
181195
}: CmdRunParams,
182196
{
183197
firefoxApp = defaultFirefoxApp,
@@ -264,6 +278,7 @@ export default async function run(
264278
sourceDir,
265279
artifactsDir,
266280
addonId,
281+
ignoreFiles,
267282
});
268283
}
269284
}

src/program.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,15 @@ Example: $0 --help run.
246246
describe: 'Show verbose output',
247247
type: 'boolean',
248248
},
249+
'ignore-files': {
250+
alias: 'i',
251+
describe: 'A list of glob patterns to define which files should be ' +
252+
'ignored. (Example: --ignore-files=path/to/first.js ' +
253+
'path/to/second.js "**/*.log")',
254+
demand: false,
255+
requiresArg: true,
256+
type: 'array',
257+
},
249258
});
250259

251260
program

src/util/file-filter.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/* @flow */
2+
import path from 'path';
3+
4+
import minimatch from 'minimatch';
5+
6+
import {createLogger} from './logger';
7+
8+
const log = createLogger(__filename);
9+
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);
18+
}
19+
return file;
20+
};
21+
22+
// FileFilter types and implementation.
23+
24+
export type FileFilterOptions = {|
25+
baseIgnoredPatterns?: Array<string>,
26+
ignoreFiles?: Array<string>,
27+
sourceDir?: string,
28+
artifactsDir?: string,
29+
|};
30+
31+
/*
32+
* Allows or ignores files.
33+
*/
34+
export class FileFilter {
35+
filesToIgnore: Array<string>;
36+
sourceDir: ?string;
37+
38+
constructor({
39+
baseIgnoredPatterns = [
40+
'**/*.xpi',
41+
'**/*.zip',
42+
'**/.*', // any hidden file and folder
43+
'**/.*/**/*', // and the content inside hidden folder
44+
'**/node_modules',
45+
'**/node_modules/**/*',
46+
],
47+
ignoreFiles = [],
48+
sourceDir,
49+
artifactsDir,
50+
}: FileFilterOptions = {}) {
51+
52+
this.filesToIgnore = [];
53+
this.sourceDir = sourceDir;
54+
55+
this.addToIgnoreList(baseIgnoredPatterns);
56+
if (ignoreFiles) {
57+
this.addToIgnoreList(ignoreFiles);
58+
}
59+
if (artifactsDir) {
60+
this.addToIgnoreList([
61+
artifactsDir,
62+
path.join(artifactsDir, '**', '*'),
63+
]);
64+
}
65+
}
66+
67+
/**
68+
* Resolve relative path to absolute path if sourceDir is setted.
69+
*/
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);
80+
}
81+
82+
/**
83+
* Insert more files into filesToIgnore array.
84+
*/
85+
addToIgnoreList(files: Array<string>) {
86+
for (const file of files) {
87+
this.filesToIgnore.push(this.resolve(file));
88+
}
89+
}
90+
91+
/*
92+
* Returns true if the file is wanted.
93+
*
94+
* If path does not start with a slash, it will be treated as a path
95+
* relative to sourceDir when matching it against all configured
96+
* ignore-patterns.
97+
*
98+
* This is called by zipdir as wantFile(path, stat) for each
99+
* file in the folder that is being archived.
100+
*/
101+
wantFile(path: string): boolean {
102+
path = this.resolve(path);
103+
for (const test of this.filesToIgnore) {
104+
if (minimatch(path, test)) {
105+
log.debug(`FileFilter: ignoring file ${path} (it matched ${test})`);
106+
return false;
107+
}
108+
}
109+
return true;
110+
}
111+
}
112+
113+
// a helper function to make mocking easier
114+
115+
export const createFileFilter = (
116+
(params: FileFilterOptions): FileFilter => new FileFilter(params)
117+
);
118+
119+
export type FileFilterCreatorFn = typeof createFileFilter;

src/watcher.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Watchpack from 'watchpack';
33
import debounce from 'debounce';
44

55
import {createLogger} from './util/logger';
6-
import {FileFilter} from './cmd/build';
6+
import {FileFilter} from './util/file-filter';
77

88

99
const log = createLogger(__filename);

0 commit comments

Comments
 (0)