Skip to content

Commit 560048c

Browse files
feat(upgradeManager): collect issues on load and workspace folder update
1 parent 18be55e commit 560048c

File tree

4 files changed

+144
-44
lines changed

4 files changed

+144
-44
lines changed

src/extension.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// Licensed under the MIT license.
33

44
import * as path from "path";
5-
import { commands, Diagnostic, Extension, ExtensionContext, extensions, languages,
6-
Range, tasks, TextDocument, TextEditor, Uri, window, workspace } from "vscode";
5+
import {
6+
commands, Diagnostic, Extension, ExtensionContext, extensions, languages,
7+
Range, tasks, TextDocument, TextEditor, Uri, window, workspace
8+
} from "vscode";
79
import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand, sendInfo } from "vscode-extension-telemetry-wrapper";
810
import { Commands, contextManager } from "../extension.bundle";
911
import { BuildTaskProvider } from "./tasks/build/buildTaskProvider";
@@ -20,9 +22,11 @@ import { DiagnosticProvider } from "./tasks/buildArtifact/migration/DiagnosticPr
2022
import { setContextForDeprecatedTasks, updateExportTaskType } from "./tasks/buildArtifact/migration/utils";
2123
import { CodeActionProvider } from "./tasks/buildArtifact/migration/CodeActionProvider";
2224
import { newJavaFile } from "./explorerCommands/new";
25+
import upgradeManager from "./upgrade/upgradeManager";
2326

