import deburr from 'lodash.deburr'; import {Option} from '../enums/option'; import {wordsToList} from '../functions/words-to-list'; import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options'; import {Issue} from './issue'; import {IssueLogger} from './loggers/issue-logger'; import {LoggerService} from '../services/logger.service'; type CleanMilestone = string; export class Milestones { private static _cleanMilestone(milestone: Readonly): CleanMilestone { return deburr(milestone.toLowerCase()); } private readonly _options: IIssuesProcessorOptions; private readonly _issue: Issue; private readonly _issueLogger: IssueLogger; constructor(options: Readonly, issue: Issue) { this._options = options; this._issue = issue; this._issueLogger = new IssueLogger(issue); } shouldExemptMilestones(): boolean { if (!this._issue.milestone) { this._issueLogger.info('This $$type has no milestone'); this._logSkip(); return false; } if (this._shouldExemptAllMilestones()) { this._issueLogger.info( LoggerService.white('└──'), 'Skipping this $$type because it has a milestone' ); return true; } const exemptMilestones: string[] = this._getExemptMilestones(); if (exemptMilestones.length === 0) { this._issueLogger.info( LoggerService.white('├──'), `No milestone option was specified to skip the stale process for this $$type` ); this._logSkip(); return false; } this._issueLogger.info( LoggerService.white('├──'), `Found ${LoggerService.cyan(exemptMilestones.length)} milestone${ exemptMilestones.length > 1 ? 's' : '' } that can exempt stale on this $$type` ); const hasExemptMilestone: boolean = exemptMilestones.some( (exemptMilestone: Readonly): boolean => this._hasMilestone(exemptMilestone) ); if (!hasExemptMilestone) { this._issueLogger.info( LoggerService.white('├──'), 'No milestone on this $$type can exempt the stale process' ); this._logSkip(); } else { this._issueLogger.info( LoggerService.white('└──'), 'Skipping this $$type because it has an exempt milestone' ); } return hasExemptMilestone; } private _getExemptMilestones(): string[] { return this._issue.isPullRequest ? this._getExemptPullRequestMilestones() : this._getExemptIssueMilestones(); } private _getExemptIssueMilestones(): string[] { if (this._options.exemptIssueMilestones === '') { this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptIssueMilestones )} is disabled. No specific milestone can skip the stale process for this $$type` ); if (this._options.exemptMilestones === '') { this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptMilestones )} is disabled. No specific milestone can skip the stale process for this $$type` ); return []; } const exemptMilestones: string[] = wordsToList( this._options.exemptMilestones ); this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptMilestones )} is set. ${LoggerService.cyan(exemptMilestones.length)} milestone${ exemptMilestones.length === 1 ? '' : 's' } can skip the stale process for this $$type` ); return exemptMilestones; } const exemptMilestones: string[] = wordsToList( this._options.exemptIssueMilestones ); this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptIssueMilestones )} is set. ${LoggerService.cyan(exemptMilestones.length)} milestone${ exemptMilestones.length === 1 ? '' : 's' } can skip the stale process for this $$type` ); return exemptMilestones; } private _getExemptPullRequestMilestones(): string[] { if (this._options.exemptPrMilestones === '') { this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptPrMilestones )} is disabled. No specific milestone can skip the stale process for this $$type` ); if (this._options.exemptMilestones === '') { this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptMilestones )} is disabled. No specific milestone can skip the stale process for this $$type` ); return []; } const exemptMilestones: string[] = wordsToList( this._options.exemptMilestones ); this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptMilestones )} is set. ${LoggerService.cyan(exemptMilestones.length)} milestone${ exemptMilestones.length === 1 ? '' : 's' } can skip the stale process for this $$type` ); return exemptMilestones; } const exemptMilestones: string[] = wordsToList( this._options.exemptPrMilestones ); this._issueLogger.info( LoggerService.white('├──'), `The option ${this._issueLogger.createOptionLink( Option.ExemptPrMilestones )} is set. ${LoggerService.cyan(exemptMilestones.length)} milestone${ exemptMilestones.length === 1 ? '' : 's' } can skip the stale process for this $$type` ); return exemptMilestones; } private _hasMilestone(milestone: Readonly): boolean { if (!this._issue.milestone) { return false; } const cleanMilestone: CleanMilestone = Milestones._cleanMilestone( milestone ); const isSameMilestone: boolean = cleanMilestone === Milestones._cleanMilestone(this._issue.milestone.title); if (isSameMilestone) { this._issueLogger.info( LoggerService.white('├──'), `The milestone "${LoggerService.cyan( milestone )}" is set on this $$type and is an exempt milestone` ); } return isSameMilestone; } private _shouldExemptAllMilestones(): boolean { if (this._issue.milestone) { return this._issue.isPullRequest ? this._shouldExemptAllPullRequestMilestones() : this._shouldExemptAllIssueMilestones(); } return false; } private _shouldExemptAllIssueMilestones(): boolean { if (this._options.exemptAllIssueMilestones === true) { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllIssueMilestones )} is enabled. Any milestone on this $$type will skip the stale process` ); return true; } else if (this._options.exemptAllIssueMilestones === false) { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllIssueMilestones )} is disabled. Only some specific milestones on this $$type will skip the stale process` ); return false; } this._logExemptAllMilestonesOption(); return this._options.exemptAllMilestones; } private _shouldExemptAllPullRequestMilestones(): boolean { if (this._options.exemptAllPrMilestones === true) { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllPrMilestones )} is enabled. Any milestone on this $$type will skip the stale process` ); return true; } else if (this._options.exemptAllPrMilestones === false) { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllPrMilestones )} is disabled. Only some specific milestones on this $$type will skip the stale process` ); return false; } this._logExemptAllMilestonesOption(); return this._options.exemptAllMilestones; } private _logExemptAllMilestonesOption(): void { if (this._options.exemptAllMilestones) { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllMilestones )} is enabled. Any milestone on this $$type will skip the stale process` ); } else { this._issueLogger.info( `The option ${this._issueLogger.createOptionLink( Option.ExemptAllMilestones )} is disabled. Only some specific milestones on this $$type will skip the stale process` ); } } private _logSkip(): void { this._issueLogger.info( LoggerService.white('└──'), 'Skip the milestones checks' ); } }