Skip to content

Commit

Permalink
Issue 217: Allow Package Name specification (#230)
Browse files Browse the repository at this point in the history
* added default setting for packageName

* function for validating package names

* added packageName property to handler interfaces

* added step for specifying package name

using groupId + artifactId as default value

* call package name step after artifactId

* handling new step

* removed default config since it's always dynamic

* fix: replace hyphen with underscore when recommending a packageName

---------

Co-authored-by: Jinbo Wang <jinbwan@microsoft.com>
  • Loading branch information
brunovieira97 and testforstephen authored Sep 19, 2024
1 parent d1e9eed commit 8bf8732
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/Utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ export function artifactIdValidation(value: string): string | undefined {
return (/^[a-z_][a-z0-9_]*(-[a-z_][a-z0-9_]*)*$/.test(value)) ? undefined : "Invalid Artifact Id";
}

export function packageNameValidation(value: string): string {
return (/^[a-z_][a-z0-9_]*(\.[a-z0-9_]+)*$/.test(value)) ? null : "Invalid Package Name";
}

export async function readXmlContent(xml: string, options?: {}): Promise<any> {
const opts: {} = Object.assign({ explicitArray: true }, options);
return new Promise<{}>(
Expand Down
3 changes: 3 additions & 0 deletions src/handler/GenerateProjectHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { BaseHandler } from "./BaseHandler";
import { IDefaultProjectData, IProjectMetadata, IStep, ParentFolder } from "./HandlerInterfaces";
import { SpecifyArtifactIdStep } from "./SpecifyArtifactIdStep";
import { SpecifyGroupIdStep } from "./SpecifyGroupIdStep";
import { SpecifyPackageNameStep } from "./SpecifyPackageNameStep";
import { SpecifyServiceUrlStep } from "./SpecifyServiceUrlStep";
import { ProjectType } from "../model";

Expand Down Expand Up @@ -47,6 +48,7 @@ export class GenerateProjectHandler extends BaseHandler {

SpecifyArtifactIdStep.getInstance().resetDefaultInput();
SpecifyGroupIdStep.getInstance().resetDefaultInput();
SpecifyPackageNameStep.getInstance().resetDefaultInput();
while (step !== undefined) {
step = await step.execute(operationId, this.metadata);
}
Expand Down Expand Up @@ -88,6 +90,7 @@ export class GenerateProjectHandler extends BaseHandler {
`javaVersion=${this.metadata.javaVersion}`,
`groupId=${this.metadata.groupId}`,
`artifactId=${this.metadata.artifactId}`,
`packageName=${this.metadata.packageName}`,
`name=${this.metadata.artifactId}`,
`packaging=${this.metadata.packaging}`,
`bootVersion=${this.metadata.bootVersion}`,
Expand Down
1 change: 1 addition & 0 deletions src/handler/HandlerInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IProjectMetadata {
javaVersion?: string;
groupId?: string;
artifactId?: string;
packageName?: string;
packaging?: string;
bootVersion?: string;
dependencies?: IDependenciesItem;
Expand Down
4 changes: 2 additions & 2 deletions src/handler/SpecifyArtifactIdStep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { workspace } from "vscode";
import { instrumentOperationStep } from "vscode-extension-telemetry-wrapper";
import { IInputMetaData, IProjectMetadata, IStep } from "./HandlerInterfaces";
import { SpecifyPackagingStep } from "./SpecifyPackagingStep";
import { SpecifyPackageNameStep } from "./SpecifyPackageNameStep";
import { createInputBox } from "./utils";

export class SpecifyArtifactIdStep implements IStep {
Expand Down Expand Up @@ -34,7 +34,7 @@ export class SpecifyArtifactIdStep implements IStep {
}

public getNextStep(): IStep | undefined {
return SpecifyPackagingStep.getInstance();
return SpecifyPackageNameStep.getInstance();
}

public async execute(operationId: string, projectMetadata: IProjectMetadata): Promise<IStep | undefined> {
Expand Down
59 changes: 59 additions & 0 deletions src/handler/SpecifyPackageNameStep.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { instrumentOperationStep } from "vscode-extension-telemetry-wrapper";
import { IInputMetaData, IProjectMetadata, IStep } from "./HandlerInterfaces";
import { SpecifyPackagingStep } from "./SpecifyPackagingStep";
import { createInputBox } from "./utils";

export class SpecifyPackageNameStep implements IStep {

public static getInstance(): SpecifyPackageNameStep {
return SpecifyPackageNameStep.specifyPackageNameStep;
}

private static specifyPackageNameStep: SpecifyPackageNameStep = new SpecifyPackageNameStep();

private defaultInput: string;

constructor() {
this.resetDefaultInput();
}

public getDefaultInput(): string {
return this.defaultInput;
}

public setDefaultInput(defaultInput: string): void {
this.defaultInput = defaultInput;
}

public resetDefaultInput(): void {
this.defaultInput = null;
}

public getNextStep(): IStep | undefined {
return SpecifyPackagingStep.getInstance();
}

public async execute(operationId: string, projectMetadata: IProjectMetadata): Promise<IStep | undefined> {
if (!await instrumentOperationStep(operationId, "PackageName", this.specifyPackageName)(projectMetadata)) {
return projectMetadata.pickSteps.pop();
}
return this.getNextStep();
}

private async specifyPackageName(projectMetadata: IProjectMetadata): Promise<boolean> {
const recommendedPackageName = `${projectMetadata.groupId}.${projectMetadata.artifactId}`.replace("-", "_");

const inputMetaData: IInputMetaData = {
metadata: projectMetadata,
title: "Spring Initializr: Input Package Name",
pickStep: SpecifyPackageNameStep.getInstance(),
placeholder: "e.g. com.example",
prompt: "Input Package Name for your project.",
defaultValue: recommendedPackageName || SpecifyPackageNameStep.getInstance().defaultInput
};
return await createInputBox(inputMetaData);
}
}
11 changes: 10 additions & 1 deletion src/handler/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as vscode from "vscode";
import { Disposable, InputBox, QuickInputButtons, QuickPick, window } from "vscode";
import { OperationCanceledError } from "../Errors";
import { Identifiable } from "../model/Metadata";
import { artifactIdValidation, groupIdValidation } from "../Utils";
import { artifactIdValidation, groupIdValidation, packageNameValidation } from "../Utils";
import { IHandlerItem, IInputMetaData, IPickMetadata, IProjectMetadata } from "./HandlerInterfaces";
import { SpecifyArtifactIdStep } from "./SpecifyArtifactIdStep";
import { SpecifyBootVersionStep } from "./SpecifyBootVersionStep";
Expand All @@ -14,6 +14,7 @@ import { SpecifyJavaVersionStep } from "./SpecifyJavaVersionStep";
import { SpecifyLanguageStep } from "./SpecifyLanguageStep";
import { SpecifyPackagingStep } from "./SpecifyPackagingStep";
import { SpecifyServiceUrlStep } from "./SpecifyServiceUrlStep";
import { SpecifyPackageNameStep } from "./SpecifyPackageNameStep";

const DEFAULT_SERVICE_URL: string = "https://start.spring.io";

Expand Down Expand Up @@ -133,6 +134,8 @@ export async function createInputBox(inputMetaData: IInputMetaData): Promise<boo
validCheck = groupIdValidation(inputBox.value);
} else if (inputMetaData.pickStep instanceof SpecifyArtifactIdStep) {
validCheck = artifactIdValidation(inputBox.value);
} else if (inputMetaData.pickStep instanceof SpecifyPackageNameStep) {
validCheck = packageNameValidation(inputBox.value);
}
inputBox.validationMessage = validCheck;
}),
Expand All @@ -148,6 +151,10 @@ export async function createInputBox(inputMetaData: IInputMetaData): Promise<boo
inputMetaData.metadata.artifactId = inputBox.value;
SpecifyArtifactIdStep.getInstance().setDefaultInput(inputBox.value);
inputMetaData.metadata.pickSteps.push(SpecifyArtifactIdStep.getInstance());
} else if (inputMetaData.pickStep instanceof SpecifyPackageNameStep) {
inputMetaData.metadata.packageName = inputBox.value;
SpecifyPackageNameStep.getInstance().setDefaultInput(inputBox.value);
inputMetaData.metadata.pickSteps.push(SpecifyPackageNameStep.getInstance());
}
return resolve(true);
}),
Expand All @@ -156,6 +163,8 @@ export async function createInputBox(inputMetaData: IInputMetaData): Promise<boo
return reject(new OperationCanceledError("GroupId not specified."));
} else if (inputMetaData.pickStep instanceof SpecifyArtifactIdStep) {
return reject(new OperationCanceledError("ArtifactId not specified."));
} else if (inputMetaData.pickStep instanceof SpecifyPackageNameStep) {
return reject(new OperationCanceledError("PackageName not specified."));
}
return reject(new Error("Unknown inputting step"));
})
Expand Down

0 comments on commit 8bf8732

Please sign in to comment.