2427
export async function activate(context: ExtensionContext): Promise<void> {
2528
contextManager.initialize(context);
29+
upgradeManager.initialize(context);
2630
await initializeFromJsonFile(context.asAbsolutePath("./package.json"));
2731
await initExpService(context);
2832
await instrumentOperation("activation", activateExtension)(context);

src/syncHandler.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { DataNode } from "./views/dataNode";
1313
import { ExplorerNode } from "./views/explorerNode";
1414
import { explorerNodeCache } from "./views/nodeCache/explorerNodeCache";
1515
import { Jdtls } from "./java/jdtls";
16+
import upgradeManager from "./upgrade/upgradeManager";
1617

1718
const ENABLE_AUTO_REFRESH: string = "java.view.package.enableAutoRefresh";
1819
const DISABLE_AUTO_REFRESH: string = "java.view.package.disableAutoRefresh";
@@ -46,6 +47,7 @@ class SyncHandler implements Disposable {
4647

4748
this.disposables.push(workspace.onDidChangeWorkspaceFolders(() => {
4849
this.refresh();
50+
upgradeManager.scan();
4951
}));
5052

5153
try {

src/upgrade/issueManager.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/upgrade/upgradeManager.ts

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import { commands, type ExtensionContext, workspace, type WorkspaceFolder } from "vscode";
5+
import * as semver from 'semver'
6+
import { Jdtls } from "../java/jdtls";
7+
import { languageServerApiManager } from "../languageServerApi/languageServerApiManager";
8+
import { NodeKind, type INodeData } from "../java/nodeData";
9+
import { Upgrade } from "../constants";
10+
import { UpgradeIssue, UpgradeReason } from "./type";
11+
import { instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper";
12+
import { Commands } from "../commands";
13+
import metadataManager from "./metadataManager";
14+
import { buildPackageId } from "./utility";
15+
16+
const DEFAULT_UPGRADE_PROMPT = "Upgrade Java project dependency";
17+
18+
function getJavaIssues(data: INodeData): UpgradeIssue[] {
19+
const javaVersion = data.metaData?.MaxSourceVersion as number | undefined;
20+
if (!javaVersion) {
21+
return [];
22+
}
23+
if (javaVersion < Upgrade.LATEST_JAVA_LTS_VESRION) {
24+
return [{
25+
packageId: buildPackageId(Upgrade.DIAGNOSTICS_GROUP_ID_FOR_JAVA_ENGINE, "*"),
26+
reason: UpgradeReason.ENGINE_TOO_OLD,
27+
currentVersion: String(javaVersion),
28+
suggestedVersion: String(Upgrade.LATEST_JAVA_LTS_VESRION),
29+
}];
30+
}
31+
32+
return [];
33+
}
34+
35+
function getDependencyIssues(data: INodeData): UpgradeIssue[] {
36+
const versionString = data.metaData?.["maven.version"];
37+
const groupId = data.metaData?.["maven.groupId"];
38+
const artifactId = data.metaData?.["maven.artifactId"];
39+
const packageId = buildPackageId(groupId, artifactId);
40+
const supportedVersionDefinition = metadataManager.getMetadataById(packageId);
41+
if (!versionString || !groupId || !supportedVersionDefinition) {
42+
return [];
43+
}
44+
const currentVersion = semver.coerce(versionString);
45+
if (!currentVersion) {
46+
return [];
47+
}
48+
if (!semver.satisfies(currentVersion, supportedVersionDefinition.supportedVersion)) {
49+
return [{
50+
packageId,
51+
packageDisplayName: supportedVersionDefinition.name,
52+
reason: UpgradeReason.END_OF_LIFE,
53+
currentVersion: versionString,
54+
suggestedVersion: "latest", // TODO
55+
}];
56+
}
57+
return [];
58+
}
59+
60+
async function getProjectIssues(projectNode: INodeData): Promise<UpgradeIssue[]> {
61+
const pomPath = projectNode.metaData?.PomPath as string | undefined;
62+
if (!pomPath) {
63+
return [];
64+
}
65+
const issues: UpgradeIssue[] = [];
66+
issues.push(...getJavaIssues(projectNode));
67+
const packageData = await Jdtls.getPackageData({ kind: NodeKind.Project, projectUri: projectNode.uri });
68+
packageData
69+
.filter(x => x.kind === NodeKind.Container)
70+
.forEach(async (packageContainer) => {
71+
const packages = await Jdtls.getPackageData({
72+
kind: NodeKind.Container,
73+
projectUri: projectNode.uri,
74+
path: packageContainer.path,
75+
});
76+
packages.forEach(
77+
(pkg) => {
78+
issues.push(...getDependencyIssues(pkg))
79+
}
80+
);
81+
});
82+
return issues;
83+
}
84+
85+
class UpgradeManager {
86+
public initialize(context: ExtensionContext) {
87+
// Command to be used
88+
context.subscriptions.push(instrumentOperationAsVsCodeCommand(Commands.VIEW_TRIGGER_JAVA_UPGRADE_TOOL, (promptText?: string) => {
89+
this.runUpgrade(promptText ?? DEFAULT_UPGRADE_PROMPT);
90+
}));
91+
92+
upgradeManager.scan();
93+
}
94+
95+
public scan() {
96+
workspace.workspaceFolders?.forEach((folder) =>
97+
this.checkUpgradableComponents(folder)
98+
);
99+
}
100+
101+
private async checkUpgradableComponents(folder: WorkspaceFolder) {
102+
if (!await languageServerApiManager.ready()) {
103+
return;
104+
}
105+
const hasJavaError: boolean = await Jdtls.checkImportStatus();
106+
if (hasJavaError) {
107+
return;
108+
}
109+
110+
const projectIssues: Record</* pomPath */string, UpgradeIssue[]> = {};
111+
const uri = folder.uri.toString();
112+
const projects = await Jdtls.getProjects(uri);
113+
projects.forEach(async (projectNode) => {
114+
const pomPath = projectNode.metaData?.PomPath as string | undefined;
115+
if (!pomPath) {
116+
return;
117+
}
118+
119+
const issues = await getProjectIssues(projectNode);
120+
projectIssues[pomPath] = issues;
121+
});
122+
123+
// TODO: show notification
124+
}
125+
126+
127+
private async runUpgrade(promptText: string) {
128+
await commands.executeCommand("workbench.action.chat.open", {
129+
query: promptText,
130+
isPartialQuery: true
131+
});
132+
}
133+
}
134+
135+
const upgradeManager = new UpgradeManager();
136+
export default upgradeManager;

0 commit comments

Comments
 (0)