140 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // 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';
 | |
| import * as helpers from './mod.helpers.js';
 | |
| 
 | |
| export const run = async (argvArg: any) => {
 | |
|   if (argvArg.format) {
 | |
|     const formatMod = await import('../mod_format/index.js');
 | |
|     await formatMod.run();
 | |
|   }
 | |
| 
 | |
|   logger.log('info', `gathering facts...`);
 | |
|   const aidoc = new plugins.tsdoc.AiDoc();
 | |
|   await aidoc.start();
 | |
| 
 | |
|   const nextCommitObject = await aidoc.buildNextCommitObject(paths.cwd);
 | |
| 
 | |
|   await aidoc.stop();
 | |
| 
 | |
|   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}"`);
 | |
| 
 | |
|   // Detect project type and bump version accordingly
 | |
|   const projectType = await helpers.detectProjectType();
 | |
|   await helpers.bumpProjectVersion(projectType, commitVersionType);
 | |
| 
 | |
|   if (
 | |
|     answerBucket.getAnswerFor('pushToOrigin') &&
 | |
|     !(process.env.CI === 'true')
 | |
|   ) {
 | |
|     // Detect current branch instead of hardcoding "master"
 | |
|     const currentBranch = await helpers.detectCurrentBranch();
 | |
|     await smartshellInstance.exec(`git push origin ${currentBranch} --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}`;
 | |
| };
 |