Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: node_modules will be searched when detecting configuration #229

Merged
merged 5 commits into from
Sep 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/commands/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import * as fse from 'fs-extra';
import { Uri, window, workspace } from 'vscode';
import { checkstyleDiagnosticManager } from '../checkstyleDiagnosticManager';
import { findNonIgnoredFiles } from '../utils/workspaceUtils';

export async function checkCode(uri?: Uri): Promise<void> {
if (!uri) { // If not specified, check active editor
Expand All @@ -14,7 +15,7 @@ export async function checkCode(uri?: Uri): Promise<void> {
}
let filesToCheck: Uri[];
if ((await fse.stat(uri.fsPath)).isDirectory()) {
filesToCheck = await workspace.findFiles(`${workspace.asRelativePath(uri)}/**/*.java`);
filesToCheck = await findNonIgnoredFiles(`${workspace.asRelativePath(uri)}/**/*.java`);
} else {
filesToCheck = [uri];
}
Expand Down
7 changes: 4 additions & 3 deletions src/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

import * as fse from 'fs-extra';
import * as path from 'path';
import { Uri, window, workspace, WorkspaceFolder } from 'vscode';
import { Uri, window, WorkspaceFolder } from 'vscode';
import * as xmljs from 'xml-js';
import { checkstyleChannel } from '../checkstyleChannel';
import { BuiltinConfiguration, checkstyleDoctypeIds } from '../constants/checkstyleConfigs';
import { IQuickPickItemEx } from '../models';
import { getDefaultWorkspaceFolder, setCheckstyleConfigurationPath, tryUseWorkspaceFolder } from '../utils/settingUtils';
import { setCheckstyleConfigurationPath } from '../utils/settingUtils';
import { findNonIgnoredFiles, getDefaultWorkspaceFolder, tryUseWorkspaceFolder } from '../utils/workspaceUtils';

export async function setConfiguration(uri?: Uri): Promise<void> {
if (uri) {
Expand Down Expand Up @@ -89,7 +90,7 @@ async function inputConfiguration(): Promise<string | undefined> {

async function detectConfigurations(): Promise<IQuickPickItemEx[]> {
const detected: IQuickPickItemEx[] = [];
for (const xml of await workspace.findFiles('**/*.xml')) {
for (const xml of await findNonIgnoredFiles('**/*.xml')) {
const relativeXml: string = tryUseWorkspaceFolder(xml.fsPath);
function doctypeFn(doctype: string): void {
const [name, type] = doctype.split(/\s+/, 2);
Expand Down
45 changes: 2 additions & 43 deletions src/utils/settingUtils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Copyright (c) jdneo. All rights reserved.
// Licensed under the GNU LGPLv3 license.

import * as path from 'path';
import { ConfigurationTarget, Uri, window, workspace, WorkspaceConfiguration, WorkspaceFolder } from 'vscode';
import { ConfigurationTarget, Uri, window, workspace, WorkspaceConfiguration } from 'vscode';
import { JAVA_CHECKSTYLE_AUTOCHECK, JAVA_CHECKSTYLE_CONFIGURATION, JAVA_CHECKSTYLE_PROPERTIES, JAVA_CHECKSTYLE_VERSION } from '../constants/settings';
import { resolveVariables } from './workspaceUtils';

export function setCheckstyleConfigurationPath(fsPath: string, uri?: Uri): void {
setConfiguration(JAVA_CHECKSTYLE_CONFIGURATION, fsPath, uri);
Expand Down Expand Up @@ -31,34 +31,10 @@ export function getCheckstyleProperties(uri?: Uri): object {
return properties;
}

export function getDefaultWorkspaceFolder(): WorkspaceFolder | undefined {
const workspaceFolders: WorkspaceFolder[] | undefined = workspace.workspaceFolders;
if (workspaceFolders === undefined) {
return undefined;
}
if (workspaceFolders.length === 1) {
return workspaceFolders[0];
}
if (window.activeTextEditor) {
const activeWorkspaceFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(window.activeTextEditor.document.uri);
return activeWorkspaceFolder;
}
return undefined;
}

export function isAutoCheckEnabled(): boolean {
return getConfiguration().get<boolean>(JAVA_CHECKSTYLE_AUTOCHECK, true);
}

export function tryUseWorkspaceFolder(fsPath: string): string {
const result: string = workspace.asRelativePath(fsPath);
if (result === fsPath) {
return result;
} else {
return path.join('${workspaceFolder}', result);
}
}

export function getConfiguration(uri?: Uri): WorkspaceConfiguration {
return workspace.getConfiguration(undefined, uri || null);
}
Expand All @@ -69,20 +45,3 @@ function setConfiguration(section: string, value: any, uri?: Uri): void {
}
getConfiguration(uri).update(section, value, ConfigurationTarget.WorkspaceFolder);
}

const workspaceRegexp: RegExp = /\$\{workspacefolder\}/i;
function resolveVariables(value: string, resourceUri?: Uri): string {
let workspaceFolder: WorkspaceFolder | undefined;
if (resourceUri) {
workspaceFolder = workspace.getWorkspaceFolder(resourceUri);
} else {
workspaceFolder = getDefaultWorkspaceFolder();
}
if (workspaceRegexp.test(value)) {
if (!workspaceFolder) {
throw new Error('No workspace folder is opened in current VS Code workspace when resolving ${workspaceFolder}');
}
return value.replace(workspaceRegexp, workspaceFolder.uri.fsPath);
}
return value;
}
87 changes: 87 additions & 0 deletions src/utils/workspaceUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) jdneo. All rights reserved.
// Licensed under the GNU LGPLv3 license.

import * as cp from 'child_process';
import * as _ from 'lodash';
import * as path from 'path';
import { Uri, window, workspace, WorkspaceFolder } from 'vscode';
import { checkstyleChannel } from '../checkstyleChannel';

export function getDefaultWorkspaceFolder(): WorkspaceFolder | undefined {
const workspaceFolders: WorkspaceFolder[] | undefined = workspace.workspaceFolders;
if (workspaceFolders === undefined) {
return undefined;
}
if (workspaceFolders.length === 1) {
return workspaceFolders[0];
}
if (window.activeTextEditor) {
const activeWorkspaceFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(window.activeTextEditor.document.uri);
return activeWorkspaceFolder;
}
return undefined;
}

export function tryUseWorkspaceFolder(fsPath: string): string {
const result: string = workspace.asRelativePath(fsPath);
if (result === fsPath) {
return result;
} else {
return path.join('${workspaceFolder}', result);
}
}

const workspaceRegexp: RegExp = /\$\{workspacefolder\}/i;

export function resolveVariables(value: string, resourceUri?: Uri): string {
let workspaceFolder: WorkspaceFolder | undefined;
if (resourceUri) {
workspaceFolder = workspace.getWorkspaceFolder(resourceUri);
} else {
workspaceFolder = getDefaultWorkspaceFolder();
}
if (workspaceRegexp.test(value)) {
if (!workspaceFolder) {
throw Error('No workspace folder is opened in current VS Code workspace when resolving ${workspaceFolder}');
}
return value.replace(workspaceRegexp, workspaceFolder.uri.fsPath);
}
return value;
}

// workspace.findFiles only defaults to exclude entires in files.exclude
// so it is not even able to exclude node_modules
// Refer to: https://github.com/Microsoft/vscode/issues/48674
export async function findNonIgnoredFiles(pattern: string): Promise<Uri[]> {
let uris: Uri[] = await workspace.findFiles(pattern, `{${[
...Object.keys(await workspace.getConfiguration('search', null).get('exclude') || {}),
...Object.keys(await workspace.getConfiguration('files', null).get('exclude') || {}),
].join(',')}}`);

const workspaceFolder: WorkspaceFolder | undefined = getDefaultWorkspaceFolder();
if (workspaceFolder) {
try { // tslint:disable-next-line: typedef
const result: string = await new Promise<string>((resolve, reject) => {
cp.exec(`git check-ignore ${uris.map((uri: Uri) => workspace.asRelativePath(uri)).join(' ')}`, {
cwd: workspaceFolder.uri.fsPath,
}, (error: Error & { code?: 0 | 1 | 128 }, stdout: string, stderr: string) => {
if (error && (error.code !== 0 && error.code !== 1)) {
reject(error);
} else if (stderr) {
reject(new Error(stderr));
} else {
resolve(stdout);
}
});
});
const excludes: Uri[] = result.trim().split('\n').map((relativePath: string) => {
return Uri.file(path.join(workspaceFolder.uri.fsPath, relativePath.replace(/"(.+)"/, '$1')));
});
uris = _.differenceBy(uris, excludes, 'fsPath');
} catch (error) {
checkstyleChannel.appendLine(`git check-ignore exec error: ${error.toString()}`);
}
}

return uris;
}