Skip to content

Commit 7d8cf2e

Browse files
authored
fix: Get options from matadata (#173)
1 parent 54ea24f commit 7d8cf2e

10 files changed

+88
-74
lines changed

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@
166166
"mocha": "^7.1.1",
167167
"ts-loader": "^4.4.2",
168168
"tslint": "^5.18.0",
169-
"typescript": "^3.5.3",
169+
"typescript": "^4.2.3",
170170
"vscode-test": "^1.2.0",
171171
"webpack": "^4.42.0",
172172
"webpack-cli": "^3.3.12"

src/handler/HandlerInterfaces.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { QuickPickItem } from "vscode";
55
import { IDependenciesItem } from "../DependencyManager";
6+
import { Identifiable } from "../model/Metadata";
67

78
export interface IStep {
89
getNextStep(): IStep | undefined;
@@ -32,12 +33,17 @@ export interface IDefaultProjectData {
3233
targetFolder?: string;
3334
}
3435

35-
export interface IPickMetadata {
36+
export interface IHandlerItem<T extends Identifiable> extends QuickPickItem {
37+
label: string;
38+
value?: T;
39+
}
40+
41+
export interface IPickMetadata<T extends Identifiable> {
3642
metadata: IProjectMetadata;
3743
title: string;
3844
pickStep: IStep;
3945
placeholder: string;
40-
items: QuickPickItem[];
46+
items: Array<IHandlerItem<T>>;
4147
}
4248

4349
export interface IInputMetaData {

src/handler/SpecifyBootVersionStep.ts

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import { Disposable, QuickInputButtons, QuickPick, window } from "vscode";
54
import { instrumentOperationStep, sendInfo } from "vscode-extension-telemetry-wrapper";
6-
import { OperationCanceledError } from "../Errors";
7-
import { IValue, serviceManager } from "../model";
8-
import { IProjectMetadata, IStep } from "./HandlerInterfaces";
5+
import { serviceManager } from "../model";
6+
import { BootVersion, MatadataType } from "../model/Metadata";
7+
import { IPickMetadata, IProjectMetadata, IStep } from "./HandlerInterfaces";
98
import { SpecifyLanguageStep } from "./SpecifyLanguageStep";
9+
import { createPickBox } from "./utils";
1010

1111
export class SpecifyBootVersionStep implements IStep {
1212

@@ -29,46 +29,13 @@ export class SpecifyBootVersionStep implements IStep {
2929
}
3030

3131
private async specifyBootVersion(projectMetadata: IProjectMetadata): Promise<boolean> {
32-
const disposables: Disposable[] = [];
33-
const result: boolean = await new Promise<boolean>(async (resolve, reject) => {
34-
const pickBox: QuickPick<{ value: IValue, label: string }> = window.createQuickPick<{ value: IValue, label: string }>();
35-
pickBox.title = "Spring Initializr: Specify Spring Boot version",
36-
pickBox.placeholder = "Specify Spring Boot version.";
37-
try {
38-
pickBox.items = await serviceManager.getBootVersions(projectMetadata.serviceUrl).then(versions => versions.map(v => ({ value: v, label: v.name })));
39-
} catch (error) {
40-
return reject(error);
41-
}
42-
pickBox.ignoreFocusOut = true;
43-
if (projectMetadata.pickSteps.length > 0) {
44-
pickBox.buttons = [(QuickInputButtons.Back)];
45-
disposables.push(
46-
pickBox.onDidTriggerButton((item) => {
47-
if (item === QuickInputButtons.Back) {
48-
return resolve(false);
49-
}
50-
})
51-
);
52-
}
53-
disposables.push(
54-
pickBox.onDidAccept(() => {
55-
if (!pickBox.selectedItems[0]) {
56-
return;
57-
}
58-
projectMetadata.bootVersion = pickBox.selectedItems[0] && pickBox.selectedItems[0].value && pickBox.selectedItems[0].value.id;
59-
projectMetadata.pickSteps.push(SpecifyBootVersionStep.getInstance());
60-
return resolve(true);
61-
}),
62-
pickBox.onDidHide(() => {
63-
return reject(new OperationCanceledError("BootVersion not specified."));
64-
})
65-
);
66-
disposables.push(pickBox);
67-
pickBox.show();
68-
});
69-
for (const d of disposables) {
70-
d.dispose();
71-
}
72-
return result;
32+
const pickMetaData: IPickMetadata<BootVersion> = {
33+
metadata: projectMetadata,
34+
title: "Spring Initializr: Specify Spring Boot version",
35+
pickStep: SpecifyBootVersionStep.getInstance(),
36+
placeholder: "Specify Spring Boot version.",
37+
items: await serviceManager.getItems(projectMetadata.serviceUrl, MatadataType.BOOTVERSION),
38+
};
39+
return await createPickBox(pickMetaData);
7340
}
7441
}

src/handler/SpecifyJavaVersionStep.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import { workspace } from "vscode";
55
import { instrumentOperationStep } from "vscode-extension-telemetry-wrapper";
6+
import { serviceManager } from "../model";
7+
import { JavaVersion, MatadataType } from "../model/Metadata";
68
import { IPickMetadata, IProjectMetadata, IStep } from "./HandlerInterfaces";
79
import { SpecifyDependenciesStep } from "./SpecifyDependenciesStep";
810
import { createPickBox } from "./utils";
@@ -32,12 +34,12 @@ export class SpecifyJavaVersionStep implements IStep {
3234
projectMetadata.javaVersion = javaVersion;
3335
return true;
3436
}
35-
const pickMetaData: IPickMetadata = {
37+
const pickMetaData: IPickMetadata<JavaVersion> = {
3638
metadata: projectMetadata,
3739
title: "Spring Initializr: Specify Java version",
3840
pickStep: SpecifyJavaVersionStep.getInstance(),
3941
placeholder: "Specify Java version.",
40-
items: [{ label: "11" }, { label: "1.8" }, { label: "14" }]
42+
items: await serviceManager.getItems(projectMetadata.serviceUrl, MatadataType.JAVAVERSION),
4143
};
4244
return await createPickBox(pickMetaData);
4345
}

src/handler/SpecifyLanguageStep.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import { workspace } from "vscode";
55
import { instrumentOperationStep } from "vscode-extension-telemetry-wrapper";
6+
import { serviceManager } from "../model";
7+
import { Language, MatadataType } from "../model/Metadata";
68
import { IPickMetadata, IProjectMetadata, IStep } from "./HandlerInterfaces";
79
import { SpecifyGroupIdStep } from "./SpecifyGroupIdStep";
810
import { createPickBox } from "./utils";
@@ -32,12 +34,12 @@ export class SpecifyLanguageStep implements IStep {
3234
projectMetadata.language = language && language.toLowerCase();
3335
return true;
3436
}
35-
const pickMetaData: IPickMetadata = {
37+
const pickMetaData: IPickMetadata<Language> = {
3638
metadata: projectMetadata,
3739
title: "Spring Initializr: Specify project language",
3840
pickStep: SpecifyLanguageStep.getInstance(),
3941
placeholder: "Specify project language.",
40-
items: [{ label: "Java" }, { label: "Kotlin" }, { label: "Groovy" }]
42+
items: await serviceManager.getItems(projectMetadata.serviceUrl, MatadataType.LANGUAGE),
4143
};
4244
return await createPickBox(pickMetaData);
4345
}

src/handler/SpecifyPackagingStep.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
import { workspace } from "vscode";
55
import { instrumentOperationStep } from "vscode-extension-telemetry-wrapper";
6+
import { serviceManager } from "../model";
7+
import { MatadataType, Packaging } from "../model/Metadata";
68
import { IPickMetadata, IProjectMetadata, IStep } from "./HandlerInterfaces";
79
import { SpecifyJavaVersionStep } from "./SpecifyJavaVersionStep";
810
import { createPickBox } from "./utils";
@@ -32,12 +34,12 @@ export class SpecifyPackagingStep implements IStep {
3234
projectMetadata.packaging = packaging && packaging.toLowerCase();
3335
return true;
3436
}
35-
const pickMetaData: IPickMetadata = {
37+
const pickMetaData: IPickMetadata<Packaging> = {
3638
metadata: projectMetadata,
3739
title: "Spring Initializr: Specify packaging type",
3840
pickStep: SpecifyPackagingStep.getInstance(),
3941
placeholder: "Specify packaging type.",
40-
items: [{ label: "JAR" }, { label: "WAR" }]
42+
items: await serviceManager.getItems(projectMetadata.serviceUrl, MatadataType.PACKAGING),
4143
};
4244
return await createPickBox(pickMetaData);
4345
}

src/handler/utils.ts

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

44
import * as vscode from "vscode";
5-
import { Disposable, InputBox, QuickInputButtons, QuickPick, QuickPickItem, window } from "vscode";
5+
import { Disposable, InputBox, QuickInputButtons, QuickPick, window } from "vscode";
66
import { OperationCanceledError } from "../Errors";
7+
import { Identifiable } from "../model/Metadata";
78
import { artifactIdValidation, groupIdValidation } from "../Utils";
8-
import { IInputMetaData, IPickMetadata, IProjectMetadata } from "./HandlerInterfaces";
9+
import { IHandlerItem, IInputMetaData, IPickMetadata, IProjectMetadata } from "./HandlerInterfaces";
910
import { SpecifyArtifactIdStep } from "./SpecifyArtifactIdStep";
11+
import { SpecifyBootVersionStep } from "./SpecifyBootVersionStep";
1012
import { SpecifyGroupIdStep } from "./SpecifyGroupIdStep";
1113
import { SpecifyJavaVersionStep } from "./SpecifyJavaVersionStep";
1214
import { SpecifyLanguageStep } from "./SpecifyLanguageStep";
@@ -32,10 +34,10 @@ export async function specifyServiceUrl(projectMetadata?: IProjectMetadata): Pro
3234
}
3335
}
3436

35-
export async function createPickBox(pickMetadata: IPickMetadata): Promise<boolean> {
37+
export async function createPickBox<T extends Identifiable>(pickMetadata: IPickMetadata<T>): Promise<boolean> {
3638
const disposables: Disposable[] = [];
3739
const result: boolean = await new Promise<boolean>((resolve, reject) => {
38-
const pickBox: QuickPick<QuickPickItem> = window.createQuickPick<QuickPickItem>();
40+
const pickBox: QuickPick<IHandlerItem<T>> = window.createQuickPick<IHandlerItem<T>>();
3941
pickBox.title = pickMetadata.title;
4042
pickBox.placeholder = pickMetadata.placeholder;
4143
pickBox.items = pickMetadata.items;
@@ -52,15 +54,17 @@ export async function createPickBox(pickMetadata: IPickMetadata): Promise<boolea
5254
}
5355
disposables.push(
5456
pickBox.onDidAccept(() => {
55-
if (!pickBox.selectedItems[0]) {
57+
if (!pickBox.selectedItems?.[0]) {
5658
return;
5759
}
5860
if (pickMetadata.pickStep instanceof SpecifyLanguageStep) {
59-
pickMetadata.metadata.language = pickBox.selectedItems[0].label && pickBox.selectedItems[0].label.toLowerCase();
61+
pickMetadata.metadata.language = pickBox.selectedItems[0].label?.toLowerCase();
6062
} else if (pickMetadata.pickStep instanceof SpecifyJavaVersionStep) {
6163
pickMetadata.metadata.javaVersion = pickBox.selectedItems[0].label;
6264
} else if (pickMetadata.pickStep instanceof SpecifyPackagingStep) {
63-
pickMetadata.metadata.packaging = pickBox.selectedItems[0].label && pickBox.selectedItems[0].label.toLowerCase();
65+
pickMetadata.metadata.packaging = pickBox.selectedItems[0].label?.toLowerCase();
66+
} else if (pickMetadata.pickStep instanceof SpecifyBootVersionStep) {
67+
pickMetadata.metadata.bootVersion = pickBox.selectedItems[0].value?.id;
6468
}
6569
pickMetadata.metadata.pickSteps.push(pickMetadata.pickStep);
6670
return resolve(true);
@@ -72,6 +76,8 @@ export async function createPickBox(pickMetadata: IPickMetadata): Promise<boolea
7276
return reject(new OperationCanceledError("Java version not specified."));
7377
} else if (pickMetadata.pickStep instanceof SpecifyPackagingStep) {
7478
return reject(new OperationCanceledError("Packaging not specified."));
79+
} else if (pickMetadata.pickStep instanceof SpecifyBootVersionStep) {
80+
return reject(new OperationCanceledError("BootVersion not specified."));
7581
}
7682
return reject(new Error("Unknown picking step"));
7783
})

src/model/Metadata.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ export interface Metadata {
1313
type: Category<ProjectType>;
1414
}
1515

16+
export enum MatadataType {
17+
BOOTVERSION,
18+
JAVAVERSION,
19+
LANGUAGE,
20+
PACKAGING,
21+
}
22+
1623
interface Nameable {
1724
name: string;
1825
}
1926

20-
interface Identifiable extends Nameable {
27+
export interface Identifiable extends Nameable {
2128
id: string;
2229
}
2330

@@ -30,10 +37,10 @@ interface ProjectType extends Identifiable {
3037
action: string;
3138
}
3239

33-
type BootVersion = Identifiable;
34-
type Packaging = Identifiable;
35-
type JavaVersion = Identifiable;
36-
type Language = Identifiable;
40+
export type BootVersion = Identifiable;
41+
export type Packaging = Identifiable;
42+
export type JavaVersion = Identifiable;
43+
export type Language = Identifiable;
3744

3845
export interface DependencyGroup extends Category<Dependency>, Nameable {
3946
}

src/model/ServiceManager.ts

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

44
import { IDependency, IStarters } from ".";
5+
import { IHandlerItem } from "../handler/HandlerInterfaces";
56
import { downloadFile } from "../Utils";
67
import { matchRange } from "../Utils/VersionHelper";
7-
import { DependencyGroup, Metadata } from "./Metadata";
8+
import { DependencyGroup, Identifiable, MatadataType, Metadata } from "./Metadata";
89

910
/**
1011
* Prefer v2.2 and fallback to v2.1
@@ -15,15 +16,36 @@ const METADATA_HEADERS = { Accept: "application/vnd.initializr.v2.2+json,applica
1516
class ServiceManager {
1617
private metadataMap: Map<string, Metadata> = new Map();
1718

18-
public async getBootVersions(serviceUrl: string): Promise<any[]> {
19+
public async getItems<T extends Identifiable>(serviceUrl: string, type: MatadataType): Promise<Array<IHandlerItem<T>>> {
1920
const metadata = await this.ensureMetadata(serviceUrl);
2021
if (!metadata) {
2122
throw new Error("Failed to fetch metadata.");
2223
}
24+
let defaultLabel: string;
25+
let values: any[];
26+
switch (type) {
27+
case MatadataType.BOOTVERSION:
28+
defaultLabel = metadata.bootVersion.default;
29+
values = metadata.bootVersion.values;
30+
break;
31+
case MatadataType.JAVAVERSION:
32+
defaultLabel = metadata.javaVersion.default;
33+
values = metadata.javaVersion.values;
34+
break;
35+
case MatadataType.LANGUAGE:
36+
defaultLabel = metadata.language.default;
37+
values = metadata.language.values;
38+
break;
39+
case MatadataType.PACKAGING:
40+
defaultLabel = metadata.packaging.default;
41+
values = metadata.packaging.values;
42+
break;
43+
default:
44+
throw new Error("Invalid metadata type.");
45+
}
2346

24-
const defaultVersion: string = metadata.bootVersion.default;
25-
const versions = metadata.bootVersion.values;
26-
return versions.filter(x => x.id === defaultVersion).concat(versions.filter(x => x.id !== defaultVersion));
47+
const sortedValues = values.filter(x => x.id === defaultLabel).concat(values.filter(x => x.id !== defaultLabel));
48+
return (type === MatadataType.BOOTVERSION) ? sortedValues.map(v => ({ value: v, label: v.name })) : sortedValues.map(v => ({ label: v.name }));
2749
}
2850

2951
public async getAvailableDependencies(serviceUrl: string, bootVersion: string): Promise<IDependency[]> {

0 commit comments

Comments
 (0)