// this file contains code to create commits in a consistent way import * as plugins from './mod.plugins.js'; import * as paths from '../paths.js'; import { logger } from '../gitzone.logging.js'; export const run = async (argvArg: any) => { logger.log('info', `gathering facts...`); const aidoc = new plugins.tsdoc.AiDoc(); await aidoc.start(); const nextCommitObject = await aidoc.buildNextCommitObject(paths.cwd); logger.log('info', `--------- Next recommended commit would be: =========== -> ${nextCommitObject.recommendedNextVersion}: -> ${nextCommitObject.recommendedNextVersionLevel}(${nextCommitObject.recommendedNextVersionScope}): ${nextCommitObject.recommendedNextVersionMessage} =========== `); const commitInteract = new plugins.smartinteract.SmartInteract(); commitInteract.addQuestions([ { type: 'list', name: `commitType`, message: `Choose TYPE of the commit:`, choices: [`fix`, `feat`, `BREAKING CHANGE`], default: nextCommitObject.recommendedNextVersionLevel, }, { type: 'input', name: `commitScope`, message: `What is the SCOPE of the commit:`, default: nextCommitObject.recommendedNextVersionScope, }, { type: `input`, name: `commitDescription`, message: `What is the DESCRIPTION of the commit?`, default: nextCommitObject.recommendedNextVersionMessage, }, { type: 'confirm', name: `pushToOrigin`, message: `Do you want to push this version now?`, default: true, }, ]); const answerBucket = await commitInteract.runQueue(); const commitString = createCommitStringFromAnswerBucket(answerBucket); const commitVersionType = (() => { switch (answerBucket.getAnswerFor('commitType')) { case 'fix': return 'patch'; case 'feat': return 'minor'; case 'BREAKING CHANGE': return 'major'; } })(); logger.log('info', `OK! Creating commit with message '${commitString}'`); const smartshellInstance = new plugins.smartshell.Smartshell({ executor: 'bash', sourceFilePaths: [], }); logger.log('info', `Baking commitinfo into code ...`); const commitInfo = new plugins.commitinfo.CommitInfo(paths.cwd, commitVersionType); await commitInfo.writeIntoPotentialDirs(); logger.log('info', `Writing changelog.md ...`); let changelog = nextCommitObject.changelog; changelog = changelog.replaceAll('{{nextVersion}}', (await commitInfo.getNextPlannedVersion()).versionString); changelog = changelog.replaceAll('{{nextVersionScope}}', `${await answerBucket.getAnswerFor('commitType')}(${await answerBucket.getAnswerFor('commitScope')})`); changelog = changelog.replaceAll('{{nextVersionMessage}}', nextCommitObject.recommendedNextVersionMessage); if (nextCommitObject.recommendedNextVersionDetails?.length > 0) { changelog = changelog.replaceAll('{{nextVersionDetails}}', '- ' + nextCommitObject.recommendedNextVersionDetails.join('\n- ')); } else { changelog = changelog.replaceAll('\n{{nextVersionDetails}}', ''); } await plugins.smartfile.memory.toFs(changelog, plugins.path.join(paths.cwd, `changelog.md`)); logger.log('info', `Staging files for commit:`); await smartshellInstance.exec(`git add -A`); await smartshellInstance.exec(`git commit -m "${commitString}"`); await smartshellInstance.exec(`npm version ${commitVersionType}`); if (answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true')) { await smartshellInstance.exec(`git push origin master --follow-tags`); } }; const createCommitStringFromAnswerBucket = (answerBucket: plugins.smartinteract.AnswerBucket) => { const commitType = answerBucket.getAnswerFor('commitType'); const commitScope = answerBucket.getAnswerFor('commitScope'); const commitDescription = answerBucket.getAnswerFor('commitDescription'); return `${commitType}(${commitScope}): ${commitDescription}`; };