Skip to content

Commit

Permalink
fix(package): limit maximum depth of glob stream
Browse files Browse the repository at this point in the history
Limit of the maximum depth of a read directory. New extension property advanced.deep with default value 5 .
  • Loading branch information
tomandco-rafalwolak committed Aug 19, 2019
1 parent 142d02d commit 1fec34a
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 68 deletions.
1 change: 0 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"type": "npm",
"script": "watch",
"problemMatcher": "$gulp-tsc",
"isBackground": true,
"presentation": {
"reveal": "never"
},
Expand Down
45 changes: 28 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,43 @@
"type": "object",
"title": "Workspace Manager",
"properties": {
"workspace-manager.includeGlobPattern": {
"type": "array",
"default": [
"~/**/*"
],
"description": "Paths of directories when `.code-workspace` files can be saved and then read from"
},
"workspace-manager.excludeGlobPattern": {
"type": "array",
"default": [],
"description": "A glob pattern that defines files and folders to exclude"
},
"workspace-manager.codeExecutable": {
"workspace-manager.advanced.codeExecutable": {
"type": "string",
"default": "code",
"description": "Path to the executable file for VS Code"
"description": "Path to the executable file for VS Code."
},
"workspace-manager.codeInsidersExecutable": {
"workspace-manager.advanced.codeInsidersExecutable": {
"type": "string",
"default": "code-insiders",
"description": "Path to the executable file for VS Code Insiders"
"description": "Path to the executable file for VS Code Insiders."
},
"workspace-manager.advanced.deep": {
"type": "number",
"default": "5",
"description": "The maximum depth of a read directory relative to the start directory."
},
"workspace-manager.advanced.excludeGlobPattern": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"description": "A glob pattern that defines files and folders to exclude."
},
"workspace-manager.includeGlobPattern": {
"type": "array",
"items": {
"type": "string"
},
"default": [
"~/**/*"
],
"description": "Paths of directories when `.code-workspace` files can be saved and then read from. You do not need to use `**/*` at the end."
},
"workspace-manager.showInActivityBar": {
"type": "boolean",
"default": true,
"description": "Whether or not to show the activity bar tree view container"
"description": "Whether or not to show the activity bar tree view container."
},
"workspace-manager.showInExplorer": {
"type": "boolean",
Expand Down
7 changes: 4 additions & 3 deletions src/model/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@ export enum IOutputLevel {

export interface IConfig {
includeGlobPattern: string | string[];
excludeGlobPattern: string | string[];
codeExecutable: string;
codeInsidersExecutable: string;
showInActivityBar: boolean;
showInExplorer: boolean;
outputLevel: IOutputLevel;
advanced: IAdvancedConfig;
}

export interface IAdvancedConfig {
codeExecutable: string;
codeInsidersExecutable: string;
deep: number;
excludeGlobPattern: string | string[];
telemetry: {
enabled: boolean;
};
Expand Down
12 changes: 8 additions & 4 deletions src/util/getApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ import * as fs from 'fs';
import * as path from 'path';
import * as VError from 'verror';
import * as vscode from 'vscode';
import { extensionId } from '../constants';
import { configuration } from '../configuration';
import { IAdvancedConfig } from '../model/config';

export function getApp() {
try {
const key = `${
vscode.env.appName.toLowerCase().search('insiders') !== -1
? 'codeInsiders'
: 'code'
}Executable`;
const app = <string>(
vscode.workspace.getConfiguration(extensionId).get(key)
}Executable` as keyof IAdvancedConfig;

const app = configuration.get<string>(
configuration.name('advanced')(key).value,
null,
'code'
);

if (app.search(/\s/) !== -1) {
Expand Down
64 changes: 38 additions & 26 deletions src/util/getWorkspaceEntries.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as glob from 'fast-glob';
import * as VError from 'verror';
import * as vscode from 'vscode';
import { join } from 'path';
import { Cache } from '../cache/cache';
import { configuration } from '../configuration';
import { CommandContext, extensionId, setCommandContext } from '../constants';
Expand Down Expand Up @@ -30,13 +31,20 @@ export async function getWorkspaceEntries(
}

const excludeGlobPattern: string[] = configuration.get<string[]>(
configuration.name('excludeGlobPattern').value,
configuration.name('advanced')('excludeGlobPattern').value,
null,
[]
);
const deep: number = configuration.get<number>(
configuration.name('advanced')('deep').value,
null,
5
);
const directoryPaths = getWorkspaceEntryDirectories();

const directories = directoryPaths.map(dir => `${dir}**/*.code-workspace`);
const directories = directoryPaths
.map(dir => join(dir, '**/*.code-workspace'))
.filter((path, index, arr) => arr.indexOf(path) == index);

let entries: WorkspaceEntry[] = [];
let filesParsed: number = 0;
Expand Down Expand Up @@ -71,9 +79,35 @@ export async function getWorkspaceEntries(

const stream = glob.stream(directories, {
ignore: ['**/node_modules/**', ...excludeGlobPattern],
deep: deep,
onlyFiles: true
});

const onEnd = () => {
Logger.info(
`All the workspece files in the directories [${directories.join(
', '
)}] has been found [${entries.length}]`
);

entries.sort((a, b) => a.name.localeCompare(b.name));

cache.update(cacheKey, entries);

if (timeoutId) {
clearTimeout(timeoutId);
}

notifier.notify(
'file-submodule',
'Workspace entries cached (click to cache again)'
);

setCommandContext(CommandContext.Empty, !!!entries.length);

return entries;
};

stream
.on('data', (path: string) => {
notifier.notify(
Expand All @@ -88,30 +122,8 @@ export async function getWorkspaceEntries(
vscode.window.showInformationMessage(err);
throw err;
})
.on('end', () => {
Logger.info(
`All the workspece files in the directories [${directories.join(
', '
)}] has been found [${entries.length}]`
);

entries.sort((a, b) => a.name.localeCompare(b.name));

cache.update(cacheKey, entries);

if (timeoutId) {
clearTimeout(timeoutId);
}

notifier.notify(
'file-submodule',
'Workspace entries cached (click to cache again)'
);

setCommandContext(CommandContext.Empty, !!!entries.length);

return entries;
})
.on('pause', onEnd)
.on('end', onEnd)
.on('close', () => {
Logger.info(
'Stream has been destroyed and file has been closed'
Expand Down
17 changes: 2 additions & 15 deletions src/util/getWorkspaceEntryDirectories.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as glob from 'fast-glob';
import * as fs from 'fs';
import { existsSync, statSync } from 'fs';
import { configuration } from '../configuration';

export function getWorkspaceEntryDirectories(): string[] {
Expand Down Expand Up @@ -37,22 +36,10 @@ export function getWorkspaceEntryDirectories(): string[] {
const uniquePaths = Object.keys(pathsHash);

const pathsAfterGlobbingHash = uniquePaths
.map(p => {
try {
return glob.sync([p], {
cwd: '/',
onlyDirectories: true,
absolute: true
});
} catch (err) {
return [];
}
})
.reduce((acc, val) => acc.concat(val), [])
.concat(uniquePaths.map(p => p.replace(/(:?\*\*?\/?)+$/, '')))
.filter(p => {
try {
return fs.existsSync(p) && fs.statSync(p).isDirectory();
return existsSync(p) && statSync(p).isDirectory();
} catch (err) {
return false;
}
Expand Down
8 changes: 6 additions & 2 deletions src/views/abstractView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export abstract class AbstractView implements vscode.Disposable {
>this._execute(view));
} else {
const subscriptions = (<any>view).map((view: string) =>
vscode.window.registerTreeDataProvider(view, <TreeDataProvider>(
vscode.window.registerTreeDataProvider(view, <TreeDataProvider>(
this._execute(view)
))
);
Expand Down Expand Up @@ -56,7 +56,11 @@ export abstract class AbstractView implements vscode.Disposable {
) &&
!configuration.changed(
e,
configuration.name('excludeGlobPattern').value
configuration.name('advanced')('excludeGlobPattern').value
) &&
!configuration.changed(
e,
configuration.name('advanced')('deep').value
)
) {
return;
Expand Down

0 comments on commit 1fec34a

Please sign in to comment.