UNPKG

generator-begcode

Version:

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

255 lines (254 loc) 11.7 kB
import { setTimeout } from 'timers/promises'; import { readdir, rm } from 'fs/promises'; import chalk from 'chalk'; import gitignore from 'parse-gitignore'; import semver from 'semver'; import { ResetMode } from 'simple-git'; import BaseGenerator from '../base/index.js'; import { packageJson } from '../../lib/index.js'; import EnvironmentBuilder from '../../cli/environment-builder.mjs'; import { SERVER_MAIN_RES_DIR } from '../generator-constants.js'; import { GIT_VERSION_NOT_ALLOW_MERGE_UNRELATED_HISTORIES, UPGRADE_BRANCH } from './support/index.js'; const GENERATOR_JHIPSTER = 'generator-begcode'; const GENERATOR_APP = 'app'; const DEFAULT_CLI_OPTIONS = '--force --skip-install --skip-git --ignore-errors --no-insight --skip-checks'; const DEFAULT_NON_INTERATIVE_OPTIONS = { skipInstall: true, skipGit: true, skipChecks: true, force: true, ignoreErrors: true, skipPriorities: ['prompting'], }; const DEFAULT_MERGE_OPTIONS = ['--strategy', 'ours']; export default class UpgradeGenerator extends BaseGenerator { requiredPackage = GENERATOR_JHIPSTER; createEnvBuilder; actualApplicationBranch; silent; applyConfig; spawnStdio = 'inherit'; executable; verbose; async beforeQueue() { if (!this.fromBlueprint) { await this.composeWithBlueprints(); } } get initializing() { return this.asInitializingTaskGroup({ displayLogo() { this.log.log(chalk.green('Welcome to the JHipster Upgrade Sub-Generator')); this.log.log(chalk.green(`This will upgrade your current application codebase to JHipster version ${packageJson.version}`)); this.log.log(chalk.green('For advanced options, please use the jhipster-migrate blueprint (https://github.com/jhipster/generator-jhipster-migrate/)')); this.log.log(''); }, initializeOptions() { if (this.silent) { this.spawnStdio = 'ignore'; } this.executable = this.executable ?? this.options.programName ?? 'jhipster'; this.createEnvBuilder = this.options.createEnvBuilder ?? EnvironmentBuilder.createDefaultBuilder; }, assertJHipsterProject() { if (!this.config.existed) { throw new Error("Could not find a valid BegCode application configuration, check if the '.yo-rc.json' file exists and if the 'generator-begcode' key exists inside it."); } if (!this.config.get('baseName')) { throw new Error('Current directory does not contain a JHipster project.'); } }, async checkoutDependency() { if (this.applyConfig) return; const jhipsterVersion = this.getPackageJsonVersion(); if (!jhipsterVersion) { throw new Error('No generator-jhipster dependency found in your package.json'); } if (this.isV7(jhipsterVersion)) { if (jhipsterVersion !== '7.9.4') { throw new Error('Upgrade the project to JHipster 7.9.4 before upgrading to the latest version.'); } if ((this.jhipsterConfig.blueprints ?? []).length > 0) { const errorMessage = 'Upgrade does not support upgrading a v7 project with blueprints. Please use the jhipster-migrate blueprint.'; if (!this.skipChecks) { throw new Error(errorMessage); } else { this.log.warn(errorMessage); } } } }, async assertGitPresent() { if (!(await this.checkGitVersion(GIT_VERSION_NOT_ALLOW_MERGE_UNRELATED_HISTORIES))) { this.log.warn('git is not found on your computer.\n', ` Install git: ${chalk.yellow('https://git-scm.com/')}`); throw new Error('Exiting the process.'); } }, async assertGitRepository() { const git = this.createGit(); if (!(await git.checkIsRepo())) { this.log.warn('Current directory is not a git repository. Initializing git.'); await git.init().add('.').commit('initial commit', ['--allow-empty', '--no-verify']); } }, async assertNoLocalChanges() { const result = await this.createGit().status(); if (!result.isClean()) { throw new Error(` local changes found.\n\tPlease commit/stash them before upgrading\n\t${result.files .map(file => `${file.index} ${file.path}`) .join('\n\t')}`); } }, async detectCurrentBranch() { this.actualApplicationBranch = await this.createGit().revparse(['--abbrev-ref', 'HEAD']); if (this.actualApplicationBranch === UPGRADE_BRANCH) { throw new Error('You are on the upgrade branch, please switch to another branch before upgrading.'); } }, }); } get [BaseGenerator.INITIALIZING]() { return this.delegateTasksToBlueprint(() => this.initializing); } get default() { return this.asDefaultTaskGroup({ async prepareUpgradeBranch() { const git = this.createGit(); try { await git.revparse(['--verify', UPGRADE_BRANCH]); await git.checkout(UPGRADE_BRANCH); } catch { await git.checkout(['--orphan', UPGRADE_BRANCH]); } await this.cleanUp(); if (this.applyConfig) { await this.runNonInteractive(false); } else { await this.spawnCommand('npm install', { stdio: this.spawnStdio }); const customCliOptions = []; if (this.getPackageJsonVersion() === '7.9.4') { customCliOptions.push('--with-entities'); } this.log.info(`Regenerating sources using ${this.executable} executable`); await this.spawn('npx', ['--no', this.executable, ...customCliOptions, ...DEFAULT_CLI_OPTIONS.split(' ')], { stdio: this.spawnStdio, }); } await this.rmRf(`${SERVER_MAIN_RES_DIR}config/tls/keystore.p12`); await git.add('.').commit(`generated ${UPGRADE_BRANCH} using JHipster ${this.getPackageJsonVersion()}`, ['--no-verify']); this.log.info('reference application created'); await setTimeout(1000); }, async prepareSourceBranch() { const git = this.createGit(); await git .checkout(this.actualApplicationBranch, ['-f']) .merge([ UPGRADE_BRANCH, ...DEFAULT_MERGE_OPTIONS, '-m', `reference merge of ${UPGRADE_BRANCH} branch into ${this.actualApplicationBranch}`, '--allow-unrelated-histories', ]); this.log.info('reference application merged into source branch'); await setTimeout(1000); }, async updateUpgradeBranch() { const git = this.createGit(); await git.checkout(UPGRADE_BRANCH); await this.cleanUp(); await this.runNonInteractive(); await this.rmRf(`${SERVER_MAIN_RES_DIR}config/tls/keystore.p12`); await git.add('.').commit(`generated ${UPGRADE_BRANCH} using JHipster ${packageJson.version}`, ['--no-verify']); this.log.info('upgrade commit created'); await setTimeout(1000); }, async upgradeSourceBranch() { const git = this.createGit(); await git .checkout(this.actualApplicationBranch, ['-f']) .merge([UPGRADE_BRANCH, '-m', `upgrade merge of ${UPGRADE_BRANCH} branch into ${this.actualApplicationBranch}`]) .reset(ResetMode.HARD); this.log.info('upgrade application merged into source branch'); if (!this.applyConfig) { await this.rmRf('node_modules'); await this.rmRf('package-lock.json'); this.log.info('node_modules and package-lock.json removed to allow a clean install'); } }, }); } get [BaseGenerator.DEFAULT]() { return this.delegateTasksToBlueprint(() => this.default); } get end() { return this.asEndTaskGroup({ async end() { const diff = await this.createGit().diff(['--name-only', '--diff-filter', 'U']); this.log.ok(chalk.bold('upgraded successfully.')); if (diff) { this.log.warn(`please fix conflicts listed below and commit!\n${diff}`); } }, }); } get [BaseGenerator.END]() { return this.delegateTasksToBlueprint(() => this.end); } async rmRf(file) { const absolutePath = this.destinationPath(file); if (this.verbose) { this.log.verboseInfo(`Removing ${absolutePath}`); } try { await rm(absolutePath, { recursive: true }); } catch { } } async cleanUp() { const gitignoreContent = this.readDestination('.gitignore', { defaults: '' }); const ignoredFiles = gitignoreContent ? (gitignore(gitignoreContent).patterns ?? []) : []; const filesToKeep = ['.yo-rc.json', '.jhipster', 'package.json', 'package-lock.json', 'node_modules', '.git', ...ignoredFiles]; for (const file of await readdir(this.destinationPath())) { if (!filesToKeep.includes(file)) { await this.rmRf(file); } } this.log.info('cleaned up project directory'); } getPackageJsonVersion() { return this.readDestinationJSON('package.json').devDependencies?.['generator-jhipster']; } isV7(version) { return version.includes('.') && parseInt(version.split('.', 2), 10) < 8; } async runNonInteractive(inherit = true) { const adapter = this.env.adapter.newAdapter?.(); const sharedFs = inherit ? this.env.sharedFs : undefined; const inheritedOptions = inherit ? this.options : {}; const envOptions = { sharedFs, adapter }; const generatorOptions = { ...inheritedOptions, ...DEFAULT_NON_INTERATIVE_OPTIONS }; delete generatorOptions.sharedData; const envBuilder = await this.createEnvBuilder(envOptions); const env = envBuilder.getEnvironment(); await env.run([`begcode:${GENERATOR_APP}`], generatorOptions); } async checkGitVersion(minVersion) { try { const rawVersion = await this.createGit().raw('--version'); const gitVersion = String(rawVersion.match(/([0-9]+\.[0-9]+\.[0-9]+)/g)); if (minVersion) { return semver.gte(gitVersion, minVersion); } return true; } catch { return false; } } }