Skip to content

Commit 3602974

Browse files
authoredSep 27, 2024··
✨ Extension Configuration (#32)
This PR makes the essential bits of our extension configurable in a VSCode native way. We now provide: 1. Configuration, which means the user can modify the configuration like any other extension in the application settings view. 1. Walkthroughs, that step the user through the different things that can be configured and how. 1. Some basic commands for configuring in a more hand-holding kind of way (filepicker for analyzer, picker for sources/targets, dialog to useDefaultRulesets). We leave the runAnalyzer piece unimplemented for now as that will come when it actually exists. Fixes #4 Fixes #5 Signed-off-by: David Zager <[email protected]>
1 parent a87c734 commit 3602974

File tree

7 files changed

+497
-1
lines changed

7 files changed

+497
-1
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Analysis Arguments
2+
==================
3+
4+
The mechanism we use to configure which rules apply to the project during analysis is the labelSelector.
5+
6+
There are two ways to configure the labelSelector:
7+
8+
1. Using the [Konveyor: Configure Analysis Sources and Targets](command:konveyor.configureSourcesTargets) from the command palette.
9+
2. Using the [Konveyor: Configure Analysis Label Selector](command:konveyor.configureLabelSelector) from the command palette.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Custom Rules
2+
============
3+
4+
The Konveyor extension allows you to add custom rules to the analyzer. This is useful if you want to add your own rules to the analyzer.
5+
6+
To add a custom rule, run the [Konveyor: Configure Custom Rules](command:konveyor.configureCustomRules) command.
7+
8+
This will open a file dialog to select the file(s) to add as a custom rule(s).
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Override Analyzer Binary
2+
========================
3+
4+
The Konveyor extension comes packaged with a default analyzer binary. However,
5+
you may want to use a custom or updated version of the analyzer.
6+
7+
To override the default analyzer run the [Konveyor: Override Analyzer Binaries](command:konveyor.overrideAnalyzerBinaries) command.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Start Analyzer
2+
==============
3+
4+
Not yet implemented.

‎vscode/package.json

+153-1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,30 @@
4545
"command": "konveyor.startAnalysis",
4646
"title": "Start Analysis",
4747
"category": "Konveyor"
48+
},
49+
{
50+
"command": "konveyor.overrideAnalyzerBinaries",
51+
"title": "Override Analyzer Binaries",
52+
"category": "Konveyor",
53+
"icon": "$(gear)"
54+
},
55+
{
56+
"command": "konveyor.configureCustomRules",
57+
"title": "Configure Custom Rules",
58+
"category": "Konveyor",
59+
"icon": "$(gear)"
60+
},
61+
{
62+
"command": "konveyor.configureSourcesTargets",
63+
"title": "Configure Analysis Sources and Targets",
64+
"category": "Konveyor",
65+
"icon": "$(gear)"
66+
},
67+
{
68+
"command": "konveyor.configureLabelSelector",
69+
"title": "Configure Analysis LabelSelector",
70+
"category": "Konveyor",
71+
"icon": "$(gear)"
4872
}
4973
],
5074
"submenus": [
@@ -103,7 +127,135 @@
103127
"group": "navigation@1"
104128
}
105129
]
106-
}
130+
},
131+
"configuration": {
132+
"type": "object",
133+
"title": "Konveyor",
134+
"properties": {
135+
"konveyor.analyzerPath": {
136+
"type": "string",
137+
"default": "",
138+
"description": "Path to the analyzer binary. If not set, the extension will use the bundled analyzer.",
139+
"scope": "machine",
140+
"order": 0
141+
},
142+
"konveyor.incidentLimit": {
143+
"type": "number",
144+
"default": 10000,
145+
"description": "Maximum number of incidents to report",
146+
"scope": "window",
147+
"order": 1
148+
},
149+
"konveyor.contextLines": {
150+
"type": "number",
151+
"default": 10,
152+
"description": "Number of lines of context to include in incident reports",
153+
"scope": "window",
154+
"order": 2
155+
},
156+
"konveyor.codeSnipLimit": {
157+
"type": "number",
158+
"default": 10,
159+
"description": "Number of lines of code to include in incident reports",
160+
"scope": "window",
161+
"order": 3
162+
},
163+
"konveyor.useDefaultRulesets": {
164+
"type": "boolean",
165+
"default": true,
166+
"description": "Whether analysis should use the default rulesets, included in the extension",
167+
"scope": "window",
168+
"order": 4
169+
},
170+
"konveyor.customRules": {
171+
"type": "array",
172+
"items": {
173+
"type": "string"
174+
},
175+
"default": [],
176+
"description": "Array of filepaths to additional rules for analysis",
177+
"scope": "window",
178+
"order": 5
179+
},
180+
"konveyor.labelSelector": {
181+
"type": "string",
182+
"default": "discovery",
183+
"description": "Expression to select incidents based on custom variables. Example: (!package=io.konveyor.demo.config-utils)",
184+
"scope": "window",
185+
"order": 6
186+
},
187+
"konveyor.analyzeKnownLibraries": {
188+
"type": "boolean",
189+
"default": false,
190+
"description": "Whether analysis should include known open-source libraries",
191+
"scope": "window",
192+
"order": 7
193+
},
194+
"konveyor.analyzeDependencies": {
195+
"type": "boolean",
196+
"default": true,
197+
"description": "Whether analysis should include dependencies",
198+
"scope": "window",
199+
"order": 8
200+
},
201+
"konveyor.analyzeOnSave": {
202+
"type": "boolean",
203+
"default": true,
204+
"description": "Whether analysis of file should be run when saved",
205+
"scope": "window",
206+
"order": 9
207+
}
208+
}
209+
},
210+
"walkthroughs": [
211+
{
212+
"id": "konveyor-setup",
213+
"title": "Set up Konveyor",
214+
"description": "Configure Konveyor for your project",
215+
"steps": [
216+
{
217+
"id": "override-analyzer",
218+
"title": "Override Analyzer Binary",
219+
"description": "Specify a custom path for the analyzer binary\n[Override Analyzer Binary](command:konveyor.overrideAnalyzerBinaries)",
220+
221+
"completionEvents": [],
222+
"media": {
223+
"markdown": "media/walkthroughs/override-analyzer.md"
224+
}
225+
},
226+
{
227+
"id": "configure-custom-rules",
228+
"title": "Configure Custom Rules",
229+
"description": "Add custom rules for analysis\n[Configure Custom Rules](command:konveyor.configureCustomRules)",
230+
"completionEvents": ["onCommand:konveyor.configureCustomRules"],
231+
"media": {
232+
"markdown": "media/walkthroughs/custom-rules.md"
233+
}
234+
},
235+
{
236+
"id": "configure-analysis-arguments",
237+
"title": "Configure Analysis Arguments",
238+
"description": "Set up analysis arguments such as sources, targets, and label selector\n[Configure Analysis Sources and Targets](command:konveyor.configureSourcesTargets)\n[Configure Analysis Label Selector](command:konveyor.configureLabelSelector)",
239+
"completionEvents": [
240+
"onCommand:konveyor.configureSourcesTargets",
241+
"onCommand:konveyor.configureLabelSelector"
242+
],
243+
"media": {
244+
"markdown": "media/walkthroughs/analysis-arguments.md"
245+
}
246+
},
247+
{
248+
"id": "start-analyzer",
249+
"title": "Start Analyzer",
250+
"description": "Start the analyzer",
251+
"completionEvents": [],
252+
"media": {
253+
"markdown": "media/walkthroughs/start-analyzer.md"
254+
}
255+
}
256+
]
257+
}
258+
]
107259
},
108260
"scripts": {
109261
"vscode:prepublish": "npm run package",

‎vscode/src/commands.ts

+172
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { KonveyorGUIWebviewViewProvider } from "./KonveyorGUIWebviewViewProvider
33
import { setupWebviewMessageListener } from "./webviewMessageHandler";
44
import { ExtensionState } from "./extensionState";
55
import { getWebviewContent } from "./webviewContent";
6+
import { sourceOptions, targetOptions } from "./config/labels";
67

78
let fullScreenPanel: vscode.WebviewPanel | undefined;
89

@@ -107,6 +108,177 @@ const commandsMap: (
107108
extensionContext.subscriptions,
108109
);
109110
},
111+
"konveyor.overrideAnalyzerBinaries": async () => {
112+
const options: vscode.OpenDialogOptions = {
113+
canSelectMany: false,
114+
openLabel: 'Select Analyzer Binary',
115+
filters: {
116+
'Executable Files': ['exe', 'sh', 'bat', ''],
117+
'All Files': ['*']
118+
}
119+
};
120+
121+
const fileUri = await vscode.window.showOpenDialog(options);
122+
123+
if (fileUri && fileUri[0]) {
124+
const filePath = fileUri[0].fsPath;
125+
126+
// Update the user settings
127+
const config = vscode.workspace.getConfiguration('konveyor');
128+
await config.update('analyzerPath', filePath, vscode.ConfigurationTarget.Global);
129+
130+
vscode.window.showInformationMessage(`Analyzer binary path updated to: ${filePath}`);
131+
} else {
132+
vscode.window.showInformationMessage('No analyzer binary selected.');
133+
}
134+
},
135+
"konveyor.configureCustomRules": async () => {
136+
const options: vscode.OpenDialogOptions = {
137+
canSelectMany: true,
138+
canSelectFolders: true,
139+
canSelectFiles: true,
140+
openLabel: 'Select Custom Rules',
141+
filters: {
142+
'All Files': ['*']
143+
}
144+
};
145+
146+
const fileUris = await vscode.window.showOpenDialog(options);
147+
148+
if (fileUris && fileUris.length > 0) {
149+
const customRules = fileUris.map((uri) => uri.fsPath);
150+
151+
// TODO(djzager): Should we verify the rules provided are valid?
152+
153+
// Update the user settings
154+
const config = vscode.workspace.getConfiguration('konveyor');
155+
await config.update('customRules', customRules, vscode.ConfigurationTarget.Workspace);
156+
157+
// Ask the user if they want to disable the default ruleset
158+
const useDefaultRulesets = await vscode.window.showQuickPick(
159+
['Yes', 'No'],
160+
{
161+
placeHolder: 'Do you want to use the default rulesets?',
162+
canPickMany: false
163+
}
164+
);
165+
166+
if (useDefaultRulesets === 'Yes') {
167+
await config.update('useDefaultRulesets', true, vscode.ConfigurationTarget.Workspace);
168+
} else if (useDefaultRulesets === 'No') {
169+
await config.update('useDefaultRulesets', false, vscode.ConfigurationTarget.Workspace);
170+
}
171+
172+
vscode.window.showInformationMessage(`Custom Rules Updated: ${customRules}\nUse Default Rulesets: ${useDefaultRulesets}`);
173+
} else {
174+
vscode.window.showInformationMessage('No custom rules selected.');
175+
}
176+
},
177+
"konveyor.configureSourcesTargets": async() => {
178+
const config = vscode.workspace.getConfiguration('konveyor');
179+
const currentLabelSelector = config.get<string>('labelSelector', '');
180+
181+
// Function to extract values from label selector
182+
const extractValuesFromSelector = (selector: string, key: string): string[] => {
183+
const regex = new RegExp(`konveyor.io/${key}=(.*?)(?:\\s|$)`, 'g');
184+
const matches = selector.matchAll(regex);
185+
const values = Array.from(matches, match => match[1]);
186+
return values.flatMap(value => value.split('|'));
187+
};
188+
189+
// Extract sources and targets from the current label selector
190+
const currentSources = extractValuesFromSelector(currentLabelSelector, 'source');
191+
const currentTargets = extractValuesFromSelector(currentLabelSelector, 'target');
192+
193+
const state: { sources: string[]; targets: string[]; labelSelector: string } = { sources: [], targets: [], labelSelector: '' };
194+
195+
// Function to show QuickPick for sources and targets
196+
const showQuickPick = async (title: string, placeholder: string, items: string[], selectedItems: string[]): Promise<string[] | undefined> => {
197+
const result = await vscode.window.showQuickPick(
198+
items.map(item => ({
199+
label: item,
200+
picked: selectedItems.includes(item)
201+
})),
202+
{
203+
canPickMany: true,
204+
placeHolder: placeholder,
205+
title: title
206+
}
207+
);
208+
if (result === undefined) {
209+
return undefined;
210+
}
211+
return result.map(item => item.label);
212+
};
213+
214+
// Show QuickPick for sources
215+
const selectedSources = await showQuickPick(
216+
'Select Source Technologies',
217+
'Choose one or more source technologies',
218+
sourceOptions,
219+
currentSources
220+
);
221+
if (selectedSources === undefined) {
222+
return;
223+
}
224+
state.sources = selectedSources;
225+
226+
// Show QuickPick for targets
227+
const selectedTargets = await showQuickPick(
228+
'Select Target Technologies',
229+
'Choose one or more target technologies',
230+
targetOptions,
231+
currentTargets
232+
);
233+
if (selectedTargets === undefined) {
234+
return;
235+
}
236+
state.targets = selectedTargets;
237+
238+
// Compute initial label selector
239+
const sources = state.sources.map(source => `konveyor.io/source=${source}`).join(' || ');
240+
const targets = state.targets.map(target => `konveyor.io/target=${target}`).join(' || ');
241+
if (sources === "" && targets === "") {
242+
vscode.window.showInformationMessage("No sources or targets selected.");
243+
return;
244+
}
245+
246+
state.labelSelector = `(${[sources, targets].filter(part => part !== "").join(' && ')}) || (discovery)`;
247+
248+
// Show input box for modifying label selector
249+
const modifiedLabelSelector = await vscode.window.showInputBox({
250+
prompt: 'Modify the label selector if needed',
251+
value: state.labelSelector,
252+
placeHolder: 'e.g., source=(java|spring) target=(quarkus)'
253+
});
254+
255+
if (modifiedLabelSelector === undefined) {
256+
return;
257+
}
258+
state.labelSelector = modifiedLabelSelector;
259+
260+
// Update the user settings
261+
await config.update('labelSelector', state.labelSelector, vscode.ConfigurationTarget.Workspace);
262+
263+
vscode.window.showInformationMessage(`Configuration updated: Sources: ${state.sources.join(', ')}, Targets: ${state.targets.join(', ')}, Label Selector: ${state.labelSelector}`);
264+
},
265+
"konveyor.configureLabelSelector": async () => {
266+
const config = vscode.workspace.getConfiguration('konveyor');
267+
const currentLabelSelector = config.get<string>('labelSelector', '');
268+
269+
const modifiedLabelSelector = await vscode.window.showInputBox({
270+
prompt: 'Modify the label selector if needed',
271+
value: currentLabelSelector,
272+
placeHolder: 'e.g., source=(java|spring) target=(quarkus)'
273+
});
274+
275+
if (modifiedLabelSelector === undefined) {
276+
return;
277+
}
278+
279+
// Update the user settings
280+
await config.update('labelSelector', modifiedLabelSelector, vscode.ConfigurationTarget.Workspace);
281+
},
110282
};
111283
};
112284

