Skip to content

Commit

Permalink
fix(no recent worklog): account for subtask's worklog when calculatin…
Browse files Browse the repository at this point in the history
…g 'no recent worklog'

Add any worklogs recorded on subtasks of a given task when calculating that tasks grade for 'no
recent worklog'

fix #258
  • Loading branch information
lfzolati committed Jun 14, 2023
1 parent 7005e1e commit 2f3c17d
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 89 deletions.
149 changes: 77 additions & 72 deletions cli/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,77 @@
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json",
tsconfigRootDir: __dirname,
ecmaVersion: 2018,
sourceType: "module",
},
extends: ["typed-fp", "agile-digital"],
env: {
"jest/globals": true,
es6: true,
},
plugins: [
"jest",
"sonarjs",
"functional",
"@typescript-eslint",
"prettier",
"total-functions",
],
rules: {
// https://github.com/aotaduy/eslint-plugin-spellcheck
"spellcheck/spell-checker": [
"warn",
{
skipWords: [
"Argv",
"Authorised",
"assignee",
"changelog",
"changelogs",
"clc",
"codec",
"Codec",
"globals",
"io",
"issuetype",
"jira",
"Jira",
"jiralint",
"jiralintrc",
"jql",
"Kanban",
"Nullable",
"oauth",
"proxied",
"Readonly",
"readonly",
"servlet",
"sonarjs",
"subtask",
"subtasks",
"timetracking",
"unicode",
"utf8",
"Urls",
"versioned",
"worklog",
"Worklog",
"worklogs",
"yargs",
],
},
],
},
settings: {
jest: {
version: 28,
},
},
};
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
project: "tsconfig.json",
tsconfigRootDir: __dirname,
ecmaVersion: 2018,
sourceType: "module",
},
extends: ["typed-fp", "agile-digital"],
env: {
"jest/globals": true,
es6: true,
},
plugins: [
"jest",
"sonarjs",
"functional",
"@typescript-eslint",
"prettier",
"total-functions",
],
rules: {
// https://github.com/aotaduy/eslint-plugin-spellcheck
"spellcheck/spell-checker": [
"warn",
{
skipWords: [
"Argv",
"Authorised",
"assignee",
"changelog",
"changelogs",
"clc",
"codec",
"Codec",
"globals",
"io",
"issuetype",
"jira",
"Jira",
"jiralint",
"jiralintrc",
"jql",
"Kanban",
"Nullable",
"oauth",
"proxied",
"Readonly",
"readonly",
"servlet",
"sonarjs",
"subtask",
"subtasks",
"timetracking",
"unicode",
"utf8",
"Urls",
"versioned",
"worklog",
"Worklog",
"worklogs",
"yargs",
"monday",
"tuesday",
"sunday",
"aggregatetimeoriginalestimate",
"aggregatetimespent",
],
},
],
},
settings: {
jest: {
version: 28,
},
},
};
9 changes: 7 additions & 2 deletions cli/src/scripts/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ import * as clc from "cli-color";
// eslint-disable-next-line functional/no-expression-statements
require("cli-color");

// eslint-disable-next-line functional/type-declaration-immutability
type CheckedIssue = EnhancedIssue & {
readonly action: IssueAction;
readonly reasons: readonly string[];
readonly issueQuality: string;
};

const checkedIssues = (
// eslint-disable-next-line functional/prefer-immutable-types
issues: readonly EnhancedIssue[]
// eslint-disable-next-line functional/prefer-immutable-types
): readonly CheckedIssue[] => {
const now = readonlyDate(readonlyNow());

Expand All @@ -51,16 +54,17 @@ const checkedIssues = (
});
};

// eslint-disable-next-line functional/no-return-void
// eslint-disable-next-line functional/no-return-void, functional/prefer-immutable-types
const renderJson = (issues: readonly EnhancedIssue[]): void => {
// eslint-disable-next-line functional/no-return-void
// eslint-disable-next-line functional/no-return-void, functional/prefer-immutable-types
checkedIssues(issues).forEach((issue) =>
// eslint-disable-next-line no-console
console.log(JSON.stringify(issue, null, 2))
);
};

