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

add configureCurrentJHipsterCommandConfig and add configure to some c… #26172

Merged
merged 1 commit into from
May 17, 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
40 changes: 38 additions & 2 deletions generators/base-core/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { requireNamespace } from '@yeoman/namespace';
import { GeneratorMeta } from '@yeoman/types';
import chalk from 'chalk';
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
import { kebabCase, snakeCase, merge, get, set } from 'lodash-es';
import { kebabCase, snakeCase, merge, get, set, defaults } from 'lodash-es';
import { simpleGit } from 'simple-git';
import type { CopyOptions } from 'mem-fs-editor';
import type { Data as TemplateData, Options as TemplateOptions } from 'ejs';
Expand All @@ -36,7 +36,13 @@ import type Environment from 'yeoman-environment';
import latestVersion from 'latest-version';
import SharedData from '../base/shared-data.js';
import { CUSTOM_PRIORITIES, PRIORITY_NAMES, PRIORITY_PREFIX } from '../base/priorities.js';
import { createJHipster7Context, formatDateForChangelog, joinCallbacks, Logger } from '../base/support/index.js';
import {
createJHipster7Context,
formatDateForChangelog,
joinCallbacks,
Logger,
removeFieldsWithNullishValues,
} from '../base/support/index.js';

import type {
JHipsterGeneratorOptions,
Expand All @@ -60,6 +66,7 @@ import { GENERATOR_JHIPSTER, YO_RC_FILE } from '../generator-constants.js';
import { convertConfigToOption } from '../../lib/internal/index.js';
import { getGradleLibsVersionsProperties } from '../gradle/support/dependabot-gradle.js';
import { dockerPlaceholderGenerator } from '../docker/utils.js';
import { getConfigWithDefaults } from '../../jdl/index.js';

const {
INITIALIZING,
Expand Down Expand Up @@ -228,6 +235,20 @@ export default class CoreGenerator extends YeomanGenerator<JHipsterGeneratorOpti
return this._needleApi;
}

/**
* JHipster config with default values fallback
*/
get jhipsterConfigWithDefaults() {
const configWithDefaults = getConfigWithDefaults(removeFieldsWithNullishValues(this.config.getAll()));
defaults(configWithDefaults, {
skipFakeData: false,
skipCheckLengthOfIdentifier: false,
enableGradleEnterprise: false,
pages: [],
});
return configWithDefaults;
}

/**
* Warn or throws check failure based on current skipChecks option.
* @param message
Expand Down Expand Up @@ -343,6 +364,21 @@ You can ignore this error by passing '--skip-checks' to jhipster command.`);
return this.prompt(this.prepareQuestions(generatorCommand.configs));
}

/**
* Configure the current JHipster command.
* Blueprints with command override takes precedence.
*/
async configureCurrentJHipsterCommandConfig() {
const generatorCommand = await this.getCurrentJHipsterCommand();
if (!generatorCommand.configs) {
throw new Error(`Configs not found for generator ${this.options.namespace}`);
}

for (const def of Object.values(generatorCommand.configs)) {
def.configure?.(this);
}
}

/**
* Load the current JHipster command storage configuration into the context.
* Blueprints with command override takes precedence.
Expand Down
4 changes: 4 additions & 0 deletions generators/base/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ export type ConfigSpec = {
* The callback receives blueprintStorage contents as input for 'blueprint' scope.
*/
default?: string | boolean | string[] | ((any) => string | boolean | string[]);
/**
* Configure the generator according to the selected configuration.
*/
configure?: (gen: CoreGenerator) => void;
};

export type JHipsterArguments = Record<string, JHipsterArgumentConfig>;
Expand Down
18 changes: 1 addition & 17 deletions generators/base/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@ import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import semver from 'semver';
import { defaults } from 'lodash-es';

import type { ComposeOptions } from 'yeoman-generator';
import { packageJson } from '../../lib/index.js';
import { packageNameToNamespace, removeFieldsWithNullishValues } from './support/index.js';
import { packageNameToNamespace } from './support/index.js';
import { mergeBlueprints, parseBluePrints, loadBlueprintsFromConfiguration, normalizeBlueprintName } from './internal/index.js';
import { PRIORITY_NAMES } from './priorities.js';
import { BaseGeneratorDefinition, GenericTaskGroup } from './tasks.js';
import type { JHipsterGeneratorFeatures, JHipsterGeneratorOptions } from './api.js';
import CoreGenerator from '../base-core/index.js';
import { LOCAL_BLUEPRINT_PACKAGE_NAMESPACE } from './support/constants.js';
import { getConfigWithDefaults } from '../../jdl/index.js';
import { loadStoredAppOptions } from '../app/support/index.js';

/**
Expand Down Expand Up @@ -443,20 +441,6 @@ export default class JHipsterBaseBlueprintGenerator<
return taskGroup;
}

/**
* JHipster config with default values fallback
*/
get jhipsterConfigWithDefaults() {
const configWithDefaults = getConfigWithDefaults(removeFieldsWithNullishValues(this.config.getAll()));
defaults(configWithDefaults, {
skipFakeData: false,
skipCheckLengthOfIdentifier: false,
enableGradleEnterprise: false,
pages: [],
});
return configWithDefaults;
}

