From bea48534753b642324afb028f0c11f11fd27cdd8 Mon Sep 17 00:00:00 2001 From: Adela Homolova Date: Tue, 7 Jan 2020 10:47:43 +0100 Subject: [PATCH] feat: implement TimeToSolveIssues practice --- .../TimeToSolveIssuesPractice.ts | 50 +++++++++++++++++++ src/practices/index.ts | 2 + 2 files changed, 52 insertions(+) create mode 100644 src/practices/LanguageIndependent/TimeToSolveIssuesPractice.ts diff --git a/src/practices/LanguageIndependent/TimeToSolveIssuesPractice.ts b/src/practices/LanguageIndependent/TimeToSolveIssuesPractice.ts new file mode 100644 index 000000000..91c8a49dc --- /dev/null +++ b/src/practices/LanguageIndependent/TimeToSolveIssuesPractice.ts @@ -0,0 +1,50 @@ +import moment from 'moment'; +import { PracticeContext } from '../../contexts/practice/PracticeContext'; +import { PracticeEvaluationResult, PracticeImpact } from '../../model'; +import { GitServiceUtils } from '../../services/git/GitServiceUtils'; +import { DxPractice } from '../DxPracticeDecorator'; +import { IPractice } from '../IPractice'; + +@DxPractice({ + id: 'LanguageIndependent.TimeToSolveIssues', + name: 'Solve Issues Continuously', + impact: PracticeImpact.medium, + suggestion: 'Do not have an open Issues more than 60 days. Solve Issues continuously.', + reportOnlyOnce: true, + url: '', + //dependsOn: { practicing: ['LanguageIndependent.DoesPullRequests'] }, +}) +export class TimeToSolveIssuesPractice implements IPractice { + async isApplicable(): Promise { + return true; + } + + async evaluate(ctx: PracticeContext): Promise { + if (ctx.fileInspector === undefined || ctx.issueTrackingInspector === undefined) { + return PracticeEvaluationResult.unknown; + } + + const repoName = GitServiceUtils.getRepoName(ctx.projectComponent.repositoryPath, ctx.projectComponent.path); + const ownerAndRepoName = GitServiceUtils.getOwnerAndRepoName(repoName); + + //Both GitHub API and Bitbucket API returns open issues by default + const issues = await ctx.issueTrackingInspector.getIssues(ownerAndRepoName.owner, ownerAndRepoName.repoName); + const latestIssueUpdate = issues.items.map((item) => new Date(item.updatedAt || item.createdAt).getTime()); + + const daysInMilliseconds = moment.duration(60, 'days').asMilliseconds(); + const now = Date.now(); + const openPullRequestsTooLong = []; + + latestIssueUpdate.forEach((issueDate) => { + if (now - issueDate > daysInMilliseconds) { + openPullRequestsTooLong.push(issueDate); + } + }); + + if (openPullRequestsTooLong.length === 0) { + return PracticeEvaluationResult.practicing; + } + + return PracticeEvaluationResult.notPracticing; + } +} diff --git a/src/practices/index.ts b/src/practices/index.ts index 4c90e73a4..7d9939bd1 100644 --- a/src/practices/index.ts +++ b/src/practices/index.ts @@ -24,6 +24,7 @@ import { DoesPullRequestsPractice } from './LanguageIndependent/DoesPullRequests import { DependenciesVersionMinorPatchLevelPractice } from './JavaScript/DependenciesVersionMinorPatchLevel'; import { CorrectCommitMessagesPractice } from './LanguageIndependent/CorrectCommitMessagesPractice'; import { TimeToSolvePullRequestsPractice } from './LanguageIndependent/TimeToSolvePullRequestsPractice'; +import { TimeToSolveIssuesPractice } from './LanguageIndependent/TimeToSolveIssuesPractice'; // register practices here export const practices = [ @@ -53,4 +54,5 @@ export const practices = [ DoesPullRequestsPractice, CorrectCommitMessagesPractice, TimeToSolvePullRequestsPractice, + TimeToSolveIssuesPractice, ];