Skip to content

Commit

Permalink
Change grunt, gulp and jake task auto detection to be off by default (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexdima committed May 11, 2021
1 parent 4151b62 commit 5f3466a
Show file tree
Hide file tree
Showing 9 changed files with 96 additions and 20 deletions.
4 changes: 2 additions & 2 deletions extensions/grunt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
"title": "Grunt",
"properties": {
"grunt.autoDetect": {
"scope": "resource",
"scope": "application",
"type": "string",
"enum": [
"off",
"on"
],
"default": "on",
"default": "off",
"description": "%config.grunt.autoDetect%"
}
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/grunt/package.nls.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"description": "Extension to add Grunt capabilities to VS Code.",
"displayName": "Grunt support for VS Code",
"config.grunt.autoDetect": "Controls whether auto detection of Grunt tasks is on or off. Default is on.",
"config.grunt.autoDetect": "Controls enablement of Grunt task detection. Grunt task detection can cause files in any open workspace to be executed.",
"grunt.taskDefinition.type.description": "The Grunt task to customize.",
"grunt.taskDefinition.args.description": "Command line arguments to pass to the grunt task",
"grunt.taskDefinition.file.description": "The Grunt file that provides the task. Can be omitted."
Expand Down
4 changes: 2 additions & 2 deletions extensions/gulp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
"title": "Gulp",
"properties": {
"gulp.autoDetect": {
"scope": "resource",
"scope": "application",
"type": "string",
"enum": [
"off",
"on"
],
"default": "on",
"default": "off",
"description": "%config.gulp.autoDetect%"
}
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/gulp/package.nls.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"description": "Extension to add Gulp capabilities to VSCode.",
"displayName": "Gulp support for VSCode",
"config.gulp.autoDetect": "Controls whether auto detection of Gulp tasks is on or off. Default is on.",
"config.gulp.autoDetect": "Controls enablement of Gulp task detection. Gulp task detection can cause files in any open workspace to be executed.",
"gulp.taskDefinition.type.description": "The Gulp task to customize.",
"gulp.taskDefinition.file.description": "The Gulp file that provides the task. Can be omitted."
}
4 changes: 2 additions & 2 deletions extensions/jake/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@
"title": "Jake",
"properties": {
"jake.autoDetect": {
"scope": "resource",
"scope": "application",
"type": "string",
"enum": [
"off",
"on"
],
"default": "on",
"default": "off",
"description": "%config.jake.autoDetect%"
}
}
Expand Down
2 changes: 1 addition & 1 deletion extensions/jake/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"displayName": "Jake support for VS Code",
"jake.taskDefinition.type.description": "The Jake task to customize.",
"jake.taskDefinition.file.description": "The Jake file that provides the task. Can be omitted.",
"config.jake.autoDetect": "Controls whether auto detection of Jake tasks is on or off. Default is on."
"config.jake.autoDetect": "Controls enablement of Jake task detection. Jake task detection can cause files in any open workspace to be executed."
}
19 changes: 16 additions & 3 deletions src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export namespace ConfigureTaskAction {
export const TEXT = nls.localize('ConfigureTaskRunnerAction.label', "Configure Task");
}

type TaskQuickPickEntryType = (IQuickPickItem & { task: Task; }) | (IQuickPickItem & { folder: IWorkspaceFolder; });
type TaskQuickPickEntryType = (IQuickPickItem & { task: Task; }) | (IQuickPickItem & { folder: IWorkspaceFolder; }) | (IQuickPickItem & { settingType: string; });

class ProblemReporter implements TaskConfig.IProblemReporter {

Expand Down Expand Up @@ -2330,7 +2330,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}

private async showTwoLevelQuickPick(placeHolder: string, defaultEntry?: TaskQuickPickEntry) {
return TaskQuickPick.show(this, this.configurationService, this.quickInputService, this.notificationService, placeHolder, defaultEntry);
return TaskQuickPick.show(this, this.configurationService, this.quickInputService, this.notificationService, this.dialogService, placeHolder, defaultEntry);
}

private async showQuickPick(tasks: Promise<Task[]> | Task[], placeHolder: string, defaultEntry?: TaskQuickPickEntry, group: boolean = false, sort: boolean = false, selectedEntry?: TaskQuickPickEntry, additionalEntries?: TaskQuickPickEntry[]): Promise<TaskQuickPickEntry | undefined | null> {
Expand Down Expand Up @@ -2918,6 +2918,11 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
return candidate && !!candidate.task;
}

private isSettingEntry(value: IQuickPickItem): value is IQuickPickItem & { settingType: string } {
let candidate: IQuickPickItem & { settingType: string } = value as any;
return candidate && !!candidate.settingType;
}

private configureTask(task: Task) {
if (ContributedTask.is(task)) {
this.customize(task, undefined, true);
Expand All @@ -2934,6 +2939,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
if (this.isTaskEntry(selection)) {
this.configureTask(selection.task);
} else if (this.isSettingEntry(selection)) {
const taskQuickPick = new TaskQuickPick(this, this.configurationService, this.quickInputService, this.notificationService, this.dialogService);
taskQuickPick.handleSettingOption(selection.settingType);
} else if (selection.folder && (this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY)) {
this.openTaskFile(selection.folder.toResource('.vscode/tasks.json'), TaskSourceKind.Workspace);
} else {
Expand Down Expand Up @@ -3028,7 +3036,12 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
}

this.quickInputService.pick(entries,
const entriesWithSettings = entries.then(resolvedEntries => {
resolvedEntries.push(...TaskQuickPick.allSettingEntries(this.configurationService));
return resolvedEntries;
});

this.quickInputService.pick(entriesWithSettings,
{ placeHolder: nls.localize('TaskService.pickTask', 'Select a task to configure') }, cancellationToken).
then(async (selection) => {
if (cancellationToken.isCancellationRequested) {
Expand Down
73 changes: 67 additions & 6 deletions src/vs/workbench/contrib/tasks/browser/taskQuickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { Disposable } from 'vs/base/common/lifecycle';
import { Event } from 'vs/base/common/event';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { Codicon } from 'vs/base/common/codicons';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';

export const QUICKOPEN_DETAIL_CONFIG = 'task.quickOpen.detail';
export const QUICKOPEN_SKIP_CONFIG = 'task.quickOpen.skip';
Expand All @@ -29,8 +30,10 @@ export function isWorkspaceFolder(folder: IWorkspace | IWorkspaceFolder): folder
export interface TaskQuickPickEntry extends IQuickPickItem {
task: Task | undefined | null;
}

export interface TaskTwoLevelQuickPickEntry extends IQuickPickItem {
task: Task | ConfiguringTask | string | undefined | null;
settingType?: string;
}

const SHOW_ALL: string = nls.localize('taskQuickPick.showAll', "Show All Tasks...");
Expand All @@ -45,7 +48,8 @@ export class TaskQuickPick extends Disposable {
private taskService: ITaskService,
private configurationService: IConfigurationService,
private quickInputService: IQuickInputService,
private notificationService: INotificationService) {
private notificationService: INotificationService,
private dialogService: IDialogService) {
super();
this.sorter = this.taskService.createSorter();
}
Expand Down Expand Up @@ -173,6 +177,21 @@ export class TaskQuickPick extends Disposable {
return { entries: this.topLevelEntries, isSingleConfigured: configuredTasks.length === 1 ? configuredTasks[0] : undefined };
}

public async handleSettingOption(selectedType: string) {
const noButton = nls.localize('TaskQuickPick.changeSettingNo', "No");
const yesButton = nls.localize('TaskQuickPick.changeSettingYes', "Yes");
const changeSettingResult = await this.dialogService.show(Severity.Warning,
nls.localize('TaskQuickPick.changeSettingDetails',
"Task detection for {0} tasks causes files in any workspace you open to be run as code. Enabling {0} task detection is a user setting and will apply to any workspace you open. Do you want to enable {0} task detection for all workspaces?", selectedType),
[noButton, yesButton]);

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 13, 2022

Member

@meganrogge is this intentionally putting the noButton first?

This comment has been minimized.

Copy link
@meganrogge

meganrogge Jul 13, 2022

Contributor

That change preceded me, so I'm not sure.

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 14, 2022

Member

Maybe @alexr00

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 14, 2022

Member

Maybe @alexr00

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 14, 2022

Member

Maybe @alexr00

This comment has been minimized.

Copy link
@alexr00

alexr00 Jul 14, 2022

Member

I think we put the option that would prevent tasks from running first so that users would have to deliberately click the yes option to make tasks run. I don't know how much this actually matters though.

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 14, 2022

Member

Ok just wanted to double check, because the first button will be by default selected and has focus.

This comment has been minimized.

Copy link
@bpasero

bpasero Jul 14, 2022

Member

Ok just wanted to double check, because the first button will be by default selected and has focus.

if (changeSettingResult.choice === 1) {
await this.configurationService.updateValue(`${selectedType}.autoDetect`, 'on');
await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
return this.show(nls.localize('TaskService.pickRunTask', 'Select the task to run'), undefined, selectedType);
}
return undefined;
}

public async show(placeHolder: string, defaultEntry?: TaskQuickPickEntry, startAtType?: string): Promise<Task | undefined | null> {
const picker: IQuickPick<TaskTwoLevelQuickPickEntry> = this.quickInputService.createQuickPick();
picker.placeholder = placeHolder;
Expand Down Expand Up @@ -218,9 +237,12 @@ export class TaskQuickPick extends Disposable {
if (Types.isString(firstLevelTask)) {
// Proceed to second level of quick pick
const selectedEntry = await this.doPickerSecondLevel(picker, firstLevelTask);
if (selectedEntry && selectedEntry.task === null) {
if (selectedEntry && !selectedEntry.settingType && selectedEntry.task === null) {
// The user has chosen to go back to the first level
firstLevelTask = await this.doPickerFirstLevel(picker, (await this.getTopLevelEntries(defaultEntry)).entries);
} else if (selectedEntry && Types.isString(selectedEntry.settingType)) {
picker.dispose();
return this.handleSettingOption(selectedEntry.settingType);
} else {
picker.dispose();
return (selectedEntry?.task && !Types.isString(selectedEntry?.task)) ? this.toTask(selectedEntry?.task) : undefined;
Expand Down Expand Up @@ -249,7 +271,9 @@ export class TaskQuickPick extends Disposable {
private async doPickerSecondLevel(picker: IQuickPick<TaskTwoLevelQuickPickEntry>, type: string) {
picker.busy = true;
if (type === SHOW_ALL) {
picker.items = (await this.taskService.tasks()).sort((a, b) => this.sorter.compare(a, b)).map(task => this.createTaskEntry(task));
const items = (await this.taskService.tasks()).sort((a, b) => this.sorter.compare(a, b)).map(task => this.createTaskEntry(task));
items.push(...TaskQuickPick.allSettingEntries(this.configurationService));
picker.items = items;
} else {
picker.value = '';
picker.items = await this.getEntriesForProvider(type);
Expand All @@ -264,6 +288,36 @@ export class TaskQuickPick extends Disposable {
return secondLevelPickerResult;
}

public static allSettingEntries(configurationService: IConfigurationService): (TaskTwoLevelQuickPickEntry & { settingType: string })[] {
const entries: (TaskTwoLevelQuickPickEntry & { settingType: string })[] = [];
const gruntEntry = TaskQuickPick.getSettingEntry(configurationService, 'grunt');
if (gruntEntry) {
entries.push(gruntEntry);
}
const gulpEntry = TaskQuickPick.getSettingEntry(configurationService, 'gulp');
if (gulpEntry) {
entries.push(gulpEntry);
}
const jakeEntry = TaskQuickPick.getSettingEntry(configurationService, 'jake');
if (jakeEntry) {
entries.push(jakeEntry);
}
return entries;
}

public static getSettingEntry(configurationService: IConfigurationService, type: string): (TaskTwoLevelQuickPickEntry & { settingType: string }) | undefined {
if (configurationService.getValue(`${type}.autoDetect`) === 'off') {
return {
label: nls.localize('TaskQuickPick.changeSettingsOptions', "$(gear) {0} task detection is turned off. Enable {1} task detection...",
type[0].toUpperCase() + type.slice(1), type),
task: null,
settingType: type,
alwaysShow: true
};
}
return undefined;
}

private async getEntriesForProvider(type: string): Promise<QuickPickInput<TaskTwoLevelQuickPickEntry>[]> {
const tasks = (await this.taskService.tasks({ type })).sort((a, b) => this.sorter.compare(a, b));
let taskQuickPickEntries: QuickPickInput<TaskTwoLevelQuickPickEntry>[];
Expand All @@ -283,6 +337,11 @@ export class TaskQuickPick extends Disposable {
alwaysShow: true
}];
}

const settingEntry = TaskQuickPick.getSettingEntry(this.configurationService, type);
if (settingEntry) {
taskQuickPickEntries.push(settingEntry);
}
return taskQuickPickEntries;
}

Expand All @@ -299,8 +358,10 @@ export class TaskQuickPick extends Disposable {
return resolvedTask;
}

static async show(taskService: ITaskService, configurationService: IConfigurationService, quickInputService: IQuickInputService, notificationService: INotificationService, placeHolder: string, defaultEntry?: TaskQuickPickEntry) {
const taskQuickPick = new TaskQuickPick(taskService, configurationService, quickInputService, notificationService);
static async show(taskService: ITaskService, configurationService: IConfigurationService,
quickInputService: IQuickInputService, notificationService: INotificationService,
dialogService: IDialogService, placeHolder: string, defaultEntry?: TaskQuickPickEntry) {
const taskQuickPick = new TaskQuickPick(taskService, configurationService, quickInputService, notificationService, dialogService);
return taskQuickPick.show(placeHolder, defaultEntry);
}
}
6 changes: 4 additions & 2 deletions src/vs/workbench/contrib/tasks/browser/tasksQuickAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { TaskQuickPick, TaskTwoLevelQuickPickEntry } from 'vs/workbench/contrib/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { isString } from 'vs/base/common/types';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';

export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQuickAccessItem> {

Expand All @@ -28,7 +29,8 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQ
@ITaskService private taskService: ITaskService,
@IConfigurationService private configurationService: IConfigurationService,
@IQuickInputService private quickInputService: IQuickInputService,
@INotificationService private notificationService: INotificationService
@INotificationService private notificationService: INotificationService,
@IDialogService private dialogService: IDialogService
) {
super(TasksQuickAccessProvider.PREFIX, {
noResultsPick: {
Expand All @@ -47,7 +49,7 @@ export class TasksQuickAccessProvider extends PickerQuickAccessProvider<IPickerQ
return [];
}

const taskQuickPick = new TaskQuickPick(this.taskService, this.configurationService, this.quickInputService, this.notificationService);
const taskQuickPick = new TaskQuickPick(this.taskService, this.configurationService, this.quickInputService, this.notificationService, this.dialogService);
const topLevelPicks = await taskQuickPick.getTopLevelEntries();
const taskPicks: Array<IPickerQuickAccessItem | IQuickPickSeparator> = [];

Expand Down

0 comments on commit 5f3466a

Please sign in to comment.