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

✨ Extension Configuration #32

Merged
merged 1 commit into from
Sep 27, 2024
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
9 changes: 9 additions & 0 deletions vscode/media/walkthroughs/analysis-arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Analysis Arguments
==================

The mechanism we use to configure which rules apply to the project during analysis is the labelSelector.

There are two ways to configure the labelSelector:

1. Using the [Konveyor: Configure Analysis Sources and Targets](command:konveyor.configureSourcesTargets) from the command palette.
2. Using the [Konveyor: Configure Analysis Label Selector](command:konveyor.configureLabelSelector) from the command palette.
8 changes: 8 additions & 0 deletions vscode/media/walkthroughs/custom-rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Custom Rules
============

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.

To add a custom rule, run the [Konveyor: Configure Custom Rules](command:konveyor.configureCustomRules) command.

This will open a file dialog to select the file(s) to add as a custom rule(s).
7 changes: 7 additions & 0 deletions vscode/media/walkthroughs/override-analyzer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Override Analyzer Binary
========================

The Konveyor extension comes packaged with a default analyzer binary. However,
you may want to use a custom or updated version of the analyzer.

To override the default analyzer run the [Konveyor: Override Analyzer Binaries](command:konveyor.overrideAnalyzerBinaries) command.
4 changes: 4 additions & 0 deletions vscode/media/walkthroughs/start-analyzer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Start Analyzer
==============

