UNPKG

gen-jhipster

Version:

VHipster - Spring Boot + Angular/React/Vue in one handy generator

211 lines (210 loc) 9.27 kB
/** * Copyright 2013-2026 the original author or authors from the JHipster project. * * This file is part of the JHipster project, see https://www.jhipster.tech/ * for more information. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { rm } from 'node:fs/promises'; import { createConflicterTransform, createYoResolveTransform, forceYoFiles } from '@yeoman/conflicter'; import { transform } from '@yeoman/transform'; import { isFilePending, isFileStateModified } from 'mem-fs-editor/state'; import { createCommitTransform } from 'mem-fs-editor/transform'; import BaseGenerator, { CommandBaseGenerator } from "../base/index.js"; import { PRIORITY_NAMES, QUEUES } from "../base-application/priorities.js"; import { createNeedleTransform } from "../base-core/support/needles.js"; import { PRETTIER_EXTENSIONS } from "../generator-constants.js"; import { autoCrlfTransform, createESLintTransform, createForceWriteConfigFilesTransform, createMultiStepTransform, createPrettierTransform, createRemoveUnusedImportsTransform, createSortConfigFilesTransform, isPrettierConfigFilePath, } from "./support/index.js"; const { MULTISTEP_TRANSFORM, PRE_CONFLICTS } = PRIORITY_NAMES; const { MULTISTEP_TRANSFORM_QUEUE, PRE_CONFLICTS_QUEUE } = QUEUES; const MULTISTEP_TRANSFORM_PRIORITY = BaseGenerator.asPriority(MULTISTEP_TRANSFORM); const PRE_CONFLICTS_PRIORITY = BaseGenerator.asPriority(PRE_CONFLICTS); export default class BootstrapGenerator extends CommandBaseGenerator { static MULTISTEP_TRANSFORM = MULTISTEP_TRANSFORM_PRIORITY; static PRE_CONFLICTS = PRE_CONFLICTS_PRIORITY; upgradeCommand; skipPrettier; skipEslint; prettierExtensions = PRETTIER_EXTENSIONS.split(','); prettierOptions = { plugins: [] }; refreshOnCommit = false; constructor(args, options, features) { super(args, options, { uniqueGlobally: true, customCommitTask: () => this.commitTask(), ...features }); } async beforeQueue() { // Force npm override later if needed this.env.options.nodePackageManager = 'npm'; this.upgradeCommand = this.options.commandName === 'upgrade'; if (!this.fromBlueprint) { await this.composeWithBlueprints(); } if (this.delegateToBlueprint) { throw new Error('Only sbs blueprint is supported'); } } get multistepTransform() { return { queueMultistepTransform() { this.queueMultistepTransform(); }, }; } get [MULTISTEP_TRANSFORM_PRIORITY]() { return this.multistepTransform; } get preConflicts() { return this.asAnyTaskGroup({ queueCommitPrettierConfig() { this.queueCommitPrettierConfig(); }, }); } get [PRE_CONFLICTS_PRIORITY]() { return this.preConflicts; } /** * Queue multi step templates transform */ queueMultistepTransform() { const templateData = { ...this.jhipsterConfig }; const multiStepTransform = createMultiStepTransform(templateData); const listener = (filePath) => { if (multiStepTransform.templateFileFs.isTemplate(filePath)) { this.env.sharedFs.removeListener('change', listener); this.queueMultistepTransform(); } }; this.queueTask({ method: async () => { await this.pipeline({ name: 'applying multi-step templates', filter: file => isFileStateModified(file) && multiStepTransform.templateFileFs.isTemplate(file.path), refresh: true, resolveConflict: (current, newFile) => (isFileStateModified(current) ? current : newFile), }, multiStepTransform); this.env.sharedFs.on('change', listener); }, taskName: MULTISTEP_TRANSFORM_QUEUE, queueName: MULTISTEP_TRANSFORM_QUEUE, once: true, }); } queueCommitPrettierConfig() { const listener = (filePath) => { if (isPrettierConfigFilePath(filePath)) { this.env.sharedFs.removeListener('change', listener); this.queueCommitPrettierConfig(); } }; this.queueTask({ method: async () => { await this.commitPrettierConfig(); this.env.sharedFs.on('change', listener); }, taskName: 'commitPrettierConfig', queueName: PRE_CONFLICTS_QUEUE, once: true, }); } async commitPrettierConfig() { await this.commitSharedFs({ log: 'prettier configuration files committed to disk', filter: file => isPrettierConfigFilePath(file.path), }); } async commitTask() { await this.commitSharedFs({ refresh: this.refreshOnCommit }, ...this.env.findFeature('commitTransformFactory').flatMap(({ feature }) => feature())); } /** * Commits the MemFs to the disc. */ async commitSharedFs({ log, ...options } = {}, ...transforms) { const skipYoResolveTransforms = []; if (!this.options.skipYoResolve) { skipYoResolveTransforms.push(createYoResolveTransform()); } const prettierTransforms = []; if (!this.skipPrettier) { const ignoreErrors = this.options.ignoreErrors || this.upgradeCommand; if (!this.skipEslint) { prettierTransforms.push(await createESLintTransform.call(this, { ignoreErrors }), await createRemoveUnusedImportsTransform.call(this, { ignoreErrors })); } prettierTransforms.push(await createPrettierTransform.call(this, { ignoreErrors, prettierPackageJson: true, prettierJava: !this.jhipsterConfig.skipServer, extensions: this.prettierExtensions.join(','), prettierOptions: this.prettierOptions, })); } const autoCrlfTransforms = []; if (this.jhipsterConfigWithDefaults.autoCrlf) { autoCrlfTransforms.push(await autoCrlfTransform({ baseDir: this.destinationPath() })); } let customizeActions; if (this.options.devBlueprintEnabled) { customizeActions = (actions, { separator }) => { return [ ...actions, ...(separator ? [separator()] : []), { key: 't', name: 'apply to template', value: async ({ file }) => { const { applyChangesToFileOrCopy } = await import("../../lib/ci/apply-patch-to-template.js"); if (file.history?.[0] && file.conflicterData?.diskContents) { const templateFile = file.history[0]; if (file.contents) { const oldFileContents = file.conflicterData.diskContents.toString(); const newFileContents = file.contents.toString(); applyChangesToFileOrCopy({ templateFile, oldFileContents, newFileContents }); } else { await rm(templateFile, { force: true }); } } return 'skip'; }, }, ]; }; } const removeNeedlesTransforms = []; if (this.jhipsterConfig.removeNeedles) { removeNeedlesTransforms.push(createNeedleTransform()); } const transformStreams = [ ...skipYoResolveTransforms, forceYoFiles(), createSortConfigFilesTransform(), createForceWriteConfigFilesTransform(), ...removeNeedlesTransforms, ...prettierTransforms, ...autoCrlfTransforms, createConflicterTransform(this.env.adapter, { ...this.env.conflicterOptions, customizeActions }), createCommitTransform(), ]; await this.pipeline({ refresh: false, // Let pending files pass through. pendingFiles: false, ...options, // Disable progress since it blocks stdin. disabled: true, }, ...transforms, // Filter out pending files. transform((file) => (isFilePending(file) ? file : undefined)), ...transformStreams); this.log.ok(log ?? 'files committed to disk'); } }