feat(statistics): split the stats between issues and PRs (#364)

* docs(only-labels): enhance the docs and fix duplicate (#341)

* docs(only-labels): remove duplicated option and improve descriptions

a bad rebase happend

* docs(readme): use a multi-line array and remove the optional column

the option column was not helpful since each value is optional
the multi-line array will allow to have a better UI in small devices and basically in GitHub too due to the max-width

* style(readme): break line for the statistics

* docs(readme): add a better description for the ascending option

* docs(action): add missing punctuation

* build(deps-dev): bump @typescript-eslint/eslint-plugin (#342)

Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.15.2 to 4.16.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.16.1/packages/eslint-plugin)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump @octokit/rest from 18.3.0 to 18.3.2 (#350)

Bumps [@octokit/rest](https://github.com/octokit/rest.js) from 18.3.0 to 18.3.2.
- [Release notes](https://github.com/octokit/rest.js/releases)
- [Commits](https://github.com/octokit/rest.js/compare/v18.3.0...v18.3.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* test: add more coverage for the stale label behaviour (#352) (#15)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* test: add more coverage for the stale label behaviour (#352) (#17)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* test(refactor): use toHaveLength

* feat(statistics): split the processed issues and prs

* feat(statistics): split the new stale issues and prs

* feat(statistics): split the no longer stale issues and prs

* chore(deps): undo upgrade of dependencies

* feat(statistics): split closed issues and prs

* feat(statistics): use the word "items" when something concern both issues and prs

* feat(statistics): split more stats by issues and prs

* feat(statistics): split more stats by issues and prs (final)

* chore(index): update it

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
Geoffrey Testelin 2021-04-27 20:47:02 +02:00 committed by GitHub
parent 10eec4583b
commit 5e20aa8410
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 841 additions and 303 deletions

View File

@ -25,8 +25,8 @@ test('processing an issue with no label will make it stale and close it, if it i
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing an issue with no label and a start date as ECMAScript epoch in seconds being before the issue creation date will not make it stale nor close it when it is old enough and days-before-close is set to 0', async () => {
@ -305,9 +305,9 @@ test('processing an issue with no label will make it stale and close it, if it i
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.deletedBranchIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(1);
expect(processor.deletedBranchIssues).toHaveLength(0);
});
test('processing an issue with no label will make it stale and not close it, if it is old enough only if days-before-close is set to > 0 and days-before-issue-close is set to > 0', async () => {
@ -330,8 +330,8 @@ test('processing an issue with no label will make it stale and not close it, if
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue with no label will make it stale and not close it if days-before-close is set to > 0', async () => {
@ -353,8 +353,8 @@ test('processing an issue with no label will make it stale and not close it if d
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue with no label will make it stale and not close it if days-before-close is set to -1 and days-before-issue-close is set to > 0', async () => {
@ -377,8 +377,8 @@ test('processing an issue with no label will make it stale and not close it if d
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue with no label will not make it stale if days-before-stale is set to -1', async () => {
@ -401,8 +401,8 @@ test('processing an issue with no label will not make it stale if days-before-st
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue with no label will not make it stale if days-before-stale and days-before-issue-stale are set to -1', async () => {
@ -426,8 +426,8 @@ test('processing an issue with no label will not make it stale if days-before-st
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue with no label will make it stale but not close it', async () => {
@ -454,8 +454,8 @@ test('processing an issue with no label will make it stale but not close it', as
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing a stale issue will close it', async () => {
@ -485,8 +485,8 @@ test('processing a stale issue will close it', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale issue containing a space in the label will close it', async () => {
@ -516,8 +516,8 @@ test('processing a stale issue containing a space in the label will close it', a
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale issue containing a slash in the label will close it', async () => {
@ -547,8 +547,8 @@ test('processing a stale issue containing a slash in the label will close it', a
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale issue will close it when days-before-issue-stale override days-before-stale', async () => {
@ -579,8 +579,8 @@ test('processing a stale issue will close it when days-before-issue-stale overri
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale PR will close it', async () => {
@ -610,8 +610,8 @@ test('processing a stale PR will close it', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale PR will close it when days-before-pr-stale override days-before-stale', async () => {
@ -642,8 +642,8 @@ test('processing a stale PR will close it when days-before-pr-stale override day
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale issue will close it even if configured not to mark as stale', async () => {
@ -674,8 +674,8 @@ test('processing a stale issue will close it even if configured not to mark as s
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale issue will close it even if configured not to mark as stale when days-before-issue-stale override days-before-stale', async () => {
@ -707,8 +707,8 @@ test('processing a stale issue will close it even if configured not to mark as s
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale PR will close it even if configured not to mark as stale', async () => {
@ -739,8 +739,8 @@ test('processing a stale PR will close it even if configured not to mark as stal
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('processing a stale PR will close it even if configured not to mark as stale when days-before-pr-stale override days-before-stale', async () => {
@ -772,8 +772,8 @@ test('processing a stale PR will close it even if configured not to mark as stal
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(1);
});
test('closed issues will not be marked stale', async () => {
@ -799,8 +799,8 @@ test('closed issues will not be marked stale', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('stale closed issues will not be closed', async () => {
@ -827,8 +827,8 @@ test('stale closed issues will not be closed', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('closed prs will not be marked stale', async () => {
@ -855,8 +855,8 @@ test('closed prs will not be marked stale', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('stale closed prs will not be closed', async () => {
@ -883,8 +883,8 @@ test('stale closed prs will not be closed', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('locked issues will not be marked stale', async () => {
@ -910,8 +910,8 @@ test('locked issues will not be marked stale', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('stale locked issues will not be closed', async () => {
@ -939,8 +939,8 @@ test('stale locked issues will not be closed', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('locked prs will not be marked stale', async () => {
@ -966,8 +966,8 @@ test('locked prs will not be marked stale', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('stale locked prs will not be closed', async () => {
@ -995,8 +995,8 @@ test('stale locked prs will not be closed', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('exempt issue labels will not be marked stale', async () => {
@ -1055,8 +1055,8 @@ test('exempt issue labels will not be marked stale (multi issue label with space
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('exempt issue labels will not be marked stale (multi issue label)', async () => {
@ -1084,9 +1084,9 @@ test('exempt issue labels will not be marked stale (multi issue label)', async (
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
});
test('exempt pr labels will not be marked stale', async () => {
@ -1131,7 +1131,7 @@ test('exempt pr labels will not be marked stale', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(2); // PR should get processed even though it has an exempt **issue** label
expect(processor.staleIssues).toHaveLength(2); // PR should get processed even though it has an exempt **issue** label
});
test('exempt issue labels will not be marked stale and will remove the existing stale label', async () => {
@ -1215,8 +1215,8 @@ test('stale issues should not be closed if days is set to -1', async () => {
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
});
test('stale label should be removed if a comment was added to a stale issue', async () => {
@ -1251,9 +1251,9 @@ test('stale label should be removed if a comment was added to a stale issue', as
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(1);
});
test('stale label should not be removed if a comment was added by the bot (and the issue should be closed)', async () => {
@ -1289,9 +1289,9 @@ test('stale label should not be removed if a comment was added by the bot (and t
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(1);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
});
test('stale label containing a space should be removed if a comment was added to a stale issue', async () => {
@ -1322,9 +1322,9 @@ test('stale label containing a space should be removed if a comment was added to
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(1);
});
test('stale issues should not be closed until after the closed number of days', async () => {
@ -1354,9 +1354,9 @@ test('stale issues should not be closed until after the closed number of days',
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(1);
});
test('stale issues should be closed if the closed nubmer of days (additive) is also passed', async () => {
@ -1387,9 +1387,9 @@ test('stale issues should be closed if the closed nubmer of days (additive) is a
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(1);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
});
test('stale issues should not be closed until after the closed number of days (long)', async () => {
@ -1419,9 +1419,9 @@ test('stale issues should not be closed until after the closed number of days (l
// process our fake issue list
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(1);
});
test('skips stale message on issues when skip-stale-issue-message is set', async () => {
@ -1455,9 +1455,9 @@ test('skips stale message on issues when skip-stale-issue-message is set', async
await processor.processIssues(1);
// issue should be staled
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(1);
// comment should not be created
expect(markSpy).toHaveBeenCalledWith(
@ -1500,9 +1500,9 @@ test('skips stale message on prs when skip-stale-pr-message is set', async () =>
await processor.processIssues(1);
// issue should be staled
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(1);
// comment should not be created
expect(markSpy).toHaveBeenCalledWith(
@ -1543,9 +1543,9 @@ test('not providing state takes precedence over skipStaleIssueMessage', async ()
await processor.processIssues(1);
// issue should be staled
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
});
test('not providing stalePrMessage takes precedence over skipStalePrMessage', async () => {
@ -1577,9 +1577,9 @@ test('not providing stalePrMessage takes precedence over skipStalePrMessage', as
await processor.processIssues(1);
// issue should be staled
expect(processor.closedIssues.length).toEqual(0);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
});
test('git branch is deleted when option is enabled', async () => {
@ -1606,10 +1606,10 @@ test('git branch is deleted when option is enabled', async () => {
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.deletedBranchIssues.length).toEqual(1);
expect(processor.closedIssues).toHaveLength(1);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.deletedBranchIssues).toHaveLength(1);
});
test('git branch is not deleted when issue is not pull request', async () => {
@ -1636,10 +1636,10 @@ test('git branch is not deleted when issue is not pull request', async () => {
await processor.processIssues(1);
expect(processor.closedIssues.length).toEqual(1);
expect(processor.removedLabelIssues.length).toEqual(0);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.deletedBranchIssues.length).toEqual(0);
expect(processor.closedIssues).toHaveLength(1);
expect(processor.removedLabelIssues).toHaveLength(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.deletedBranchIssues).toHaveLength(0);
});
test('an issue without a milestone will be marked as stale', async () => {
@ -1938,8 +1938,8 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue opened since 2 days and with the option "daysBeforeIssueStale" at 2 will make it stale', async () => {
@ -1965,8 +1965,8 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing an issue opened since 2 days and with the option "daysBeforeIssueStale" at 1 will make it stale', async () => {
@ -1992,8 +1992,8 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing a pull request opened since 2 days and with the option "daysBeforePrStale" at 3 will not make it stale', async () => {
@ -2026,8 +2026,8 @@ test('processing a pull request opened since 2 days and with the option "daysBef
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(0);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(0);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing a pull request opened since 2 days and with the option "daysBeforePrStale" at 2 will make it stale', async () => {
@ -2060,8 +2060,8 @@ test('processing a pull request opened since 2 days and with the option "daysBef
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing a pull request opened since 2 days and with the option "daysBeforePrStale" at 1 will make it stale', async () => {
@ -2094,8 +2094,8 @@ test('processing a pull request opened since 2 days and with the option "daysBef
// process our fake issue list
await processor.processIssues(1);
expect(processor.staleIssues.length).toEqual(1);
expect(processor.closedIssues.length).toEqual(0);
expect(processor.staleIssues).toHaveLength(1);
expect(processor.closedIssues).toHaveLength(0);
});
test('processing a previously closed issue with a close label will remove the close label', async () => {

390
dist/index.js vendored
View File

@ -284,7 +284,7 @@ class IssuesProcessor {
}
for (const issue of issues.values()) {
const issueLogger = new issue_logger_1.IssueLogger(issue);
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementProcessedIssuesCount();
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementProcessedItemsCount(issue);
issueLogger.info(`Found this $$type last updated ${issue.updated_at}`);
// calculate string based messages for this issue
const staleMessage = issue.isPullRequest
@ -418,7 +418,7 @@ class IssuesProcessor {
// find any comments since date on the given issue
try {
this._operations.consumeOperation();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedIssuesCommentsCount();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsCommentsCount();
const comments = yield this.client.issues.listComments({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -463,7 +463,7 @@ class IssuesProcessor {
direction: this.options.ascending ? 'asc' : 'desc',
page
});
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedIssuesCount(issueResult.data.length);
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsCount(issueResult.data.length);
return issueResult.data.map((issue) => new issue_1.Issue(this.options, issue));
}
catch (error) {
@ -480,7 +480,7 @@ class IssuesProcessor {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Checking for label on $$type`);
this._operations.consumeOperation();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedIssuesEventsCount();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsEventsCount();
const options = this.client.issues.listEvents.endpoint.merge({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -566,7 +566,7 @@ class IssuesProcessor {
if (!skipMessage) {
try {
this._operations.consumeOperation();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedComment();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedItemsComment(issue);
yield this.client.issues.createComment({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -580,8 +580,8 @@ class IssuesProcessor {
}
try {
this._operations.consumeOperation();
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementAddedLabel();
(_c = this._statistics) === null || _c === void 0 ? void 0 : _c.incrementStaleIssuesCount();
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementAddedItemsLabel(issue);
(_c = this._statistics) === null || _c === void 0 ? void 0 : _c.incrementStaleItemsCount(issue);
yield this.client.issues.addLabels({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -607,7 +607,7 @@ class IssuesProcessor {
if (closeMessage) {
try {
this._operations.consumeOperation();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedComment();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedItemsComment(issue);
yield this.client.issues.createComment({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -622,7 +622,7 @@ class IssuesProcessor {
if (closeLabel) {
try {
this._operations.consumeOperation();
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementAddedLabel();
(_b = this._statistics) === null || _b === void 0 ? void 0 : _b.incrementAddedItemsLabel(issue);
yield this.client.issues.addLabels({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -636,7 +636,7 @@ class IssuesProcessor {
}
try {
this._operations.consumeOperation();
(_c = this._statistics) === null || _c === void 0 ? void 0 : _c.incrementClosedIssuesCount();
(_c = this._statistics) === null || _c === void 0 ? void 0 : _c.incrementClosedItemsCount(issue);
yield this.client.issues.update({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -701,7 +701,7 @@ class IssuesProcessor {
}
});
}
// Remove a label from an issue
// Remove a label from an issue or a pull request
_removeLabel(issue, label) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
@ -713,7 +713,7 @@ class IssuesProcessor {
}
try {
this._operations.consumeOperation();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedLabelsCount();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedItemsLabelsCount(issue);
yield this.client.issues.removeLabel({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
@ -765,7 +765,7 @@ class IssuesProcessor {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`The $$type is no longer stale. Removing the stale label...`);
yield this._removeLabel(issue, staleLabel);
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementUndoStaleIssuesCount();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementUndoStaleItemsCount(issue);
});
}
_removeCloseLabel(issue, closeLabel) {
@ -780,7 +780,7 @@ class IssuesProcessor {
if (is_labeled_1.isLabeled(issue, closeLabel)) {
issueLogger.info(`The $$type has a close label "${closeLabel}". Removing the close label...`);
yield this._removeLabel(issue, closeLabel);
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedCloseLabelsCount();
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedCloseItemsLabelsCount(issue);
}
});
}
@ -1112,70 +1112,94 @@ class Statistics {
constructor() {
this._logger = new logger_1.Logger();
this._processedIssuesCount = 0;
this._processedPullRequestsCount = 0;
this._staleIssuesCount = 0;
this._stalePullRequestsCount = 0;
this._undoStaleIssuesCount = 0;
this._undoStalePullRequestsCount = 0;
this._operationsCount = 0;
this._closedIssuesCount = 0;
this._deletedLabelsCount = 0;
this._deletedCloseLabelsCount = 0;
this._closedPullRequestsCount = 0;
this._deletedIssuesLabelsCount = 0;
this._deletedPullRequestsLabelsCount = 0;
this._deletedCloseIssuesLabelsCount = 0;
this._deletedClosePullRequestsLabelsCount = 0;
this._deletedBranchesCount = 0;
this._addedLabelsCount = 0;
this._addedCommentsCount = 0;
this._fetchedIssuesCount = 0;
this._fetchedIssuesEventsCount = 0;
this._fetchedIssuesCommentsCount = 0;
this._addedIssuesLabelsCount = 0;
this._addedPullRequestsLabelsCount = 0;
this._addedIssuesCommentsCount = 0;
this._addedPullRequestsCommentsCount = 0;
this._fetchedItemsCount = 0;
this._fetchedItemsEventsCount = 0;
this._fetchedItemsCommentsCount = 0;
this._fetchedPullRequestsCount = 0;
}
incrementProcessedIssuesCount(increment = 1) {
this._processedIssuesCount += increment;
return this;
incrementProcessedItemsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementProcessedPullRequestsCount(increment);
}
incrementStaleIssuesCount(increment = 1) {
this._staleIssuesCount += increment;
return this;
return this._incrementProcessedIssuesCount(increment);
}
incrementUndoStaleIssuesCount(increment = 1) {
this._undoStaleIssuesCount += increment;
return this;
incrementStaleItemsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementStalePullRequestsCount(increment);
}
return this._incrementStaleIssuesCount(increment);
}
incrementUndoStaleItemsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementUndoStalePullRequestsCount(increment);
}
return this._incrementUndoStaleIssuesCount(increment);
}
setOperationsLeft(operationsLeft) {
this._operationsCount = operationsLeft;
return this;
}
incrementClosedIssuesCount(increment = 1) {
this._closedIssuesCount += increment;
return this;
incrementClosedItemsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementClosedPullRequestsCount(increment);
}
incrementDeletedLabelsCount(increment = 1) {
this._deletedLabelsCount += increment;
return this;
return this._incrementClosedIssuesCount(increment);
}
incrementDeletedCloseLabelsCount(increment = 1) {
this._deletedCloseLabelsCount += increment;
return this;
incrementDeletedItemsLabelsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementDeletedPullRequestsLabelsCount(increment);
}
return this._incrementDeletedIssuesLabelsCount(increment);
}
incrementDeletedCloseItemsLabelsCount(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementDeletedClosePullRequestsLabelsCount(increment);
}
return this._incrementDeletedCloseIssuesLabelsCount(increment);
}
incrementDeletedBranchesCount(increment = 1) {
this._deletedBranchesCount += increment;
return this;
}
incrementAddedLabel(increment = 1) {
this._addedLabelsCount += increment;
incrementAddedItemsLabel(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementAddedPullRequestsLabel(increment);
}
return this._incrementAddedIssuesLabel(increment);
}
incrementAddedItemsComment(issue, increment = 1) {
if (issue.isPullRequest) {
return this._incrementAddedPullRequestsComment(increment);
}
return this._incrementAddedIssuesComment(increment);
}
incrementFetchedItemsCount(increment = 1) {
this._fetchedItemsCount += increment;
return this;
}
incrementAddedComment(increment = 1) {
this._addedCommentsCount += increment;
incrementFetchedItemsEventsCount(increment = 1) {
this._fetchedItemsEventsCount += increment;
return this;
}
incrementFetchedIssuesCount(increment = 1) {
this._fetchedIssuesCount += increment;
return this;
}
incrementFetchedIssuesEventsCount(increment = 1) {
this._fetchedIssuesEventsCount += increment;
return this;
}
incrementFetchedIssuesCommentsCount(increment = 1) {
this._fetchedIssuesCommentsCount += increment;
incrementFetchedItemsCommentsCount(increment = 1) {
this._fetchedItemsCommentsCount += increment;
return this;
}
incrementFetchedPullRequestsCount(increment = 1) {
@ -1184,69 +1208,257 @@ class Statistics {
}
logStats() {
this._logger.info(chalk_1.default.yellow.bold('Statistics:'));
this._logProcessedIssuesCount();
this._logStaleIssuesCount();
this._logUndoStaleIssuesCount();
this._logOperationsCount();
this._logClosedIssuesCount();
this._logDeletedLabelsCount();
this._logDeletedCloseLabelsCount();
this._logProcessedIssuesAndPullRequestsCount();
this._logStaleIssuesAndPullRequestsCount();
this._logUndoStaleIssuesAndPullRequestsCount();
this._logClosedIssuesAndPullRequestsCount();
this._logDeletedIssuesAndPullRequestsLabelsCount();
this._logDeletedCloseIssuesAndPullRequestsLabelsCount();
this._logDeletedBranchesCount();
this._logAddedLabelsCount();
this._logAddedCommentsCount();
this._logFetchedIssuesCount();
this._logFetchedIssuesEventsCount();
this._logFetchedIssuesCommentsCount();
this._logAddedIssuesAndPullRequestsLabelsCount();
this._logAddedIssuesAndPullRequestsCommentsCount();
this._logFetchedItemsCount();
this._logFetchedItemsEventsCount();
this._logFetchedItemsCommentsCount();
this._logFetchedPullRequestsCount();
this._logOperationsCount();
return this;
}
_logProcessedIssuesCount() {
this._logCount('Processed issues/PRs', this._processedIssuesCount);
_incrementProcessedIssuesCount(increment = 1) {
this._processedIssuesCount += increment;
return this;
}
_logStaleIssuesCount() {
this._logCount('New stale issues/PRs', this._staleIssuesCount);
_incrementProcessedPullRequestsCount(increment = 1) {
this._processedPullRequestsCount += increment;
return this;
}
_logUndoStaleIssuesCount() {
this._logCount('No longer stale issues/PRs', this._undoStaleIssuesCount);
_incrementStaleIssuesCount(increment = 1) {
this._staleIssuesCount += increment;
return this;
}
_logOperationsCount() {
this._logCount('Operations performed', this._operationsCount);
_incrementStalePullRequestsCount(increment = 1) {
this._stalePullRequestsCount += increment;
return this;
}
_logClosedIssuesCount() {
this._logCount('Closed issues', this._closedIssuesCount);
_incrementUndoStaleIssuesCount(increment = 1) {
this._undoStaleIssuesCount += increment;
return this;
}
_logDeletedLabelsCount() {
this._logCount('Deleted labels', this._deletedLabelsCount);
_incrementUndoStalePullRequestsCount(increment = 1) {
this._undoStalePullRequestsCount += increment;
return this;
}
_logDeletedCloseLabelsCount() {
this._logCount('Deleted close labels', this._deletedCloseLabelsCount);
_incrementClosedIssuesCount(increment = 1) {
this._closedIssuesCount += increment;
return this;
}
_incrementClosedPullRequestsCount(increment = 1) {
this._closedPullRequestsCount += increment;
return this;
}
_incrementDeletedIssuesLabelsCount(increment = 1) {
this._deletedIssuesLabelsCount += increment;
return this;
}
_incrementDeletedPullRequestsLabelsCount(increment = 1) {
this._deletedPullRequestsLabelsCount += increment;
return this;
}
_incrementDeletedCloseIssuesLabelsCount(increment = 1) {
this._deletedCloseIssuesLabelsCount += increment;
return this;
}
_incrementDeletedClosePullRequestsLabelsCount(increment = 1) {
this._deletedClosePullRequestsLabelsCount += increment;
return this;
}
_incrementAddedIssuesLabel(increment = 1) {
this._addedIssuesLabelsCount += increment;
return this;
}
_incrementAddedPullRequestsLabel(increment = 1) {
this._addedPullRequestsLabelsCount += increment;
return this;
}
_incrementAddedIssuesComment(increment = 1) {
this._addedIssuesCommentsCount += increment;
return this;
}
_incrementAddedPullRequestsComment(increment = 1) {
this._addedPullRequestsCommentsCount += increment;
return this;
}
_logProcessedIssuesAndPullRequestsCount() {
this._logGroup('Processed items', [
{
name: 'Processed issues',
count: this._processedIssuesCount
},
{
name: 'Processed PRs',
count: this._processedPullRequestsCount
}
]);
}
_logStaleIssuesAndPullRequestsCount() {
this._logGroup('New stale items', [
{
name: 'New stale issues',
count: this._staleIssuesCount
},
{
name: 'New stale PRs',
count: this._stalePullRequestsCount
}
]);
}
_logUndoStaleIssuesAndPullRequestsCount() {
this._logGroup('No longer stale items', [
{
name: 'No longer stale issues',
count: this._undoStaleIssuesCount
},
{
name: 'No longer stale PRs',
count: this._undoStalePullRequestsCount
}
]);
}
_logClosedIssuesAndPullRequestsCount() {
this._logGroup('Closed items', [
{
name: 'Closed issues',
count: this._closedIssuesCount
},
{
name: 'Closed PRs',
count: this._closedPullRequestsCount
}
]);
}
_logDeletedIssuesAndPullRequestsLabelsCount() {
this._logGroup('Deleted items labels', [
{
name: 'Deleted issues labels',
count: this._deletedIssuesLabelsCount
},
{
name: 'Deleted PRs labels',
count: this._deletedPullRequestsLabelsCount
}
]);
}
_logDeletedCloseIssuesAndPullRequestsLabelsCount() {
this._logGroup('Deleted close items labels', [
{
name: 'Deleted close issues labels',
count: this._deletedCloseIssuesLabelsCount
},
{
name: 'Deleted close PRs labels',
count: this._deletedClosePullRequestsLabelsCount
}
]);
}
_logDeletedBranchesCount() {
this._logCount('Deleted branches', this._deletedBranchesCount);
}
_logAddedLabelsCount() {
this._logCount('Added labels', this._addedLabelsCount);
_logAddedIssuesAndPullRequestsLabelsCount() {
this._logGroup('Added items labels', [
{
name: 'Added issues labels',
count: this._addedIssuesLabelsCount
},
{
name: 'Added PRs labels',
count: this._addedPullRequestsLabelsCount
}
_logAddedCommentsCount() {
this._logCount('Added comments', this._addedCommentsCount);
]);
}
_logFetchedIssuesCount() {
this._logCount('Fetched issues', this._fetchedIssuesCount);
_logAddedIssuesAndPullRequestsCommentsCount() {
this._logGroup('Added items comments', [
{
name: 'Added issues comments',
count: this._addedIssuesCommentsCount
},
{
name: 'Added PRs comments',
count: this._addedPullRequestsCommentsCount
}
_logFetchedIssuesEventsCount() {
this._logCount('Fetched issues events', this._fetchedIssuesEventsCount);
]);
}
_logFetchedIssuesCommentsCount() {
this._logCount('Fetched issues comments', this._fetchedIssuesCommentsCount);
_logFetchedItemsCount() {
this._logCount('Fetched items', this._fetchedItemsCount);
}
_logFetchedItemsEventsCount() {
this._logCount('Fetched items events', this._fetchedItemsEventsCount);
}
_logFetchedItemsCommentsCount() {
this._logCount('Fetched items comments', this._fetchedItemsCommentsCount);
}
_logFetchedPullRequestsCount() {
this._logCount('Fetched pull requests', this._fetchedPullRequestsCount);
}
_logOperationsCount() {
this._logCount('Operations performed', this._operationsCount);
}
_logCount(name, count) {
if (count > 0) {
this._logger.info(`${name}:`, chalk_1.default.cyan(count));
}
}
_logGroup(groupName, values) {
if (this._isGroupValuesPartiallySet(values)) {
this._logCount(groupName, this._getGroupValuesTotalCount(values));
this._logGroupValues(values);
}
else {
// Only one value will be display
for (const value of values) {
this._logCount(value.name, value.count);
}
}
}
/**
* @private
* @description
* If there is a least two elements with a valid count then it's partially set
* Useful to defined if we should display the values as a group or not
*
* @param {IGroupValue[]} values The list of group values to check
*/
_isGroupValuesPartiallySet(values) {
return (values
.map((value) => {
return value.count > 0;
})
.filter((isSet) => isSet).length >= 2);
}
_getGroupValuesTotalCount(values) {
return values.reduce((count, value) => {
return count + value.count;
}, 0);
}
_getAllGroupValuesSet(values) {
return values.filter((value) => {
return value.count > 0;
});
}
_logGroupValues(values) {
const onlyValuesSet = this._getAllGroupValuesSet(values);
const longestValue = this._getLongestGroupValue(onlyValuesSet);
for (const [index, value] of onlyValuesSet.entries()) {
const prefix = index === onlyValuesSet.length - 1 ? '└──' : '├──';
this._logCount(`${chalk_1.default.white(prefix)} ${value.name.padEnd(longestValue, ' ')}`, value.count);
}
}
_getLongestGroupValue(values) {
return values.reduce((longestValue, value) => {
return value.name.length > longestValue
? value.name.length
: longestValue;
}, 0);
}
}
exports.Statistics = Statistics;

View File

@ -94,7 +94,7 @@ export class IssuesProcessor {
for (const issue of issues.values()) {
const issueLogger: IssueLogger = new IssueLogger(issue);
this._statistics?.incrementProcessedIssuesCount();
this._statistics?.incrementProcessedItemsCount(issue);
issueLogger.info(`Found this $$type last updated ${issue.updated_at}`);
@ -320,7 +320,7 @@ export class IssuesProcessor {
// find any comments since date on the given issue
try {
this._operations.consumeOperation();
this._statistics?.incrementFetchedIssuesCommentsCount();
this._statistics?.incrementFetchedItemsCommentsCount();
const comments = await this.client.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
@ -366,7 +366,7 @@ export class IssuesProcessor {
page
}
);
this._statistics?.incrementFetchedIssuesCount(issueResult.data.length);
this._statistics?.incrementFetchedItemsCount(issueResult.data.length);
return issueResult.data.map(
(issue: Readonly<IIssue>): Issue => new Issue(this.options, issue)
@ -388,7 +388,7 @@ export class IssuesProcessor {
issueLogger.info(`Checking for label on $$type`);
this._operations.consumeOperation();
this._statistics?.incrementFetchedIssuesEventsCount();
this._statistics?.incrementFetchedItemsEventsCount();
const options = this.client.issues.listEvents.endpoint.merge({
owner: context.repo.owner,
repo: context.repo.repo,
@ -526,7 +526,7 @@ export class IssuesProcessor {
if (!skipMessage) {
try {
this._operations.consumeOperation();
this._statistics?.incrementAddedComment();
this._statistics?.incrementAddedItemsComment(issue);
await this.client.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@ -540,8 +540,8 @@ export class IssuesProcessor {
try {
this._operations.consumeOperation();
this._statistics?.incrementAddedLabel();
this._statistics?.incrementStaleIssuesCount();
this._statistics?.incrementAddedItemsLabel(issue);
this._statistics?.incrementStaleItemsCount(issue);
await this.client.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
@ -571,7 +571,7 @@ export class IssuesProcessor {
if (closeMessage) {
try {
this._operations.consumeOperation();
this._statistics?.incrementAddedComment();
this._statistics?.incrementAddedItemsComment(issue);
await this.client.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
@ -586,7 +586,7 @@ export class IssuesProcessor {
if (closeLabel) {
try {
this._operations.consumeOperation();
this._statistics?.incrementAddedLabel();
this._statistics?.incrementAddedItemsLabel(issue);
await this.client.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
@ -600,7 +600,7 @@ export class IssuesProcessor {
try {
this._operations.consumeOperation();
this._statistics?.incrementClosedIssuesCount();
this._statistics?.incrementClosedItemsCount(issue);
await this.client.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
@ -673,7 +673,7 @@ export class IssuesProcessor {
}
}
// Remove a label from an issue
// Remove a label from an issue or a pull request
private async _removeLabel(issue: Issue, label: string): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
@ -686,7 +686,7 @@ export class IssuesProcessor {
try {
this._operations.consumeOperation();
this._statistics?.incrementDeletedLabelsCount();
this._statistics?.incrementDeletedItemsLabelsCount(issue);
await this.client.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
@ -747,7 +747,7 @@ export class IssuesProcessor {
);
await this._removeLabel(issue, staleLabel);
this._statistics?.incrementUndoStaleIssuesCount();
this._statistics?.incrementUndoStaleItemsCount(issue);
}
private async _removeCloseLabel(
@ -772,7 +772,7 @@ export class IssuesProcessor {
);
await this._removeLabel(issue, closeLabel);
this._statistics?.incrementDeletedCloseLabelsCount();
this._statistics?.incrementDeletedCloseItemsLabelsCount(issue);
}
}
}

View File

@ -1,39 +1,68 @@
import chalk from 'chalk';
import {Issue} from './issue';
import {Logger} from './loggers/logger';
interface IGroupValue {
name: string;
count: number;
}
export class Statistics {
private readonly _logger: Logger = new Logger();
private _processedIssuesCount = 0;
private _processedPullRequestsCount = 0;
private _staleIssuesCount = 0;
private _stalePullRequestsCount = 0;
private _undoStaleIssuesCount = 0;
private _undoStalePullRequestsCount = 0;
private _operationsCount = 0;
private _closedIssuesCount = 0;
private _deletedLabelsCount = 0;
private _deletedCloseLabelsCount = 0;
private _closedPullRequestsCount = 0;
private _deletedIssuesLabelsCount = 0;
private _deletedPullRequestsLabelsCount = 0;
private _deletedCloseIssuesLabelsCount = 0;
private _deletedClosePullRequestsLabelsCount = 0;
private _deletedBranchesCount = 0;
private _addedLabelsCount = 0;
private _addedCommentsCount = 0;
private _fetchedIssuesCount = 0;
private _fetchedIssuesEventsCount = 0;
private _fetchedIssuesCommentsCount = 0;
private _addedIssuesLabelsCount = 0;
private _addedPullRequestsLabelsCount = 0;
private _addedIssuesCommentsCount = 0;
private _addedPullRequestsCommentsCount = 0;
private _fetchedItemsCount = 0;
private _fetchedItemsEventsCount = 0;
private _fetchedItemsCommentsCount = 0;
private _fetchedPullRequestsCount = 0;
incrementProcessedIssuesCount(increment: Readonly<number> = 1): Statistics {
this._processedIssuesCount += increment;
return this;
incrementProcessedItemsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementProcessedPullRequestsCount(increment);
}
incrementStaleIssuesCount(increment: Readonly<number> = 1): Statistics {
this._staleIssuesCount += increment;
return this;
return this._incrementProcessedIssuesCount(increment);
}
incrementUndoStaleIssuesCount(increment: Readonly<number> = 1): Statistics {
this._undoStaleIssuesCount += increment;
incrementStaleItemsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementStalePullRequestsCount(increment);
}
return this;
return this._incrementStaleIssuesCount(increment);
}
incrementUndoStaleItemsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementUndoStalePullRequestsCount(increment);
}
return this._incrementUndoStaleIssuesCount(increment);
}
setOperationsLeft(operationsLeft: Readonly<number>): Statistics {
@ -42,24 +71,37 @@ export class Statistics {
return this;
}
incrementClosedIssuesCount(increment: Readonly<number> = 1): Statistics {
this._closedIssuesCount += increment;
return this;
}
incrementDeletedLabelsCount(increment: Readonly<number> = 1): Statistics {
this._deletedLabelsCount += increment;
return this;
}
incrementDeletedCloseLabelsCount(
incrementClosedItemsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
this._deletedCloseLabelsCount += increment;
if (issue.isPullRequest) {
return this._incrementClosedPullRequestsCount(increment);
}
return this;
return this._incrementClosedIssuesCount(increment);
}
incrementDeletedItemsLabelsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementDeletedPullRequestsLabelsCount(increment);
}
return this._incrementDeletedIssuesLabelsCount(increment);
}
incrementDeletedCloseItemsLabelsCount(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementDeletedClosePullRequestsLabelsCount(increment);
}
return this._incrementDeletedCloseIssuesLabelsCount(increment);
}
incrementDeletedBranchesCount(increment: Readonly<number> = 1): Statistics {
@ -68,36 +110,46 @@ export class Statistics {
return this;
}
incrementAddedLabel(increment: Readonly<number> = 1): Statistics {
this._addedLabelsCount += increment;
return this;
}
incrementAddedComment(increment: Readonly<number> = 1): Statistics {
this._addedCommentsCount += increment;
return this;
}
incrementFetchedIssuesCount(increment: Readonly<number> = 1): Statistics {
this._fetchedIssuesCount += increment;
return this;
}
incrementFetchedIssuesEventsCount(
incrementAddedItemsLabel(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
this._fetchedIssuesEventsCount += increment;
if (issue.isPullRequest) {
return this._incrementAddedPullRequestsLabel(increment);
}
return this._incrementAddedIssuesLabel(increment);
}
incrementAddedItemsComment(
issue: Readonly<Issue>,
increment: Readonly<number> = 1
): Statistics {
if (issue.isPullRequest) {
return this._incrementAddedPullRequestsComment(increment);
}
return this._incrementAddedIssuesComment(increment);
}
incrementFetchedItemsCount(increment: Readonly<number> = 1): Statistics {
this._fetchedItemsCount += increment;
return this;
}
incrementFetchedIssuesCommentsCount(
incrementFetchedItemsEventsCount(
increment: Readonly<number> = 1
): Statistics {
this._fetchedIssuesCommentsCount += increment;
this._fetchedItemsEventsCount += increment;
return this;
}
incrementFetchedItemsCommentsCount(
increment: Readonly<number> = 1
): Statistics {
this._fetchedItemsCommentsCount += increment;
return this;
}
@ -112,83 +164,357 @@ export class Statistics {
logStats(): Statistics {
this._logger.info(chalk.yellow.bold('Statistics:'));
this._logProcessedIssuesCount();
this._logStaleIssuesCount();
this._logUndoStaleIssuesCount();
this._logOperationsCount();
this._logClosedIssuesCount();
this._logDeletedLabelsCount();
this._logDeletedCloseLabelsCount();
this._logProcessedIssuesAndPullRequestsCount();
this._logStaleIssuesAndPullRequestsCount();
this._logUndoStaleIssuesAndPullRequestsCount();
this._logClosedIssuesAndPullRequestsCount();
this._logDeletedIssuesAndPullRequestsLabelsCount();
this._logDeletedCloseIssuesAndPullRequestsLabelsCount();
this._logDeletedBranchesCount();
this._logAddedLabelsCount();
this._logAddedCommentsCount();
this._logFetchedIssuesCount();
this._logFetchedIssuesEventsCount();
this._logFetchedIssuesCommentsCount();
this._logAddedIssuesAndPullRequestsLabelsCount();
this._logAddedIssuesAndPullRequestsCommentsCount();
this._logFetchedItemsCount();
this._logFetchedItemsEventsCount();
this._logFetchedItemsCommentsCount();
this._logFetchedPullRequestsCount();
this._logOperationsCount();
return this;
}
private _logProcessedIssuesCount(): void {
this._logCount('Processed issues/PRs', this._processedIssuesCount);
private _incrementProcessedIssuesCount(
increment: Readonly<number> = 1
): Statistics {
this._processedIssuesCount += increment;
return this;
}
private _logStaleIssuesCount(): void {
this._logCount('New stale issues/PRs', this._staleIssuesCount);
private _incrementProcessedPullRequestsCount(
increment: Readonly<number> = 1
): Statistics {
this._processedPullRequestsCount += increment;
return this;
}
private _logUndoStaleIssuesCount(): void {
this._logCount('No longer stale issues/PRs', this._undoStaleIssuesCount);
private _incrementStaleIssuesCount(
increment: Readonly<number> = 1
): Statistics {
this._staleIssuesCount += increment;
return this;
}
private _logOperationsCount(): void {
this._logCount('Operations performed', this._operationsCount);
private _incrementStalePullRequestsCount(
increment: Readonly<number> = 1
): Statistics {
this._stalePullRequestsCount += increment;
return this;
}
private _logClosedIssuesCount(): void {
this._logCount('Closed issues', this._closedIssuesCount);
private _incrementUndoStaleIssuesCount(
increment: Readonly<number> = 1
): Statistics {
this._undoStaleIssuesCount += increment;
return this;
}
private _logDeletedLabelsCount(): void {
this._logCount('Deleted labels', this._deletedLabelsCount);
private _incrementUndoStalePullRequestsCount(
increment: Readonly<number> = 1
): Statistics {
this._undoStalePullRequestsCount += increment;
return this;
}
private _logDeletedCloseLabelsCount(): void {
this._logCount('Deleted close labels', this._deletedCloseLabelsCount);
private _incrementClosedIssuesCount(
increment: Readonly<number> = 1
): Statistics {
this._closedIssuesCount += increment;
return this;
}
private _incrementClosedPullRequestsCount(
increment: Readonly<number> = 1
): Statistics {
this._closedPullRequestsCount += increment;
return this;
}
private _incrementDeletedIssuesLabelsCount(
increment: Readonly<number> = 1
): Statistics {
this._deletedIssuesLabelsCount += increment;
return this;
}
private _incrementDeletedPullRequestsLabelsCount(
increment: Readonly<number> = 1
): Statistics {
this._deletedPullRequestsLabelsCount += increment;
return this;
}
private _incrementDeletedCloseIssuesLabelsCount(
increment: Readonly<number> = 1
): Statistics {
this._deletedCloseIssuesLabelsCount += increment;
return this;
}
private _incrementDeletedClosePullRequestsLabelsCount(
increment: Readonly<number> = 1
): Statistics {
this._deletedClosePullRequestsLabelsCount += increment;
return this;
}
private _incrementAddedIssuesLabel(
increment: Readonly<number> = 1
): Statistics {
this._addedIssuesLabelsCount += increment;
return this;
}
private _incrementAddedPullRequestsLabel(
increment: Readonly<number> = 1
): Statistics {
this._addedPullRequestsLabelsCount += increment;
return this;
}
private _incrementAddedIssuesComment(
increment: Readonly<number> = 1
): Statistics {
this._addedIssuesCommentsCount += increment;
return this;
}
private _incrementAddedPullRequestsComment(
increment: Readonly<number> = 1
): Statistics {
this._addedPullRequestsCommentsCount += increment;
return this;
}
private _logProcessedIssuesAndPullRequestsCount(): void {
this._logGroup('Processed items', [
{
name: 'Processed issues',
count: this._processedIssuesCount
},
{
name: 'Processed PRs',
count: this._processedPullRequestsCount
}
]);
}
private _logStaleIssuesAndPullRequestsCount(): void {
this._logGroup('New stale items', [
{
name: 'New stale issues',
count: this._staleIssuesCount
},
{
name: 'New stale PRs',
count: this._stalePullRequestsCount
}
]);
}
private _logUndoStaleIssuesAndPullRequestsCount(): void {
this._logGroup('No longer stale items', [
{
name: 'No longer stale issues',
count: this._undoStaleIssuesCount
},
{
name: 'No longer stale PRs',
count: this._undoStalePullRequestsCount
}
]);
}
private _logClosedIssuesAndPullRequestsCount(): void {
this._logGroup('Closed items', [
{
name: 'Closed issues',
count: this._closedIssuesCount
},
{
name: 'Closed PRs',
count: this._closedPullRequestsCount
}
]);
}
private _logDeletedIssuesAndPullRequestsLabelsCount(): void {
this._logGroup('Deleted items labels', [
{
name: 'Deleted issues labels',
count: this._deletedIssuesLabelsCount
},
{
name: 'Deleted PRs labels',
count: this._deletedPullRequestsLabelsCount
}
]);
}
private _logDeletedCloseIssuesAndPullRequestsLabelsCount(): void {
this._logGroup('Deleted close items labels', [
{
name: 'Deleted close issues labels',
count: this._deletedCloseIssuesLabelsCount
},
{
name: 'Deleted close PRs labels',
count: this._deletedClosePullRequestsLabelsCount
}
]);
}
private _logDeletedBranchesCount(): void {
this._logCount('Deleted branches', this._deletedBranchesCount);
}
private _logAddedLabelsCount(): void {
this._logCount('Added labels', this._addedLabelsCount);
private _logAddedIssuesAndPullRequestsLabelsCount(): void {
this._logGroup('Added items labels', [
{
name: 'Added issues labels',
count: this._addedIssuesLabelsCount
},
{
name: 'Added PRs labels',
count: this._addedPullRequestsLabelsCount
}
]);
}
private _logAddedCommentsCount(): void {
this._logCount('Added comments', this._addedCommentsCount);
private _logAddedIssuesAndPullRequestsCommentsCount(): void {
this._logGroup('Added items comments', [
{
name: 'Added issues comments',
count: this._addedIssuesCommentsCount
},
{
name: 'Added PRs comments',
count: this._addedPullRequestsCommentsCount
}
]);
}
private _logFetchedIssuesCount(): void {
this._logCount('Fetched issues', this._fetchedIssuesCount);
private _logFetchedItemsCount(): void {
this._logCount('Fetched items', this._fetchedItemsCount);
}
private _logFetchedIssuesEventsCount(): void {
this._logCount('Fetched issues events', this._fetchedIssuesEventsCount);
private _logFetchedItemsEventsCount(): void {
this._logCount('Fetched items events', this._fetchedItemsEventsCount);
}
private _logFetchedIssuesCommentsCount(): void {
this._logCount('Fetched issues comments', this._fetchedIssuesCommentsCount);
private _logFetchedItemsCommentsCount(): void {
this._logCount('Fetched items comments', this._fetchedItemsCommentsCount);
}
private _logFetchedPullRequestsCount(): void {
this._logCount('Fetched pull requests', this._fetchedPullRequestsCount);
}
private _logOperationsCount(): void {
this._logCount('Operations performed', this._operationsCount);
}
private _logCount(name: Readonly<string>, count: Readonly<number>): void {
if (count > 0) {
this._logger.info(`${name}:`, chalk.cyan(count));
}
}
private _logGroup(groupName: Readonly<string>, values: IGroupValue[]): void {
if (this._isGroupValuesPartiallySet(values)) {
this._logCount(groupName, this._getGroupValuesTotalCount(values));
this._logGroupValues(values);
} else {
// Only one value will be display
for (const value of values) {
this._logCount(value.name, value.count);
}
}
}
/**
* @private
* @description
* If there is a least two elements with a valid count then it's partially set
* Useful to defined if we should display the values as a group or not
*
* @param {IGroupValue[]} values The list of group values to check
*/
private _isGroupValuesPartiallySet(values: IGroupValue[]): boolean {
return (
values
.map((value: Readonly<IGroupValue>): boolean => {
return value.count > 0;
})
.filter((isSet: Readonly<boolean>): boolean => isSet).length >= 2
);
}
private _getGroupValuesTotalCount(values: IGroupValue[]): number {
return values.reduce(
(count: Readonly<number>, value: Readonly<IGroupValue>): number => {
return count + value.count;
},
0
);
}
private _getAllGroupValuesSet(values: IGroupValue[]): IGroupValue[] {
return values.filter((value: Readonly<IGroupValue>): boolean => {
return value.count > 0;
});
}
private _logGroupValues(values: IGroupValue[]): void {
const onlyValuesSet: IGroupValue[] = this._getAllGroupValuesSet(values);
const longestValue: number = this._getLongestGroupValue(onlyValuesSet);
for (const [index, value] of onlyValuesSet.entries()) {
const prefix = index === onlyValuesSet.length - 1 ? '└──' : '├──';
this._logCount(
`${chalk.white(prefix)} ${value.name.padEnd(longestValue, ' ')}`,
value.count
);
}
}
private _getLongestGroupValue(values: IGroupValue[]): number {
return values.reduce(
(
longestValue: Readonly<number>,
value: Readonly<IGroupValue>
): number => {
return value.name.length > longestValue
? value.name.length
: longestValue;
},
0
);
}
}