/**
 * Prepare commit message.
 *
 * This module ties together logic from independent modules in the `generate` module. So it is best
 * kept on the outside here.
 *
 * The "message" is the full commit message. The "file change description" is the description
 * portion, which describes how the files changed.
 *
 * This module doesn't interact with the git CLI or the extension. It just deals with text.
 */ import { lookupDiffIndexAction } from "./generate/action" ; import { getConventionType } from "./generate/convCommit" ; import { countFilesDesc } from "./generate/count" ; import { namedFilesDesc , oneChange } from "./generate/message" ; import { splitMsg } from "./generate/parseExisting" ; import { MsgPieces } from "./generate/parseExisting.d" ; import { parseDiffIndex } from "./git/parseOutput" ; import { AGGREGATE_MIN , CONVENTIONAL_TYPE } from "./lib/constants" ; import { equal } from "./lib/utils" ; import { ConvCommitMsg } from "./prepareCommitMsg.d" ; /**
 * Join two strings together with a space.
 *
 * Use only one string if only one is set, or if they are identical.
 *
 * Trimming on the outside is necessary, in case only one item is set.
 */ export function _cleanJoin ( first , second ) { first = first . trim ( ) ; second = second . trim ( ) ; if ( first === second ) { return first ; } return `${ first } ${ second }` . trim ( ) ; } param line export function _prefixFromChange ( line ) { const { x : actionChar , from : filePath } = parseDiffIndex ( line ) ; const action = lookupDiffIndexAction ( actionChar ) ; return getConventionType ( action , filePath ) ; } /**
 * Generate message for a single file change.
 */ export function _msgOne ( line ) { const typePrefix = _prefixFromChange ( line ) , description = oneChange ( line ) ; return { typePrefix , description } ; } returns export function _collapse ( types ) { let result = CONVENTIONAL_TYPE . UNKNOWN ; if ( ! types . length ) { return result ; } if ( equal ( types ) ) { result = types [ 0 ] ; } else if ( types . includes ( CONVENTIONAL_TYPE . BUILD_DEPENDENCIES ) ) { result = CONVENTIONAL_TYPE . BUILD_DEPENDENCIES ; } return result ; } /**
 * Generate prefix and named description for multiple file changes.
 *
 * This finds a common Conventional Commit prefix if one is appropriate and
 * returns a message listing all the file names.
 */ export function _msgNamed ( lines ) { const conventions = lines . map ( _prefixFromChange ) ; const typePrefix = _collapse ( conventions ) ; const changes = lines . map ( parseDiffIndex ) ; const description = namedFilesDesc ( changes ) ; return { typePrefix , description } ; } /**
 * Generate prefix and count description for multiple file changes.
 *
 * TODO: Use prefix.
 */ export function _msgCount ( lines ) { const prefix = CONVENTIONAL_TYPE . UNKNOWN ; const changes = lines . map ( parseDiffIndex ) ; const description = countFilesDesc ( changes ) ; return { typePrefix : prefix , description } ; } param lines returns export function _msgFromChanges ( lines ) { let result ; if ( lines . length === 1 ) { const line = lines [ 0 ] ; result = _msgOne ( line ) ; } else if ( lines . length < AGGREGATE_MIN ) { result = _msgNamed ( lines ) ; } else { result = _msgCount ( lines ) ; } return result ; } /**
 * Output a readable conventional commit message.
 */ export function _formatMsg ( convCommitMsg ) { if ( convCommitMsg . typePrefix === CONVENTIONAL_TYPE . UNKNOWN ) { return convCommitMsg . description ; } return `${ convCommitMsg . typePrefix }: ${ convCommitMsg . description }` ; } /**
 * Generate a new commit message and format it as a string.
 */ export function _newMsg ( lines ) { const convCommitMsg = _msgFromChanges ( lines ) ; return _formatMsg ( convCommitMsg ) ; } /**
 * Join old and automated inferred values as one commit message
 */ export function _joinOldAndNew ( autoMsgPieces , oldMsgPieces ) { let typePrefix = "" ; if ( oldMsgPieces . typePrefix ) { typePrefix = oldMsgPieces . typePrefix ; } else if ( autoMsgPieces . typePrefix !== CONVENTIONAL_TYPE . UNKNOWN ) { typePrefix = autoMsgPieces . typePrefix ; } const descResult = _cleanJoin ( autoMsgPieces . description , oldMsgPieces . description ) ; if ( typePrefix ) { const prefix = _cleanJoin ( oldMsgPieces . customPrefix , typePrefix ) ; return `${ prefix }: ${ descResult }` ; } return descResult ; } param autoType param autoDesc param oldMsg export function _combineOldAndNew ( autoType , autoDesc , oldMsg ) { if ( ! oldMsg ) { const autoCommitMsg = { typePrefix : autoType , description : autoDesc , } ; return _formatMsg ( autoCommitMsg ) ; } const oldMsgPieces = splitMsg ( oldMsg ) ; const autoMsgPieces = { typePrefix : autoType , description : autoDesc , } ; return _joinOldAndNew ( autoMsgPieces , oldMsgPieces ) ; } /**
 * Generate commit message using existing message and new generated message.
 *
 * High-level function to process file changes and an old message, to generate a
 * replacement commit message.
 */ export function _generateMsgWithOld ( lines , oldMsg ) { if ( oldMsg === "" ) { throw new Error ( "`oldMsg` must be non-empty - or use `generateNewMsg` instead." ) ; } const { typePrefix , description } = _msgFromChanges ( lines ) ; return _combineOldAndNew ( typePrefix , description , oldMsg ) ; } param lines export function generateMsg ( lines , oldMsg ? ) { if ( ! oldMsg ) { return _newMsg ( lines ) ; } return _generateMsgWithOld ( lines , oldMsg ) ; }