Not yet implemented.
154 changes: 153 additions & 1 deletion vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,30 @@
"command": "konveyor.startAnalysis",
"title": "Start Analysis",
"category": "Konveyor"
},
{
"command": "konveyor.overrideAnalyzerBinaries",
"title": "Override Analyzer Binaries",
"category": "Konveyor",
"icon": "$(gear)"
},
{
"command": "konveyor.configureCustomRules",
"title": "Configure Custom Rules",
"category": "Konveyor",
"icon": "$(gear)"
},
{
"command": "konveyor.configureSourcesTargets",
"title": "Configure Analysis Sources and Targets",
"category": "Konveyor",
"icon": "$(gear)"
},
{
"command": "konveyor.configureLabelSelector",
"title": "Configure Analysis LabelSelector",
"category": "Konveyor",
"icon": "$(gear)"
}
],
"submenus": [
Expand Down Expand Up @@ -103,7 +127,135 @@
"group": "navigation@1"
}
]
}
},
"configuration": {
"type": "object",
"title": "Konveyor",
"properties": {
"konveyor.analyzerPath": {
"type": "string",
"default": "",
"description": "Path to the analyzer binary. If not set, the extension will use the bundled analyzer.",
"scope": "machine",
"order": 0
},
"konveyor.incidentLimit": {
"type": "number",
"default": 10000,
"description": "Maximum number of incidents to report",
"scope": "window",
"order": 1
},
"konveyor.contextLines": {
"type": "number",
"default": 10,
"description": "Number of lines of context to include in incident reports",
"scope": "window",
"order": 2
},
"konveyor.codeSnipLimit": {
"type": "number",
"default": 10,
"description": "Number of lines of code to include in incident reports",
"scope": "window",
"order": 3
},
"konveyor.useDefaultRulesets": {
"type": "boolean",
"default": true,
"description": "Whether analysis should use the default rulesets, included in the extension",
"scope": "window",
"order": 4
},
"konveyor.customRules": {
"type": "array",
"items": {
"type": "string"
},
"default": [],
"description": "Array of filepaths to additional rules for analysis",
"scope": "window",
"order": 5
},
"konveyor.labelSelector": {
"type": "string",
"default": "discovery",
"description": "Expression to select incidents based on custom variables. Example: (!package=io.konveyor.demo.config-utils)",
"scope": "window",
"order": 6
},
"konveyor.analyzeKnownLibraries": {
"type": "boolean",
"default": false,
"description": "Whether analysis should include known open-source libraries",
"scope": "window",
"order": 7
},
"konveyor.analyzeDependencies": {
"type": "boolean",
"default": true,
"description": "Whether analysis should include dependencies",
"scope": "window",
"order": 8
},
"konveyor.analyzeOnSave": {
"type": "boolean",
"default": true,
"description": "Whether analysis of file should be run when saved",
"scope": "window",
"order": 9
}
}
},
"walkthroughs": [
{
"id": "konveyor-setup",
"title": "Set up Konveyor",
"description": "Configure Konveyor for your project",
"steps": [
{
"id": "override-analyzer",
"title": "Override Analyzer Binary",
"description": "Specify a custom path for the analyzer binary\n[Override Analyzer Binary](command:konveyor.overrideAnalyzerBinaries)",

"completionEvents": [],
"media": {
"markdown": "media/walkthroughs/override-analyzer.md"
}
},
{
"id": "configure-custom-rules",
"title": "Configure Custom Rules",
"description": "Add custom rules for analysis\n[Configure Custom Rules](command:konveyor.configureCustomRules)",
"completionEvents": ["onCommand:konveyor.configureCustomRules"],
"media": {
"markdown": "media/walkthroughs/custom-rules.md"
}
},
{
"id": "configure-analysis-arguments",
"title": "Configure Analysis Arguments",
"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)",
"completionEvents": [
"onCommand:konveyor.configureSourcesTargets",
"onCommand:konveyor.configureLabelSelector"
],
"media": {
"markdown": "media/walkthroughs/analysis-arguments.md"
}
},
{
"id": "start-analyzer",
"title": "Start Analyzer",
"description": "Start the analyzer",
"completionEvents": [],
"media": {
"markdown": "media/walkthroughs/start-analyzer.md"
}
}
]
}
]
},
"scripts": {
"vscode:prepublish": "npm run package",
Expand Down
172 changes: 172 additions & 0 deletions vscode/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { KonveyorGUIWebviewViewProvider } from "./KonveyorGUIWebviewViewProvider
import { setupWebviewMessageListener } from "./webviewMessageHandler";
import { ExtensionState } from "./extensionState";
import { getWebviewContent } from "./webviewContent";
import { sourceOptions, targetOptions } from "./config/labels";

let fullScreenPanel: vscode.WebviewPanel | undefined;

Expand Down Expand Up @@ -107,6 +108,177 @@ const commandsMap: (
extensionContext.subscriptions,
);
},
"konveyor.overrideAnalyzerBinaries": async () => {
const options: vscode.OpenDialogOptions = {
canSelectMany: false,
openLabel: 'Select Analyzer Binary',
filters: {
'Executable Files': ['exe', 'sh', 'bat', ''],
'All Files': ['*']
}
};

const fileUri = await vscode.window.showOpenDialog(options);

if (fileUri && fileUri[0]) {
const filePath = fileUri[0].fsPath;

// Update the user settings
const config = vscode.workspace.getConfiguration('konveyor');
await config.update('analyzerPath', filePath, vscode.ConfigurationTarget.Global);

vscode.window.showInformationMessage(`Analyzer binary path updated to: ${filePath}`);
} else {
vscode.window.showInformationMessage('No analyzer binary selected.');
}
},
"konveyor.configureCustomRules": async () => {
const options: vscode.OpenDialogOptions = {
canSelectMany: true,
canSelectFolders: true,
canSelectFiles: true,
openLabel: 'Select Custom Rules',
filters: {
'All Files': ['*']
}
};

const fileUris = await vscode.window.showOpenDialog(options);

if (fileUris && fileUris.length > 0) {
const customRules = fileUris.map((uri) => uri.fsPath);

// TODO(djzager): Should we verify the rules provided are valid?

// Update the user settings
const config = vscode.workspace.getConfiguration('konveyor');
await config.update('customRules', customRules, vscode.ConfigurationTarget.Workspace);

// Ask the user if they want to disable the default ruleset
const useDefaultRulesets = await vscode.window.showQuickPick(
['Yes', 'No'],
{
placeHolder: 'Do you want to use the default rulesets?',
canPickMany: false
}
);

if (useDefaultRulesets === 'Yes') {
await config.update('useDefaultRulesets', true, vscode.ConfigurationTarget.Workspace);
} else if (useDefaultRulesets === 'No') {
await config.update('useDefaultRulesets', false, vscode.ConfigurationTarget.Workspace);
}

vscode.window.showInformationMessage(`Custom Rules Updated: ${customRules}\nUse Default Rulesets: ${useDefaultRulesets}`);
} else {
vscode.window.showInformationMessage('No custom rules selected.');
}
},
"konveyor.configureSourcesTargets": async() => {
const config = vscode.workspace.getConfiguration('konveyor');
const currentLabelSelector = config.get<string>('labelSelector', '');

// Function to extract values from label selector
const extractValuesFromSelector = (selector: string, key: string): string[] => {
const regex = new RegExp(`konveyor.io/${key}=(.*?)(?:\\s|$)`, 'g');
const matches = selector.matchAll(regex);
const values = Array.from(matches, match => match[1]);
return values.flatMap(value => value.split('|'));
};

// Extract sources and targets from the current label selector
const currentSources = extractValuesFromSelector(currentLabelSelector, 'source');
const currentTargets = extractValuesFromSelector(currentLabelSelector, 'target');

const state: { sources: string[]; targets: string[]; labelSelector: string } = { sources: [], targets: [], labelSelector: '' };

// Function to show QuickPick for sources and targets
const showQuickPick = async (title: string, placeholder: string, items: string[], selectedItems: string[]): Promise<string[] | undefined> => {
const result = await vscode.window.showQuickPick(
items.map(item => ({
label: item,
picked: selectedItems.includes(item)
})),
{
canPickMany: true,
placeHolder: placeholder,
title: title
}
);
if (result === undefined) {
return undefined;
}
return result.map(item => item.label);
};

// Show QuickPick for sources
const selectedSources = await showQuickPick(
'Select Source Technologies',
'Choose one or more source technologies',
sourceOptions,
currentSources
);
if (selectedSources === undefined) {
return;
}
state.sources = selectedSources;

// Show QuickPick for targets
const selectedTargets = await showQuickPick(
'Select Target Technologies',
'Choose one or more target technologies',
targetOptions,
currentTargets
);
if (selectedTargets === undefined) {
return;
}
state.targets = selectedTargets;

// Compute initial label selector
const sources = state.sources.map(source => `konveyor.io/source=${source}`).join(' || ');
const targets = state.targets.map(target => `konveyor.io/target=${target}`).join(' || ');
if (sources === "" && targets === "") {
vscode.window.showInformationMessage("No sources or targets selected.");
return;
}

state.labelSelector = `(${[sources, targets].filter(part => part !== "").join(' && ')}) || (discovery)`;

// Show input box for modifying label selector
const modifiedLabelSelector = await vscode.window.showInputBox({
prompt: 'Modify the label selector if needed',
value: state.labelSelector,
placeHolder: 'e.g., source=(java|spring) target=(quarkus)'
});

if (modifiedLabelSelector === undefined) {
return;
}
state.labelSelector = modifiedLabelSelector;

// Update the user settings
await config.update('labelSelector', state.labelSelector, vscode.ConfigurationTarget.Workspace);

vscode.window.showInformationMessage(`Configuration updated: Sources: ${state.sources.join(', ')}, Targets: ${state.targets.join(', ')}, Label Selector: ${state.labelSelector}`);
},
"konveyor.configureLabelSelector": async () => {
const config = vscode.workspace.getConfiguration('konveyor');
const currentLabelSelector = config.get<string>('labelSelector', '');

const modifiedLabelSelector = await vscode.window.showInputBox({
prompt: 'Modify the label selector if needed',
value: currentLabelSelector,
placeHolder: 'e.g., source=(java|spring) target=(quarkus)'
});

if (modifiedLabelSelector === undefined) {
return;
}

// Update the user settings
await config.update('labelSelector', modifiedLabelSelector, vscode.ConfigurationTarget.Workspace);
},
};
};

Expand Down
Loading
Loading