Skip to content

Commit 4f652fc

Browse files
committed
add setting to define whether pre or post scripts should be filtered
1 parent c1b4ba2 commit 4f652fc

6 files changed

Lines changed: 65 additions & 21 deletions

File tree

extensions/npm/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ For more information about auto detection of Tasks pls see the [documentation](h
1515
- `npm.packageManager` the package manager used to run the scripts: `npm` or `yarn`, the default is `npm`.
1616
- `npm.exclude` glob patterns for folders that should be excluded from automatic script detection. The pattern is matched against the **absolute path** of the package.json. For example, to exclude all test folders use '**/test/**'.
1717
- `npm.enableScriptExplorer` enable an explorer view for npm scripts.
18+
- `npm.filterPrePostScripts` filter pre or post scripts, the default is `true`.

extensions/npm/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@
151151
"default": false,
152152
"scope": "resource",
153153
"description": "%config.npm.enableScriptExplorer%"
154+
},
155+
"npm.filterPrePostScripts": {
156+
"type": "boolean",
157+
"default": true,
158+
"scope": "resource",
159+
"description": "%config.npm.filterPrePostScripts%"
154160
}
155161
}
156162
},

extensions/npm/package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"config.npm.packageManager": "The package manager used to run scripts.",
77
"config.npm.exclude": "Configure glob patterns for folders that should be excluded from automatic script detection.",
88
"config.npm.enableScriptExplorer": "Enable an explorer view for npm scripts.",
9+
"config.npm.filterPrePostScripts": "Filter pre- and postscripts. Default is true.",
910
"npm.parseError": "Npm task detection: failed to parse the file {0}",
1011
"taskdef.script": "The npm script to customize.",
1112
"taskdef.path": "The path to the folder of the package.json file that provides the script. Can be omitted.",

extensions/npm/src/main.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,37 @@ import * as vscode from 'vscode';
99

1010
import { addJSONProviders } from './features/jsonContributions';
1111
import { NpmScriptsTreeDataProvider } from './npmView';
12-
import { provideNpmScripts } from './tasks';
12+
import { provideNpmScripts, invalidateScriptsCache } from './tasks';
1313

1414
let taskProvider: vscode.Disposable | undefined;
1515