‎vscode/src/config/labels.ts

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
export const sourceOptions = [
2+
"azure-aks",
3+
"azure-appservice",
4+
"azure-container-apps",
5+
"azure-spring-apps",
6+
"camel",
7+
"camel2",
8+
"camel3",
9+
"camel3.1",
10+
"camel3.10",
11+
"camel3.11",
12+
"camel3.12",
13+
"camel3.13",
14+
"camel3.14",
15+
"camel3.15",
16+
"camel3.16",
17+
"camel3.17",
18+
"camel3.18",
19+
"camel3.19",
20+
"camel3.2",
21+
"camel3.20",
22+
"camel3.21",
23+
"camel3.3",
24+
"camel3.4",
25+
"camel3.5",
26+
"camel3.6",
27+
"camel3.7",
28+
"camel3.8",
29+
"camel3.9",
30+
"camel4",
31+
"camel4.1",
32+
"cloud-readiness",
33+
"discovery",
34+
"drools",
35+
"drools6",
36+
"eap",
37+
"eap6",
38+
"eap7",
39+
"eap7.1",
40+
"eap8",
41+
"eapxp",
42+
"eapxp2",
43+
"eapxp3",
44+
"eapxp5",
45+
"fsw",
46+
"fsw6",
47+
"fuse",
48+
"fuse6",
49+
"hibernate",
50+
"hibernate-search",
51+
"hibernate-search5",
52+
"hibernate4",
53+
"hibernate5",
54+
"hibernate5.1",
55+
"hibernate5.3",
56+
"hibernate6",
57+
"hibernate6.1",
58+
"hibernate6.2",
59+
"jakarta-ee",
60+
"jakarta-ee8",
61+
"jakarta-ee9",
62+
"java-ee",
63+
"java-ee6",
64+
"java-ee7",
65+
"jbpm",
66+
"jbpm6",
67+
"jws",
68+
"jws6",
69+
"linux",
70+
"openjdk",
71+
"openjdk11",
72+
"openjdk17",
73+
"openjdk18",
74+
"openjdk19",
75+
"openjdk20",
76+
"openjdk21",
77+
"openjdk7",
78+
"openliberty",
79+
"quarkus",
80+
"quarkus3",
81+
"resteasy",
82+
"resteasy3",
83+
"rhr",
84+
];
85+
86+
export const targetOptions = [
87+
"camel",
88+
"camel2",
89+
"camel3",
90+
"drools",
91+
"drools5",
92+
"eap",
93+
"eap4",
94+
"eap5",
95+
"eap6",
96+
"eap7",
97+
"eap7.0",
98+
"eap7.1",
99+
"eapxp",
100+
"glassfish",
101+
"hibernate",
102+
"hibernate-search",
103+
"hibernate-search4",
104+
"hibernate3.9",
105+
"hibernate4",
106+
"hibernate5.0",
107+
"hibernate5.1",
108+
"jakarta-ee",
109+
"jakarta-ee7",
110+
"java",
111+
"java-ee",
112+
"javaee",
113+
"jbpm",
114+
"jbpm5",
115+
"jonas",
116+
"jrun",
117+
"log4j",
118+
"openjdk",
119+
"openjdk11",
120+
"openjdk18",
121+
"openjdk19",
122+
"openjdk20",
123+
"openjdk21",
124+
"openjdk8",
125+
"oraclejdk",
126+
"oraclejdk7",
127+
"orion",
128+
"resin",
129+
"resteasy",
130+
"resteasy2",
131+
"rmi",
132+
"rpc",
133+
"seam",
134+
"seam2",
135+
"soa",
136+
"soa-p",
137+
"soa-p5",
138+
"sonic",
139+
"sonicesb",
140+
"springboot",
141+
"thorntail",
142+
"weblogic",
143+
"websphere",
144+
];

0 commit comments

Comments
 (0)
Please sign in to comment.