const renderTable = (
// eslint-disable-next-line functional/prefer-immutable-types
issues: readonly EnhancedIssue[],
qualityFieldName: string
// eslint-disable-next-line functional/no-return-void
Expand Down Expand Up @@ -205,6 +209,7 @@ const search = async (
// eslint-disable-next-line functional/no-expression-statements
countdown.start();

// eslint-disable-next-line functional/prefer-immutable-types
const issues = await jira.searchIssues(
jql,
boardNamesToIgnore,
Expand Down
5 changes: 5 additions & 0 deletions lib/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ module.exports = {
"Worklog",
"worklogs",
"yargs",
"monday",
"tuesday",
"sunday",
"aggregatetimeoriginalestimate",
"aggregatetimespent",
],
},
],
Expand Down
17 changes: 17 additions & 0 deletions lib/src/services/issue_checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type CheckResult = {
readonly reasons: ReadonlyNonEmptyArray<string>;
};

// eslint-disable-next-line functional/prefer-immutable-types
export type Check = (issue: EnhancedIssue) => CheckResult;

export type Action = "none" | "inspect";
Expand Down Expand Up @@ -84,6 +85,7 @@ const notInProgressReason = "not in progress";
*/
export const validateInProgressHasWorklog =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult => {
const check = checker("In progress tickets have been worked");

Expand Down Expand Up @@ -111,6 +113,7 @@ export const validateInProgressHasWorklog =
* @returns result of checking the issue.
*/
export const validateDependenciesHaveDueDate = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue
): CheckResult => {
const check = checker("Dependencies have a due date");
Expand All @@ -132,6 +135,7 @@ export const validateDependenciesHaveDueDate = (
*/
export const validateNotClosedDependenciesNotPassedDueDate =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult => {
const check = checker("Dependencies not passed due date");

Expand Down Expand Up @@ -160,6 +164,7 @@ export const validateNotClosedDependenciesNotPassedDueDate =
};

export const validateInProgressHasEstimate = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue
): CheckResult => {
const check = checker("In Progress issues have estimates");
Expand All @@ -182,6 +187,7 @@ export const validateInProgressHasEstimate = (
};

// TODO check whether the description is a template and fail if it is.
// eslint-disable-next-line functional/prefer-immutable-types
export const validateDescription = (issue: EnhancedIssue): CheckResult => {
const check = checker("Tickets have a description");

Expand All @@ -193,6 +199,7 @@ export const validateDescription = (issue: EnhancedIssue): CheckResult => {
const validateNotStalledFor =
(at: ReadonlyDate) =>
(
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue,
duration: number,
durationDescription: string
Expand Down Expand Up @@ -222,16 +229,19 @@ const validateNotStalledFor =

const validateNotStalledForMoreThanOneDay =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult =>
validateNotStalledFor(at)(issue, 0, "one day");

const validateNotStalledForMoreThanOneWeek =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult =>
validateNotStalledFor(at)(issue, 5, "one week");

const vaildateNotWaitingForReviewForMoreThanHalfADay =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult => {
const check = checker("issues not waiting for review for too long");

Expand Down Expand Up @@ -275,6 +285,7 @@ const vaildateNotWaitingForReviewForMoreThanHalfADay =
};

const validateInProgressNotCloseToEstimate = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue
): CheckResult => {
const check = checker(
Expand All @@ -299,6 +310,7 @@ const validateInProgressNotCloseToEstimate = (
*/
export const validateTooLongInBacklog =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult => {
const check = checker("issues don't stay in the backlog for too long");
const ageInMonths = differenceInCalendarMonths(
Expand All @@ -323,6 +335,7 @@ export const validateTooLongInBacklog =
// TODO check sub-tasks for comments?
export const validateComment =
(at: ReadonlyDate) =>
// eslint-disable-next-line functional/prefer-immutable-types
(issue: EnhancedIssue): CheckResult => {
const check = checker("issues that have been worked have comments");

Expand Down Expand Up @@ -366,7 +379,9 @@ export const validateComment =
};

const check = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue,
// eslint-disable-next-line functional/prefer-immutable-types
checks: readonly ((t: EnhancedIssue) => CheckResult)[]
): IssueAction => {
const noAction: IssueAction = {
Expand Down Expand Up @@ -400,6 +415,7 @@ const check = (
* @returns true if the issue deserves some grace, otherwise false.
*/
export const issueDeservesGrace = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue,
now: ReadonlyDate
): boolean => {
Expand All @@ -420,6 +436,7 @@ export const issueDeservesGrace = (
* @returns whether action is required, and the checks that were run to form that recommendation.
*/
export const issueActionRequired = (
// eslint-disable-next-line functional/prefer-immutable-types
issue: EnhancedIssue,
now: ReadonlyDate,
customChecks: readonly Check[]
Expand Down
7 changes: 6 additions & 1 deletion lib/src/services/jira.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ describe("decoding well-formed tickets", () => {
// Given a well-formed bit of data.

// When it is decoded.
// eslint-disable-next-line functional/prefer-immutable-types
const actual = CloudIssue.decode(data);

// Then no errors should be reported.
Expand Down Expand Up @@ -181,7 +182,7 @@ describe("finding the most recent work date", () => {
// Given an issue.

// When the time it was last worked is found.
const lastWorked = issueLastWorked(issue);
const lastWorked = issueLastWorked(issue, []);

// Then it should match the expected value.
expect(lastWorked).toEqual(expected);
Expand Down Expand Up @@ -310,8 +311,10 @@ describe("enhancing issues", () => {
};

// When it is enhanced
// eslint-disable-next-line functional/prefer-immutable-types
const enhanced = enhancedIssue(
issue,
[],
"viewlink",
fieldName,
"not_reason",
Expand Down Expand Up @@ -341,8 +344,10 @@ describe("enhancing issues", () => {
};

// When it is enhanced
// eslint-disable-next-line functional/prefer-immutable-types
const enhanced = enhancedIssue(
issue,
[],
"viewlink",
"not_quality",
fieldName,
Expand Down
Loading

0 comments on commit 2f3c17d

Please sign in to comment.