Skip to content

Commit 63b43de

Browse files
authored
feat: support exclude patterns to ignore paths (#803)
1 parent 10db1ba commit 63b43de

File tree

12 files changed

+140
-55
lines changed

12 files changed

+140
-55
lines changed

.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ cico_build_deploy.sh
2222
coverage/**
2323
Jenkinsfile
2424
out
25+
docker-compose.yaml

README.md

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,33 +92,34 @@ The Red Hat Dependency Analytics extension has some configurable parameters that
9292

9393
### Configurable parameters
9494

95-
**Red Hat Dependency Analytics Report File Path** :
96-
<br >Specify the local path to create the Red Hat Dependency Analytics report file.
95+
#### Red Hat Dependency Analytics Report File Path:
96+
Specify the local path to create the Red Hat Dependency Analytics report file.
9797
The default path is `/tmp/redhatDependencyAnalyticsReport.html`.
9898

99-
<br >**IMPORTANT:**
100-
<br >The `redHatDependencyAnalyticsReportFilePath` setting name has changed to `reportFilePath`.
99+
**IMPORTANT:**
101100

102-
**Inline Vulnerability Severity Alerts** :
103-
<br >You can set the vulnerability severity alert level to `Error` or `Warning` for inline notifications of detected vulnerabilities.
101+
The `redHatDependencyAnalyticsReportFilePath` setting name has changed to `reportFilePath`.
104102

105-
**Python** :
103+
#### Inline Vulnerability Severity Alerts:
104+
You can set the vulnerability severity alert level to `Error` or `Warning` for inline notifications of detected vulnerabilities.
105+
106+
#### Python:
106107
* `usePythonVirtualEnvironment` : Automates the installation of missing packages in a Python virtual environment.
107108
* `enablePythonBestEffortsInstallation` : Installs Python packages for the Python version is use, disregarding declared versions.
108109
This configuration option requires the _Match Manifest Versions_ option set to `false`, and _Use Python Virtual Environment_ option set to `true`.
109110
* `usePipDepTree` : Use the `pipdeptree` command-line tool for building the Python dependency tree.
110111
This can enhance analysis time.
111112

112-
**Golang** :
113+
#### Golang:
113114
* `useGoMVS` : Use the minimal version selection algorithm to select a set of module versions to use when building Go packages.
114115

115-
**HTTP Proxy** :
116+
#### HTTP Proxy:
116117
* `httpProxy` : Configure HTTP proxy settings for the extension. There are three options available:
117118
- `on`: Always use the HTTP proxy regardless of VS Code's proxy settings
118119
- `off`: Never use the HTTP proxy regardless of VS Code's proxy settings
119120
- `fallback`: Use VS Code's proxy settings (default behavior)
120121

121-
**Maven and Gradle Wrappers** :
122+
#### Maven and Gradle Wrappers:
122123
* `preferWrapper` : Configure whether to use Maven or Gradle wrappers. There are three options available:
123124
- `true`: Always use the wrapper regardless of VS Code's `maven.preferMavenWrapper` setting
124125
- `false`: Never use the wrapper regardless of VS Code's `maven.preferMavenWrapper` setting
@@ -130,11 +131,16 @@ The default path is `/tmp/redhatDependencyAnalyticsReport.html`.
130131
"preferWrapper": "true/false/fallback"
131132
},
132133
"gradle": {
133-
preferWrapper": "true/false/fallback"
134+
"preferWrapper": "true/false/fallback"
134135
}
135136
}
136137
```
137138

139+
#### Exclude manifests from analysis:
140+
Specify glob patterns for manifests to be ignored for background analysis e.g. `**/test/**/package.json` will ignore all package.json files within `test/` or any subdirectories of it.
141+
142+
**NOTE:** Only forward slash (`/`) is supported as a path separator. Please use forward slash as the path separator even for Windows paths.
143+
138144
## Features
139145

140146
- **Component analysis**

package-lock.json

Lines changed: 43 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,16 +188,6 @@
188188
"markdownDescription": "Enable usage data and errors to be sent to Red Hat servers. Read our [privacy statement](https://developers.redhat.com/article/tool-data-collection).",
189189
"scope": "window"
190190
},
191-
"redHatDependencyAnalyticsServer.trace.server": {
192-
"type": "string",
193-
"enum": [
194-
"off",
195-
"messages",
196-
"verbose"
197-
],
198-
"default": "off",
199-
"description": "Traces the communication between VSCode and the Red Hat Dependency Analytics Language Server."
200-
},
201191
"redHatDependencyAnalytics.matchManifestVersions": {
202192
"type": "boolean",
203193
"default": true,
@@ -376,7 +366,14 @@
376366
"redHatDependencyAnalytics.recommendations.enabled": {
377367
"type": "boolean",
378368
"default": true,
379-
"description": "Toggles recommending Red Hat repositories"
369+
"description": "Toggles recommending Red Hat repositories."
370+
},
371+
"redHatDependencyAnalytics.exclude": {
372+
"type": "array",
373+
"items": {
374+
"type": "string"
375+
},
376+
"description": "List of path globs for manifests to ignore for analysis. Only forward slash is support as a path separator."
380377
}
381378
}
382379
}
@@ -434,6 +431,7 @@
434431
"@xml-tools/parser": "^1.0.11",
435432
"fs": "^0.0.1-security",
436433
"json-to-ast": "^2.1.0",
434+
"minimatch": "^10.0.3",
437435
"path": "^0.12.7"
438436
}
439437
}

src/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as vscode from 'vscode';
55
import { GlobalState, DEFAULT_RHDA_REPORT_FILE_PATH, SNYK_TOKEN_KEY } from './constants';
66
import * as commands from './commands';
77
import { getTelemetryId } from './redhatTelemetry';
8+
import { Minimatch } from 'minimatch';
89

910
/**
1011
* Represents the configuration settings for the extension.
@@ -44,6 +45,7 @@ class Config {
4445
exhortDockerPath!: string;
4546
exhortPodmanPath!: string;
4647
exhortImagePlatform!: string;
48+
excludePatterns!: Minimatch[];
4749

4850
private readonly DEFAULT_MVN_EXECUTABLE = 'mvn';
4951
private readonly DEFAULT_GRADLE_EXECUTABLE = 'gradle';
@@ -129,6 +131,7 @@ class Config {
129131
this.exhortDockerPath = rhdaConfig.docker.executable.path || this.DEFAULT_DOCKER_EXECUTABLE;
130132
this.exhortPodmanPath = rhdaConfig.podman.executable.path || this.DEFAULT_PODMAN_EXECUTABLE;
131133
this.exhortImagePlatform = rhdaConfig.imagePlatform;
134+
this.excludePatterns = (rhdaConfig.exclude as string[]).map(pattern => new Minimatch(pattern));
132135
}
133136

134137
private getEffectiveHttpProxyUrl(): string {

src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ export async function activate(context: vscode.ExtensionContext) {
4040
}()));
4141

4242
const fileHandler = new AnalysisMatcher();
43-
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument((doc) => fileHandler.handle(doc)));
43+
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument((doc) => fileHandler.handle(doc, outputChannelDep)));
4444
// Anecdotaly, some extension(s) may cause did-open events for files that aren't actually open in the editor,
4545
// so this will trigger CA for files not actually open.
46-
context.subscriptions.push(vscode.workspace.onDidOpenTextDocument((doc) => fileHandler.handle(doc)));
46+
context.subscriptions.push(vscode.workspace.onDidOpenTextDocument((doc) => fileHandler.handle(doc, outputChannelDep)));
4747
context.subscriptions.push(vscode.workspace.onDidCloseTextDocument(doc => clearCodeActionsMap(doc.uri)));
4848
// Iterate all open docs, as there is (in general) no did-open event for these.
4949
for (const doc of vscode.workspace.textDocuments) {
50-
fileHandler.handle(doc);
50+
fileHandler.handle(doc, outputChannelDep);
5151
}
5252

5353
// show welcome message after first install or upgrade

src/fileHandler.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { DependencyProvider as GoMod } from './providers/go.mod';
88
import { DependencyProvider as RequirementsTxt } from './providers/requirements.txt';
99
import { DependencyProvider as BuildGradle } from './providers/build.gradle';
1010
import { ImageProvider as Docker } from './providers/docker';
11-
import { outputChannelDep } from './extension';
11+
import { globalConfig } from './config';
12+
import { DepOutputChannel } from './depOutputChannel';
1213

1314
export class AnalysisMatcher {
1415
matchers: Array<{ scheme: string, pattern: RegExp, callback: (path: Uri, contents: string) => Promise<void> }> = [
@@ -44,12 +45,17 @@ export class AnalysisMatcher {
4445
}
4546
];
4647

47-
async handle(doc: TextDocument) {
48+
async handle(doc: TextDocument, outputChannel: DepOutputChannel) {
49+
const excludeMatch = globalConfig.excludePatterns.find(pattern => pattern.match(doc.uri.fsPath));
50+
if (excludeMatch) {
51+
outputChannel.debug(`skipping "${doc.uri.fsPath}" due to matching ${excludeMatch.pattern}`);
52+
return;
53+
}
4854
for (const matcher of this.matchers) {
4955
if (matcher.pattern.test(basename(doc.fileName))) {
50-
outputChannelDep.info(`generating component analysis diagnostics for "${doc.fileName}"`);
56+
outputChannel.info(`generating component analysis diagnostics for "${doc.fileName}"`);
5157
await matcher.callback(doc.uri, doc.getText());
52-
outputChannelDep.info(`done generating component analysis diagnostics for "${doc.fileName}"`);
58+
outputChannel.info(`done generating component analysis diagnostics for "${doc.fileName}"`);
5359
}
5460
}
5561
}

test/extension.test.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
/* eslint-disable @typescript-eslint/no-unused-expressions */
12
import * as assert from 'assert';
23
import * as vscode from 'vscode';
34

45
import * as commands from '../src/commands';
6+
import * as chai from 'chai';
7+
import * as sinonChai from 'sinon-chai';
8+
9+
const expect = chai.expect;
10+
chai.use(sinonChai);
511

612
suite('Extension module', () => {
713
test('Extension should be present', () => {
@@ -25,7 +31,6 @@ suite('Extension module', () => {
2531
commands.STACK_ANALYSIS_FROM_PIE_BTN_COMMAND,
2632
commands.STACK_ANALYSIS_FROM_STATUS_BAR_COMMAND
2733
];
28-
// @ts-expect-error
29-
assert.ok((await vscode.commands.getCommands(true)).includes(...FABRIC8_COMMANDS));
34+
expect((await vscode.commands.getCommands(true))).to.include.members(FABRIC8_COMMANDS);
3035
});
31-
});
36+
});

test/fileHandler.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* eslint-disable @typescript-eslint/no-unused-expressions */
2+
import * as vscode from 'vscode';
3+
4+
import * as chai from 'chai';
5+
import * as sinon from 'sinon';
6+
import * as sinonChai from 'sinon-chai';
7+
import { AnalysisMatcher } from '../src/fileHandler';
8+
import { DepOutputChannel } from '../src/depOutputChannel';
9+
import * as path from 'path';
10+
11+
const expect = chai.expect;
12+
chai.use(sinonChai);
13+
14+
suite('File Handler', () => {
15+
let sandbox: sinon.SinonSandbox;
16+
17+
setup(() => {
18+
sandbox = sinon.createSandbox();
19+
});
20+
21+
teardown(() => {
22+
sandbox.restore();
23+
});
24+
test('test file handler exclusion', async () => {
25+
const fileHandler = new AnalysisMatcher();
26+
27+
vscode.workspace.getConfiguration('redHatDependencyAnalytics').update('exclude', ['**/requirements.txt']);
28+
29+
const manifestFile = path.resolve(vscode.workspace.workspaceFolders![0].uri.fsPath, 'requirements.txt');
30+
const doc = await vscode.workspace.openTextDocument(manifestFile);
31+
32+
const outputChannel = new DepOutputChannel('sample');
33+
const debuglogSpy = sandbox.stub(outputChannel, 'debug');
34+
35+
await fileHandler.handle(doc, outputChannel);
36+
37+
expect(debuglogSpy).to.be.calledOnce;
38+
expect(debuglogSpy).to.be.calledWithExactly(`skipping "${manifestFile}" due to matching **/requirements.txt`);
39+
});
40+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"redHatDependencyAnalytics.exclude": [
3+
"**/requirements.txt"
4+
]
5+
}

0 commit comments

Comments
 (0)