diff --git a/generators/base-core/generator.ts b/generators/base-core/generator.ts index f44adcd8fb83..1bb66c8d4a23 100644 --- a/generators/base-core/generator.ts +++ b/generators/base-core/generator.ts @@ -862,23 +862,26 @@ You can ignore this error by passing '--skip-checks' to jhipster command.`); } const normalizeEjs = file => file.replace('.ejs', ''); - const resolveCallback = (val, fallback?) => { - if (val === undefined) { + const resolveCallback = (maybeCallback, fallback?) => { + if (maybeCallback === undefined) { if (typeof fallback === 'function') { return resolveCallback(fallback); } return fallback; } - if (typeof val === 'boolean' || typeof val === 'string') { - return val; + if (typeof maybeCallback === 'boolean' || typeof maybeCallback === 'string') { + return maybeCallback; } - if (typeof val === 'function') { - return val.call(this, templateData) || false; + if (typeof maybeCallback === 'function') { + return (maybeCallback as any).call(this, templateData) || false; } - throw new Error(`Type not supported ${val}`); + throw new Error(`Type not supported ${maybeCallback}`); }; - const renderTemplate = async ({ sourceFile, destinationFile, options, noEjs, transform, binary }) => { + const renderTemplate = async ({ condition, sourceFile, destinationFile, options, noEjs, transform, binary }) => { + if (condition !== undefined && !resolveCallback(condition, true)) { + return undefined; + } const extension = extname(sourceFile); const isBinary = binary || ['.png', '.jpg', '.gif', '.svg', '.ico'].includes(extension); const appendEjs = noEjs === undefined ? !isBinary && extension !== '.ejs' : !noEjs; @@ -1068,7 +1071,7 @@ templates: ${JSON.stringify(existingTemplates, null, 2)}`; return { sourceFile, destinationFile, noEjs, transform: derivedTransform }; } - const { options, file, renameTo, transform: fileTransform = [], binary } = fileSpec; + const { condition, options, file, renameTo, transform: fileTransform = [], binary } = fileSpec; let { sourceFile, destinationFile } = fileSpec; if (typeof fileTransform === 'boolean') { @@ -1103,6 +1106,7 @@ templates: ${JSON.stringify(existingTemplates, null, 2)}`; } return { + condition, sourceFile, destinationFile, options, @@ -1123,7 +1127,7 @@ templates: ${JSON.stringify(existingTemplates, null, 2)}`; }); } - const files = await Promise.all(parsedTemplates.map(template => renderTemplate(template))); + const files = await Promise.all(parsedTemplates.map(template => renderTemplate(template)).filter(Boolean)); this.log.debug(`Time taken to write files: ${new Date().getMilliseconds() - startTime}ms`); return files.filter(file => file); } diff --git a/generators/base/api.d.ts b/generators/base/api.d.ts index 1460bd7ed4d4..1643fc73b37f 100644 --- a/generators/base/api.d.ts +++ b/generators/base/api.d.ts @@ -118,16 +118,19 @@ export type CascatedEditFileCallback = ( ...callbacks: EditFileCallback[] ) => CascatedEditFileCallback; +type DataCallback, Generator = CoreGenerator> = Type | ((this: Generator, data: DataType) => Type); + export type WriteFileTemplate, Generator = CoreGenerator> = | string | ((this: Generator, data: DataType, filePath: string) => string) | { + condition?: DataCallback; /** source file */ - sourceFile?: string | ((this: Generator, data: DataType) => string); + sourceFile?: DataCallback; /** destination file */ - destinationFile?: string | ((this: Generator, destinationFile: DataType) => string); + destinationFile?: DataCallback; /** @deprecated, use sourceFile instead */ - file?: string | ((this: Generator, data: DataType) => string); + file?: DataCallback; /** @deprecated, use destinationFile instead */ renameTo?: string | ((this: Generator, data: DataType, filePath: string) => string); /** transforms (files processing) to be applied */ @@ -136,7 +139,7 @@ export type WriteFileTemplate, Generator = Co binary?: boolean; /** ejs options. Refer to https://ejs.co/#docs */ options?: Record; - override?: boolean | ((this: Generator, data: DataType) => boolean); + override?: DataCallback; }; export type WriteFileBlock, Generator = CoreGenerator> = { diff --git a/generators/generate-blueprint/command.ts b/generators/generate-blueprint/command.ts index 4973b0446df6..4ede3d2dd6d3 100644 --- a/generators/generate-blueprint/command.ts +++ b/generators/generate-blueprint/command.ts @@ -40,6 +40,20 @@ const command = { }, scope: 'generator', }, + skipWorkflows: { + description: 'Skip github workflows', + cli: { + type: Boolean, + }, + scope: 'generator', + }, + ignoreExistingGenerators: { + description: 'Ignore existing generators', + cli: { + type: Boolean, + }, + scope: 'generator', + }, githubRepository: { cli: { description: 'Github Repository', diff --git a/generators/generate-blueprint/files.ts b/generators/generate-blueprint/files.ts index 5d9120501ef5..62737bba1fa0 100644 --- a/generators/generate-blueprint/files.ts +++ b/generators/generate-blueprint/files.ts @@ -27,7 +27,10 @@ export const files = asWriteFilesSection({ '.github/workflows/generator.yml', '.prettierignore.jhi.blueprint', { sourceFile: 'eslint.config.js.jhi.blueprint', destinationFile: ctx => `${ctx.eslintConfigFile}.jhi.blueprint` }, - 'README.md', + { + sourceFile: 'README.md', + override: data => !data.ignoreExistingGenerators, + }, 'tsconfig.json', 'vitest.config.ts', '.blueprint/cli/commands.mjs', @@ -39,7 +42,7 @@ export const files = asWriteFilesSection({ ], }, { - condition: ctx => !ctx[LOCAL_BLUEPRINT_OPTION] && ctx.githubWorkflows, + condition: ctx => !ctx[LOCAL_BLUEPRINT_OPTION] && ctx.githubWorkflows && !ctx.skipWorkflows, templates: [ '.blueprint/github-build-matrix/build-matrix.mjs', '.blueprint/github-build-matrix/generator.mjs', @@ -59,30 +62,28 @@ export const files = asWriteFilesSection({ ], }); -export const generatorFiles = { +export const generatorFiles = asWriteFilesSection({ generator: [ { path: 'generators/generator', to: ctx => `${ctx.application.blueprintsPath}${ctx.generator}`, templates: [ - { file: 'generator.mjs.jhi', renameTo: ctx => (ctx.js ? 'generator.js.jhi' : 'generator.mjs.jhi') }, - { file: 'index.mjs', renameTo: ctx => (ctx.js ? 'index.js' : 'index.mjs') }, - ], - }, - { - path: 'generators/generator', - condition: ctx => ctx.priorities.find(priority => priority.name === 'initializing'), - to: ctx => `${ctx.application.blueprintsPath}${ctx.generator}`, - templates: [{ file: 'command.mjs', renameTo: ctx => (ctx.js ? 'command.js' : 'command.mjs') }], - }, - { - path: 'generators/generator', - to: ctx => `${ctx.application.blueprintsPath}${ctx.generator}`, - condition: ctx => !ctx.generator.startsWith('entity') && !ctx.application[LOCAL_BLUEPRINT_OPTION], - templates: [ + { sourceFile: 'index.mjs', destinationFile: ctx => (ctx.js ? 'index.js' : 'index.mjs') }, + { + sourceFile: 'command.mjs', + destinationFile: ctx => (ctx.js ? 'command.js' : 'command.mjs'), + override: data => !data.ignoreExistingGenerators, + }, + { + sourceFile: 'generator.mjs.jhi', + destinationFile: ctx => (ctx.js ? 'generator.js.jhi' : 'generator.mjs.jhi'), + override: data => !data.ignoreExistingGenerators, + }, { - file: 'generator.spec.mjs', - renameTo: ctx => (ctx.js ? 'generator.spec.js' : 'generator.spec.mjs'), + condition: data => !data.generator.startsWith('entity') && !data.application[LOCAL_BLUEPRINT_OPTION], + sourceFile: 'generator.spec.mjs', + destinationFile: data => (data.js ? 'generator.spec.js' : 'generator.spec.mjs'), + override: data => !data.ignoreExistingGenerators, }, ], }, @@ -95,10 +96,10 @@ export const generatorFiles = { transform: false, templates: [ { - file: 'templates/template-file.ejs', - renameTo: ctx => `templates/template-file-${ctx.generator}.ejs`, + sourceFile: 'templates/template-file.ejs', + destinationFile: ctx => `templates/template-file-${ctx.generator}.ejs`, }, ], }, ], -}; +}); diff --git a/generators/generate-blueprint/generator.ts b/generators/generate-blueprint/generator.ts index d2f29cbed949..44efe38ca959 100644 --- a/generators/generate-blueprint/generator.ts +++ b/generators/generate-blueprint/generator.ts @@ -55,6 +55,8 @@ const defaultPublishedFiles = ['generators', '!**/__*', '!**/*.snap', '!**/*.spe export default class extends BaseGenerator { application!: any; recreatePackageLock!: boolean; + skipWorkflows!: boolean; + ignoreExistingGenerators!: boolean; async _beforeQueue() { if (!this.fromBlueprint) { @@ -213,16 +215,23 @@ export default class extends BaseGenerator { '8.7.2': ['vitest.test-setup.ts'], }); }, - async writing() { + async writing({ application }) { this.application.sampleWritten = this.jhipsterConfig.sampleWritten; + const { skipWorkflows, ignoreExistingGenerators } = this; await this.writeFiles({ sections: files, - context: this.application, + context: { + ...application, + skipWorkflows, + ignoreExistingGenerators, + ...this.application, + }, }); this.jhipsterConfig.sampleWritten = true; }, async writingGenerators() { if (!this.application[GENERATORS]) return; + const { skipWorkflows, ignoreExistingGenerators } = this; for (const generator of Object.keys(this.application[GENERATORS])) { const subGeneratorStorage = this.getSubGeneratorStorage(generator); const subGeneratorConfig = subGeneratorStorage.getAll(); @@ -234,6 +243,8 @@ export default class extends BaseGenerator { const customGenerator = !Object.values(GENERATOR_LIST).includes(generator); const jhipsterGenerator = customGenerator || subGeneratorConfig.sbs ? 'base-application' : generator; const subTemplateData = { + skipWorkflows, + ignoreExistingGenerators, js: this.application.js, application: this.application, ...defaultSubGeneratorConfig(),