Skip to content

Commit

Permalink
RESTEasy can be excluded if using code.quarkus.io
Browse files Browse the repository at this point in the history
Reads the data from code.quarkus.io or code.quarkus.redhat.com
to see which quarkus extensions are required.
This means if code.quarkus.io is used, then resteasy is not required.
Reads the Open API of the code quarkus instance to determine if
the option to prevent sample code being generated is present.
If it is, then it adds another step to the project
generation wizard to specify if sample code should be generated.

Closes redhat-developer#322

Signed-off-by: David Thompson <davthomp@redhat.com>
  • Loading branch information
datho7561 committed Mar 5, 2021
1 parent 830535e commit accb343
Show file tree
Hide file tree
Showing 8 changed files with 7,967 additions and 3,337 deletions.
11,188 changes: 7,859 additions & 3,329 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,14 @@
"test-all": "npm test && npm run test-ui-run"
},
"resolutions": {
"minimist": "^1.2.5"
"minimist": "1.2.5"
},
"devDependencies": {
"@types/chai": "^4.2.3",
"@types/chai-fs": "^2.0.2",
"@types/ejs": "^3.0.5",
"@types/fs-extra": "^7.0.0",
"@types/js-yaml": "^4.0.0",
"@types/lodash": "^4.14.149",
"@types/mocha": "^5.2.6",
"@types/node": "^10.14.16",
Expand Down Expand Up @@ -285,6 +287,7 @@
"find-up": "^4.1.0",
"fs-extra": "^8.0.1",
"glob": "^7.1.4",
"js-yaml": "^4.0.0",
"lodash": "^4.17.15",
"request": "^2.88.0",
"request-promise": "^4.2.4",
Expand Down
7 changes: 4 additions & 3 deletions src/definitions/QExtension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ export class QExtension {
artifactId: string;
isRequired: boolean;

constructor(name: string, category: string, description: string, labels: string[], groupId: string, artifactId: string) {
constructor(name: string, category: string, description: string, labels: string[], groupId: string, artifactId: string, isRequired) {
this.name = name;
this.category = category;
this.description = description;
this.labels = labels;
this.groupId = groupId;
this.artifactId = artifactId;
this.isRequired = name === 'RESTEasy JAX-RS'; // 'RESTEasy JAX-RS' is included in every Quarkus project
this.isRequired = isRequired;
}

getGroupIdArtifactIdString() {
Expand All @@ -61,7 +61,7 @@ export function convertToQExtension(extension: APIExtension): QExtension {
artifactId = extension.id;
}
return new QExtension(extension.name, extension.category, extension.description,
extension.labels, groupId, artifactId);
extension.labels, groupId, artifactId, extension.default);
}

/**
Expand All @@ -76,4 +76,5 @@ export interface APIExtension {
shortName: string;
category: string;
order: Number;
default: boolean; // Uses a TypeScript builtin :|
}
1 change: 1 addition & 0 deletions src/definitions/inputState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface ProjectGenState extends State {
packageName: string;
resourceName: string;
targetDir: Uri;
isGenerateSampleCode: boolean;
}

export interface AddExtensionsState extends State {
Expand Down
66 changes: 66 additions & 0 deletions src/utils/codeQuarkusApiUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { IncomingMessage } from "http";
import * as https from "https";
import * as yaml from "js-yaml";
import * as path from "path";
import { QuarkusConfig } from "../QuarkusConfig";

export namespace CodeQuarkusApiUtils {

export interface Functionality {
canExcludeSampleCode: boolean;
}

/**
* Returns the capabilities of the Code Quarkus API instance that is defined in the user settings
*
* @returns the capabilities of the Code Quarkus API instance that is defined in the user settings
* @throws if something goes wrong when getting the functionality from OpenAPI
*/
export async function getCodeQuarkusApiFunctionality(): Promise<Functionality> {
const oldOpenApiUrl: string = path.dirname(QuarkusConfig.getApiUrl()) + '/openapi';
const newOpenApiUrl: string = path.dirname(QuarkusConfig.getApiUrl()) + '/q/openapi';
let openApiYaml: string;
try {
openApiYaml = await httpsGet(oldOpenApiUrl);
} catch {
openApiYaml = await httpsGet(newOpenApiUrl);
}
const openApiData: any = yaml.load(openApiYaml);

return {
canExcludeSampleCode: openApiData?.paths?.['/api/download']?.get?.parameters?.filter(p => p?.name === 'ne').length > 0
} as Functionality;
}

/**
* Returns a set of capabilities that are implemented by all Code Quarkus APIs
*
* @returns a set of capabilities that are implemented by all Code Quarkus APIs
*/
export function getDefaultFunctionality() {
return {
canExcludeSampleCode: false
} as Functionality;
}

/**
* Returns the GET response body if the code is 200 and rejects otherwise
*
* @param url URL to GET
* @returns the response body if the code is 200 and rejects otherwise
* @throws if anything goes wrong (not 200 response, any other errors during get)
*/
async function httpsGet(url: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
https.get(url, (res: IncomingMessage) => {
if (res.statusCode !== 200) {
reject(`${res.statusCode}: ${res.statusMessage}`);
}
res.on('data', (d: Buffer) => {
resolve(d.toString('utf8'));
});
})
.on('error', reject);
});
}
}
1 change: 1 addition & 0 deletions src/utils/requestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export async function downloadProject(state: ProjectGenState): Promise<ZipFile>
`a=${state.artifactId}&` +
`v=${state.projectVersion}&` +
`c=${state.packageName}.${state.resourceName}&` +
`${(state.isGenerateSampleCode === undefined ? '' : `ne=${!state.isGenerateSampleCode}&`)}` +
`e=${chosenIds.join('&e=')}`;