/**
* @protected
* Composes with blueprint generators, if any.
Expand Down
77 changes: 3 additions & 74 deletions generators/server/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { existsSync } from 'fs';
import chalk from 'chalk';

import {
getDBTypeFromDBValue,
buildJavaGet as javaGetCall,
javaBeanCase as javaBeanClassNameFormat,
buildJavaGetter as javaGetter,
Expand Down Expand Up @@ -52,7 +51,6 @@ import {

import {
applicationTypes,
authenticationTypes,
buildToolTypes,
databaseTypes,
fieldTypes,
Expand All @@ -63,7 +61,7 @@ import {
clientFrameworkTypes,
} from '../../jdl/jhipster/index.js';
import { stringifyApplicationData } from '../base-application/support/index.js';
import { createBase64Secret, createSecret, createNeedleCallback, mutateData } from '../base/support/index.js';
import { createNeedleCallback, mutateData } from '../base/support/index.js';
import { isReservedPaginationWords } from '../../jdl/jhipster/reserved-keywords.js';
import { loadStoredAppOptions } from '../app/support/index.js';
import { isReservedH2Keyword } from '../spring-data-relational/support/h2-reserved-keywords.js';
Expand All @@ -85,10 +83,9 @@ const {
const { SUPPORTED_VALIDATION_RULES } = validations;
const { isReservedTableName } = reservedKeywords;
const { ANGULAR, REACT, VUE } = clientFrameworkTypes;
const { JWT, OAUTH2, SESSION } = authenticationTypes;
const { GRADLE, MAVEN } = buildToolTypes;
const { CASSANDRA, COUCHBASE, MONGODB, NEO4J, SQL, NO: NO_DATABASE } = databaseTypes;
const { MICROSERVICE, GATEWAY } = applicationTypes;
const { CASSANDRA, SQL, NO: NO_DATABASE } = databaseTypes;
const { GATEWAY } = applicationTypes;

const { NO: NO_SEARCH_ENGINE } = searchEngineTypes;
const { CommonDBTypes, RelationalOnlyDBTypes } = fieldTypes;
Expand Down Expand Up @@ -146,37 +143,6 @@ export default class JHipsterServerGenerator extends BaseApplicationGenerator {
return this.delegateTasksToBlueprint(() => this.prompting);
}

get configuring() {
return this.asConfiguringTaskGroup({
configuring() {
if (process.env.JHI_WAR === '1') {
this.jhipsterConfig.defaultPackaging = 'war';
}
},
configServerPort() {
if (!this.jhipsterConfig.serverPort && this.jhipsterConfig.applicationIndex) {
this.jhipsterConfig.serverPort = 8080 + this.jhipsterConfig.applicationIndex;
}
},
configure() {
this._configureServer();
},
syncUserWithIdp() {
if (this.jhipsterConfig.syncUserWithIdp === undefined && this.jhipsterConfig.authenticationType === OAUTH2) {
if (this.isJhipsterVersionLessThan('8.1.1')) {
this.jhipsterConfig.syncUserWithIdp = true;
}
} else if (this.jhipsterConfig.syncUserWithIdp && this.jhipsterConfig.authenticationType !== OAUTH2) {
throw new Error(`syncUserWithIdp is only supported with authenticationType ${OAUTH2}`);
}
},
});
}

get [BaseApplicationGenerator.CONFIGURING]() {
return this.delegateTasksToBlueprint(() => this.configuring);
}

get composing() {
return this.asComposingTaskGroup({
async composeCommand() {
Expand Down Expand Up @@ -614,43 +580,6 @@ export default class JHipsterServerGenerator extends BaseApplicationGenerator {
return this.delegateTasksToBlueprint(() => this.postWriting);
}

_configureServer(config = this.jhipsterConfigWithDefaults, dest = this.jhipsterConfig) {
// Generate JWT secret key if key does not already exist in config
if (
(config.authenticationType === JWT || config.applicationType === MICROSERVICE || config.applicationType === GATEWAY) &&
config.jwtSecretKey === undefined
) {
dest.jwtSecretKey = createBase64Secret(64, this.options.reproducibleTests);
}
// Generate remember me key if key does not already exist in config
if (config.authenticationType === SESSION && !dest.rememberMeKey) {
dest.rememberMeKey = createSecret();
}

if (config.authenticationType === OAUTH2) {
dest.skipUserManagement = true;
}

if (!config.databaseType && config.prodDatabaseType) {
dest.databaseType = getDBTypeFromDBValue(config.prodDatabaseType);
}
if (!config.devDatabaseType && config.prodDatabaseType) {
dest.devDatabaseType = config.prodDatabaseType;
}

const databaseType = config.databaseType;
if (databaseType === NO_DATABASE) {
dest.devDatabaseType = NO_DATABASE;
dest.prodDatabaseType = NO_DATABASE;
dest.enableHibernateCache = false;
dest.skipUserManagement = true;
} else if ([MONGODB, NEO4J, COUCHBASE, CASSANDRA].includes(databaseType)) {
dest.devDatabaseType = databaseType;
dest.prodDatabaseType = databaseType;
dest.enableHibernateCache = false;
}
}

/**
* Validate the entityTableName
* @return {true|string} true for a valid value or error message.
Expand Down
33 changes: 33 additions & 0 deletions generators/spring-boot/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import chalk from 'chalk';
import { JHipsterCommandDefinition } from '../base/api.js';
import { GENERATOR_JAVA, GENERATOR_LIQUIBASE, GENERATOR_SPRING_DATA_RELATIONAL } from '../generator-list.js';
import { createBase64Secret, createSecret } from '../base/support/secret.js';

const command: JHipsterCommandDefinition = {
options: {
Expand Down Expand Up @@ -51,6 +52,11 @@ const command: JHipsterCommandDefinition = {
'As you are running in a microservice architecture, on which port would like your server to run? It should be unique to avoid port conflicts.',
default: () => gen.jhipsterConfigWithDefaults.serverPort,
}),
configure: gen => {
if (gen.jhipsterConfig.serverPort === undefined && gen.jhipsterConfig.applicationIndex !== undefined) {
gen.jhipsterConfig.serverPort = 8080 + gen.jhipsterConfig.applicationIndex;
}
},
},
serviceDiscoveryType: {
cli: {
Expand Down Expand Up @@ -89,6 +95,19 @@ const command: JHipsterCommandDefinition = {
{ value: 'oauth2', name: 'OAuth 2.0 / OIDC Authentication (stateful, works with Keycloak and Okta)' },
{ value: 'session', name: 'HTTP Session Authentication (stateful, default Spring Security mechanism)' },
],
configure: gen => {
const { jwtSecretKey, rememberMeKey, authenticationType, applicationType } = gen.jhipsterConfigWithDefaults;
if (authenticationType === 'session' && !rememberMeKey) {
gen.jhipsterConfig.rememberMeKey = createSecret();
} else if (authenticationType === 'oauth2' && gen.jhipsterConfig.skipUserManagement === undefined) {
gen.jhipsterConfig.skipUserManagement = true;
} else if (
jwtSecretKey === undefined &&
(authenticationType === 'jwt' || applicationType === 'microservice' || applicationType === 'gateway')
) {
gen.jhipsterConfig.jwtSecretKey = createBase64Secret(64, gen.options.reproducibleTests);
}
},
},
feignClient: {
description: 'Generate a feign client',
Expand All @@ -114,6 +133,15 @@ const command: JHipsterCommandDefinition = {
message: 'Do you want to allow relationships with User entity?',
when: ({ authenticationType }) => (authenticationType ?? gen.jhipsterConfigWithDefaults.authenticationType) === 'oauth2',
}),
configure: gen => {
if (gen.jhipsterConfig.syncUserWithIdp === undefined && gen.jhipsterConfigWithDefaults.authenticationType === 'oauth2') {
if (gen.isJhipsterVersionLessThan('8.1.1')) {
gen.jhipsterConfig.syncUserWithIdp = true;
}
} else if (gen.jhipsterConfig.syncUserWithIdp && gen.jhipsterConfig.authenticationType !== 'oauth2') {
throw new Error('syncUserWithIdp is only supported with authenticationType oauth2');
}
},
},
defaultPackaging: {
description: 'Default packaging for the application',
Expand All @@ -124,6 +152,11 @@ const command: JHipsterCommandDefinition = {
choices: ['jar', 'war'],
default: 'jar',
scope: 'storage',
configure: gen => {
if (process.env.JHI_WAR === '1') {
gen.jhipsterConfig.defaultPackaging = 'war';
}
},
},
},
import: [GENERATOR_JAVA, GENERATOR_LIQUIBASE, GENERATOR_SPRING_DATA_RELATIONAL],
Expand Down
16 changes: 14 additions & 2 deletions generators/spring-boot/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ export default class SpringBootGenerator extends BaseApplicationGenerator {

get configuring() {
return this.asConfiguringTaskGroup({
async configureCommand() {
await this.configureCurrentJHipsterCommandConfig();
},
checks() {
const config = this.jhipsterConfigWithDefaults;
if (config.enableHibernateCache && [NO_CACHE, MEMCACHED].includes(config.cacheProvider)) {
Expand Down Expand Up @@ -235,11 +238,20 @@ export default class SpringBootGenerator extends BaseApplicationGenerator {
return this.delegateTasksToBlueprint(() => this.composingComponent);
}

get preparing() {
return this.asPreparingTaskGroup({
get loading() {
return this.asLoadingTaskGroup({
async loadCommand({ application }) {
await this.loadCurrentJHipsterCommandConfig(application);
},
});
}

get [BaseApplicationGenerator.LOADING]() {
return this.delegateTasksToBlueprint(() => this.loading);
}

get preparing() {
return this.asPreparingTaskGroup({
checksWebsocket({ application }) {
const { websocket } = application as any;
if (websocket && websocket !== NO_WEBSOCKET) {
Expand Down
Loading