Skip to content

Commit

Permalink
project-name: make it configurable by options (#27545)
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima authored Oct 10, 2024
1 parent 1c882d6 commit 335d0bc
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 60 deletions.
14 changes: 8 additions & 6 deletions cli/jhipster-command.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -185,12 +185,14 @@ export default class JHipsterCommand extends Command {

addJHipsterConfigs(configs = {}, blueprintOptionDescription) {
Object.assign(blueprintOptionDescription ? this.blueprintConfigs : this.configs, configs);
Object.entries(configs).forEach(([name, config]) => {
const option = convertConfigToOption(name, config);
if (option) {
this._addGeneratorOption(kebabCase(option.name), option, blueprintOptionDescription);
}
});
Object.entries(configs)
.filter(([_name, config]) => config.cli)
.forEach(([name, config]) => {
const option = convertConfigToOption(name, config);
if (option) {
this._addGeneratorOption(kebabCase(option.name), option, blueprintOptionDescription);
}
});
return this;
}

Expand Down
1 change: 1 addition & 0 deletions generators/base-application/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ export type CommonClientServerApplication<Entity> = BaseApplication &
SpringBootApplication &
ClientApplication &
ExportApplicationPropertiesFromCommand<typeof import('../git/command.ts').default> &
ExportApplicationPropertiesFromCommand<typeof import('../project-name/command.ts').default> &
ApplicationProperties & {
clientRootDir: string;
clientSrcDir: string;
Expand Down
28 changes: 22 additions & 6 deletions generators/project-name/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,32 @@
* limitations under the License.
*/
import type { JHipsterCommandDefinition } from '../../lib/command/index.js';
import { BASE_NAME, BASE_NAME_DESCRIPTION } from './constants.js';
import { BASE_NAME_DESCRIPTION } from './constants.js';

const command: JHipsterCommandDefinition = {
options: {
[BASE_NAME]: {
const command = {
configs: {
defaultBaseName: {
internal: true,
scope: 'generator',
},
validateBaseName: {
internal: true,
scope: 'generator',
},
baseName: {
description: BASE_NAME_DESCRIPTION,
type: String,
cli: {
type: String,
},
prompt: gen => ({
type: 'input',
validate: input => gen.validateBaseName(input),
message: 'What is the base name of your application?',
default: () => gen.defaultBaseName(),
}),
scope: 'storage',
},
},
};
} as const satisfies JHipsterCommandDefinition;

export default command;
24 changes: 24 additions & 0 deletions generators/project-name/generator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { fileURLToPath } from 'url';
import { describe, expect, it } from 'esmocha';
import { basicTests, testBlueprintSupport } from '../../test/support/tests.js';
import { GENERATOR_PROJECT_NAME } from '../generator-list.js';
import { defaultHelpers as helpers, runResult } from '../../lib/testing/helpers.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Expand All @@ -41,4 +42,27 @@ describe(`generator - ${generator}`, () => {
},
generatorPath,
});
describe('run', () => {
before(async () => {
await helpers.runJHipster(generator);
});
it('should apply default baseName', () => {
expect(runResult.askedQuestions).toMatchInlineSnapshot(`
[
{
"answer": "jhipster",
"name": "baseName",
},
]
`);
});
});
describe('with defaultBaseName option', () => {
before(async () => {
await helpers.runJHipster(generator).withOptions({ defaults: true, defaultBaseName: () => 'foo' });
});
it('should apply default baseName', () => {
runResult.assertJsonFileContent('.yo-rc.json', { 'generator-jhipster': { baseName: 'foo' } });
});
});
});
55 changes: 9 additions & 46 deletions generators/project-name/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@ import BaseApplicationGenerator from '../base-application/index.js';
import { getHipster } from '../base/support/index.js';
import { getDefaultAppName } from './support/index.js';

import { BASE_NAME } from './constants.js';
import { validateProjectName } from './support/name-resolver.js';