1616
export async function activate(context: vscode.ExtensionContext): Promise<void> {
1717
taskProvider = registerTaskProvider(context);
18-
registerExplorer(context);
18+
let treeDataProvider = registerExplorer(context);
1919
configureHttpRequest();
20-
vscode.workspace.onDidChangeConfiguration(() => {
20+
vscode.workspace.onDidChangeConfiguration((e) => {
2121
configureHttpRequest();
22+
if (e.affectsConfiguration('npm.filterPrePostScripts')) {
23+
invalidateScriptsCache();
24+
if (treeDataProvider) {
25+
treeDataProvider.refresh();
26+
}
27+
}
2228
});
2329
context.subscriptions.push(addJSONProviders(httpRequest.xhr));
2430
}
2531

2632
function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposable | undefined {
2733
if (vscode.workspace.workspaceFolders) {
28-
let cachedTasks: vscode.Task[] | undefined = undefined;
29-
30-
let flushCache = () => cachedTasks = undefined;
3134
let watcher = vscode.workspace.createFileSystemWatcher('**/package.json');
32-
watcher.onDidChange((_e) => flushCache());
33-
watcher.onDidDelete((_e) => flushCache());
34-
watcher.onDidCreate((_e) => flushCache());
35+
watcher.onDidChange((_e) => invalidateScriptsCache());
36+
watcher.onDidDelete((_e) => invalidateScriptsCache());
37+
watcher.onDidCreate((_e) => invalidateScriptsCache());
3538
context.subscriptions.push(watcher);
3639

3740
let provider: vscode.TaskProvider = {
3841
provideTasks: async () => {
39-
if (!cachedTasks) {
40-
cachedTasks = await provideNpmScripts();
41-
}
42-
return cachedTasks;
42+
return provideNpmScripts();
4343
},
4444
resolveTask(_task: vscode.Task): vscode.Task | undefined {
4545
return undefined;
@@ -50,11 +50,14 @@ function registerTaskProvider(context: vscode.ExtensionContext): vscode.Disposab
5050
return undefined;
5151
}
5252

53-
async function registerExplorer(context: vscode.ExtensionContext) {
53+
function registerExplorer(context: vscode.ExtensionContext): NpmScriptsTreeDataProvider | undefined {
5454
if (vscode.workspace.workspaceFolders) {
55-
let treeDataProvider = vscode.window.registerTreeDataProvider('npm', new NpmScriptsTreeDataProvider(context));
56-
context.subscriptions.push(treeDataProvider);
55+
let treeDataProvider = new NpmScriptsTreeDataProvider(context);
56+
let disposable = vscode.window.registerTreeDataProvider('npm', treeDataProvider);
57+
context.subscriptions.push(disposable);
58+
return treeDataProvider;
5759
}
60+
return undefined;
5861
}
5962

6063
function configureHttpRequest() {

extensions/npm/src/npmView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export class NpmScriptsTreeDataProvider implements TreeDataProvider<TreeItem> {
251251
await window.showTextDocument(document, { selection: new Selection(position, position) });
252252
}
253253

254-
private refresh() {
254+
public refresh() {
255255
this.taskTree = null;
256256
this._onDidChangeTreeData.fire();
257257
}

extensions/npm/src/tasks.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ export interface NpmTaskDefinition extends TaskDefinition {
2020

2121
type AutoDetect = 'on' | 'off';
2222

23+
let cachedTasks: Task[] | undefined = undefined;
24+
25+
export function invalidateScriptsCache() {
26+
cachedTasks = undefined;
27+
}
28+
2329
const buildNames: string[] = ['build', 'compile', 'watch'];
2430
function isBuildTask(name: string): boolean {
2531
for (let buildName of buildNames) {
@@ -40,8 +46,24 @@ function isTestTask(name: string): boolean {
4046
return false;
4147
}
4248

43-
function isNotPreOrPostScript(script: string): boolean {
44-
return !(script.startsWith('pre') || script.startsWith('post'));
49+
function getPrePostScripts(scripts: any): Set<string> {
50+
const prePostScripts: Set<string> = new Set([
51+
'preuninstall', 'postuninstall', 'prepack', 'postpack', 'preinstall', 'postinstall',
52+
'prepack', 'postpack', 'prepublish', 'postpublish', 'preversion', 'postversion',
53+
'prestop', 'poststop', 'prerestart', 'postrestart', 'preshrinkwrap', 'postshrinkwrap',
54+
'pretest', 'postest', 'prepublishOnly'
55+
]);
56+
let keys = Object.keys(scripts);
57+
for (let i = 0; i < keys.length; i++) {
58+
const script = keys[i];
59+
const prepost = ['pre' + script, 'post' + script];
60+
prepost.forEach(each => {
61+
if (scripts[each]) {
62+
prePostScripts.add(each);
63+
}
64+
});
65+
}
66+
return prePostScripts;
4567
}
4668

4769
export function isWorkspaceFolder(value: any): value is WorkspaceFolder {
@@ -74,7 +96,8 @@ export async function hasNpmScripts(): Promise<boolean> {
7496
}
7597
}
7698

77-
export async function provideNpmScripts(): Promise<Task[]> {
99+
async function detectNpmScripts(): Promise<Task[]> {
100+
78101
let emptyTasks: Task[] = [];
79102
let allTasks: Task[] = [];
80103

@@ -102,6 +125,13 @@ export async function provideNpmScripts(): Promise<Task[]> {
102125
}
103126
}
104127

128+
export async function provideNpmScripts(): Promise<Task[]> {
129+
if (!cachedTasks) {
130+
cachedTasks = await detectNpmScripts();
131+
}
132+
return cachedTasks;
133+
}
134+
105135
function isAutoDetectionEnabled(folder: WorkspaceFolder): boolean {
106136
return workspace.getConfiguration('npm', folder.uri).get<AutoDetect>('autoDetect') === 'on';
107137
}
@@ -140,7 +170,10 @@ async function provideNpmScriptsForFolder(packageJsonUri: Uri): Promise<Task[]>
140170
}
141171

142172
const result: Task[] = [];
143-
Object.keys(scripts).filter(isNotPreOrPostScript).forEach(each => {
173+
174+
const filterPrePost = workspace.getConfiguration('npm', folder.uri).get<boolean>('filterPrePostScripts');
175+
const prePostScripts = filterPrePost ? getPrePostScripts(scripts) : new Set<String>();
176+
Object.keys(scripts).filter(each => !prePostScripts.has(each)).forEach(each => {
144177
const task = createTask(each, `run ${each}`, folder!, packageJsonUri);
145178
const lowerCaseTaskName = each.toLowerCase();
146179
if (isBuildTask(lowerCaseTaskName)) {

0 commit comments

Comments
 (0)