const buffer: Buffer = await tryGetProjectBuffer(qProjectUrl);
Expand Down
33 changes: 30 additions & 3 deletions src/wizards/generateProject/generationWizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import { BuildToolName, INPUT_TITLE } from '../../definitions/constants';
import { ProjectGenState } from '../../definitions/inputState';
import { QExtension } from '../../definitions/QExtension';
import { QuarkusContext } from '../../QuarkusContext';
import { MultiStepInput } from '../../utils/multiStepUtils';
import { MultiStepInput, QuickPickParameters } from '../../utils/multiStepUtils';
import { downloadProject } from '../../utils/requestUtils';
import { ExtensionsPicker } from './ExtensionsPicker';
import { validateArtifactId, validateGroupId, validatePackageName, validateResourceName, validateVersion } from './validateInput';
import { CodeQuarkusApiUtils } from '../../utils/codeQuarkusApiUtils';

/**
* A multi-step input using window.createQuickPick() and window.createInputBox().
Expand All @@ -24,8 +25,15 @@ import { validateArtifactId, validateGroupId, validatePackageName, validateResou
*/
export async function generateProjectWizard() {

let apiCapabilities: CodeQuarkusApiUtils.Functionality;
try {
apiCapabilities = await CodeQuarkusApiUtils.getCodeQuarkusApiFunctionality();
} catch (e) {
apiCapabilities = CodeQuarkusApiUtils.getDefaultFunctionality();
}

const state: Partial<ProjectGenState> = {
totalSteps: 7
totalSteps: 7 + (apiCapabilities.canExcludeSampleCode ? 1 : 0)
};

async function collectInputs(state: Partial<ProjectGenState>) {
Expand Down Expand Up @@ -139,7 +147,26 @@ export async function generateProjectWizard() {
prompt: 'Your resource name',
validate: validateResourceName
});
return (input: MultiStepInput) => ExtensionsPicker.createExtensionsPicker(input, state, { showLastUsed: true, showRequiredExtensions: true, allowZeroExtensions: true });
return (input: MultiStepInput) => ExtensionsPicker.createExtensionsPicker(
input, state, { showLastUsed: true, showRequiredExtensions: true, allowZeroExtensions: true },
(apiCapabilities.canExcludeSampleCode ? inputGenerateSampleCode: undefined));
}

async function inputGenerateSampleCode(input: MultiStepInput, state: Partial<ProjectGenState>) {
const YES: string = 'Include sample code';
const NO: string = 'Do not include sample code';
const quickPickItems: QuickPickItem[] = [
{label: YES, picked: true},
{label: NO}
];

state.isGenerateSampleCode = (await input.showQuickPick<QuickPickItem, QuickPickParameters<QuickPickItem>>({
title: INPUT_TITLE,
placeholder: 'Should sample code be included? Additional dependencies may be added along with the sample.',
step: input.getStepNumber(),
totalSteps: state.totalSteps,
items: quickPickItems,
})).label === YES;
}

try {
Expand Down
3 changes: 2 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@
},
"linterOptions": {
"exclude": [
"test-resources"
"test-resources",
"out/**/*"
]
}
}

0 comments on commit accb343

Please sign in to comment.