/**
* @class
* @extends {BaseApplicationGenerator<import('../base-application/types.js').BaseApplication>}
*/
export default class ProjectNameGenerator extends BaseApplicationGenerator {
javaApplication;
javaApplication?: boolean;
defaultBaseName: () => string = () =>
getDefaultAppName({
reproducible: this.options.reproducible,
javaApplication: this.javaApplication,
});
validateBaseName: (input: string) => boolean | string = (input: string) =>
validateProjectName(input, { javaApplication: this.javaApplication });

async beforeQueue() {
this.sharedData.getControl().existingProject = Boolean(
Expand All @@ -48,10 +50,7 @@ export default class ProjectNameGenerator extends BaseApplicationGenerator {
parseOptions() {
if (this.options.defaults) {
if (!this.jhipsterConfig.baseName) {
this.jhipsterConfig.baseName = getDefaultAppName({
reproducible: this.options.reproducible,
javaApplication: this.javaApplication,
});
this.jhipsterConfig.baseName = this.defaultBaseName();
}
}
},
Expand All @@ -62,29 +61,6 @@ export default class ProjectNameGenerator extends BaseApplicationGenerator {
return this.delegateTasksToBlueprint(() => this.initializing);
}

get prompting() {
return this.asPromptingTaskGroup({
async showPrompts() {
await this.prompt(
[
{
name: BASE_NAME,
type: 'input',
validate: input => this.validateBaseName(input),
message: 'What is the base name of your application?',
default: () => getDefaultAppName({ reproducible: this.options.reproducible, javaApplication: this.javaApplication }),
},
],
this.config,
);
},
});
}

get [BaseApplicationGenerator.PROMPTING]() {
return this.delegateTasksToBlueprint(() => this.prompting);
}

get loading() {
return this.asLoadingTaskGroup({
load({ application }) {
Expand Down Expand Up @@ -121,17 +97,4 @@ export default class ProjectNameGenerator extends BaseApplicationGenerator {
get [BaseApplicationGenerator.PREPARING]() {
return this.delegateTasksToBlueprint(() => this.preparing);
}

/*
* Start of local public API, blueprints may override to customize the generator behavior.
*/

/**
* Validates baseName
* @param {String} input - Base name to be checked
* @returns Boolean
*/
validateBaseName(input) {
return validateProjectName(input, { javaApplication: this.javaApplication });
}
}
3 changes: 2 additions & 1 deletion lib/command/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ export const extractJdlDefinitionFromCommandConfig = (configs: JHipsterConfigs =
.sort((a, b) => (b.name.startsWith(a.name) ? 1 : a.name.localeCompare(b.name)));

export const convertConfigToOption = (name: string, config?: ConfigSpec<any>): JHipsterOption | undefined => {
if (!config?.cli?.type) return undefined;
if (!config?.cli?.type && config?.internal !== true) return undefined;
const choices = config.choices?.map(choice => (typeof choice === 'string' ? choice : choice.value)) as any;
return {
name,
description: config.description,
choices,
scope: config.scope ?? 'storage',
type: val => val,
...config.cli,
};
};
6 changes: 5 additions & 1 deletion lib/command/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type ConfigSpec<ConfigContext> = {
readonly choices?: JHispterChoices;
readonly cli?: CliSpec;
readonly argument?: JHipsterArgumentConfig;
readonly internal?: true;
readonly prompt?:
| PromptSpec
| ((gen: ConfigContext & { jhipsterConfigWithDefaults: Record<string, any> }, config: ConfigSpec<ConfigContext>) => PromptSpec);
Expand Down Expand Up @@ -73,7 +74,10 @@ export type JHipsterArguments = Record<string, JHipsterArgumentConfig>;

export type JHipsterOptions = Record<string, JHipsterOption>;

export type JHipsterConfig<ConfigContext = any> = RequireAtLeastOne<ConfigSpec<ConfigContext>, 'argument' | 'cli' | 'prompt' | 'jdl'>;
export type JHipsterConfig<ConfigContext = any> = RequireAtLeastOne<
ConfigSpec<ConfigContext>,
'argument' | 'cli' | 'prompt' | 'jdl' | 'internal'
>;

export type JHipsterConfigs<ConfigContext = any> = Record<string, JHipsterConfig<ConfigContext>>;

Expand Down
1 change: 1 addition & 0 deletions lib/types/application/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type ApplicationOptions = Simplify<
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/jdl/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/languages/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/liquibase/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/project-name/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/server/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/spring-boot/command.js').default> &
ExportGeneratorOptionsFromCommand<typeof import('../../../generators/spring-cloud/generators/gateway/command.js').default> &
Expand Down
1 change: 1 addition & 0 deletions lib/types/application/yo-rc.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type ApplicationConfiguration = Simplify<
ExportStoragePropertiesFromCommand<typeof import('../../../generators/jdl/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/languages/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/liquibase/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/project-name/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/server/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/spring-boot/command.js').default> &
ExportStoragePropertiesFromCommand<typeof import('../../../generators/spring-cloud/generators/gateway/command.js').default> &
Expand Down

0 comments on commit 335d0bc

Please sign in to comment.