all-contributors-for-repository 0.5.2 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,7 @@ The types of contributions detected from the GitHub API are:
51
51
  - 📖 `doc`: authors of merged PRs that address issues labeled as accepting PRs and docs _(see [Options](#options))_
52
52
  - 🚧 `maintenance`: adding labels to issues and PRs, and merging PRs
53
53
  - 👀 `review`: submitting a review for a PR
54
+ - ⚠️ `test`: authors of merged PRs that touch test files _(see [Options](#options))_
54
55
  - 🔧 `tool`: authors of merged PRs that address issues labeled as accepting PRs and tooling _(see [Options](#options))_
55
56
 
56
57
  Additionally, based on PR [conventional commit titles](https://www.conventionalcommits.org/en/v1.0.0/#summary) in the [Angular convention](https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md#type), for all PR authors and co-authors:
@@ -91,6 +92,9 @@ It additionally allows for the following optional options.
91
92
  - `labelTypeDocs` _(`string`)_: Label to indicate an issue is for documentation.
92
93
  - `labelTypeIdeas` _(`string`)_: Label to indicate an issue is for a feature.
93
94
  - `labelTypeTool` _(`string`)_: Label to indicate an issue is for tooling.
95
+ - `testFiles` _(`RegExp[]`)_: Regular expressions for file paths that count as tests, for merged PRs to be given a `test` contribution.
96
+ - Default: `[/\.(spec|test)\.[^/]+$/i, /(^|\/)(__tests__|tests?)\//i]`
97
+ - Pass `[]` to skip looking at PR files altogether.
94
98
 
95
99
  ```ts
96
100
  import { getAllContributorsForRepository } from "all-contributors-for-repository";
@@ -103,6 +107,7 @@ getAllContributorsForRepository({
103
107
  labelTypeDocs: "docs",
104
108
  labelTypeIdeas: "feature",
105
109
  labelTypeTool: "tool",
110
+ testFiles: [/^tests\//],
106
111
  });
107
112
  ```
108
113
 
@@ -1,7 +1,8 @@
1
1
  import { ContributorsCollection } from "../../ContributorsCollection.js";
2
+ import { AllContributorsForRepositoryOptions } from "../../options.js";
2
3
  import { MergedPull } from "../collecting/collectMergedPulls.js";
3
4
  import { Octokit } from "octokit";
4
5
  //#region src/collect/adding/addMergedPulls.d.ts
5
- export declare function addMergedPulls(mergedPulls: MergedPull[], contributors: Pick<ContributorsCollection, "add">, octokit: Octokit): Promise<void>;
6
+ export declare function addMergedPulls(mergedPulls: MergedPull[], contributors: Pick<ContributorsCollection, "add">, octokit: Octokit, options: Pick<AllContributorsForRepositoryOptions, "owner" | "repo" | "testFiles">): Promise<void>;
6
7
  //#endregion
7
8
  //# sourceMappingURL=addMergedPulls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addMergedPulls.d.ts","names":[],"sources":["../../../src/collect/adding/addMergedPulls.ts"],"mappings":";;;;wBAQsB,eACrB,aAAa,cACb,cAAc,KAAK,gCACnB,SAAS,UAAO"}
1
+ {"version":3,"file":"addMergedPulls.d.ts","names":[],"sources":["../../../src/collect/adding/addMergedPulls.ts"],"mappings":";;;;;wBAUsB,eACrB,aAAa,cACb,cAAc,KAAK,gCACnB,SAAS,SACT,SAAS,KACR,uEAEA"}
@@ -1,13 +1,22 @@
1
+ import { collectPullFiles } from "../collecting/collectPullFiles.js";
1
2
  import { parseMergedPullAuthors } from "../parsing/parseMergedPullAuthors.js";
2
3
  import { parseMergedPullType } from "../parsing/parseMergedPullType.js";
3
4
  import { createCachingCoAuthorToUsername } from "co-author-to-username";
4
5
  //#region src/collect/adding/addMergedPulls.ts
5
- async function addMergedPulls(mergedPulls, contributors, octokit) {
6
+ async function addMergedPulls(mergedPulls, contributors, octokit, options) {
6
7
  const cachingCoAuthorToUsername = createCachingCoAuthorToUsername({ fetcher: octokit });
8
+ const defaults = {
9
+ owner: options.owner,
10
+ repo: options.repo
11
+ };
7
12
  for (const mergedPull of mergedPulls) {
8
13
  const authors = await parseMergedPullAuthors(mergedPull, cachingCoAuthorToUsername);
9
- const type = parseMergedPullType(mergedPull.title);
10
- for (const author of authors) contributors.add(author, mergedPull.number, type);
14
+ const types = [parseMergedPullType(mergedPull.title)];
15
+ if (!types.includes("test") && options.testFiles.length && await touchesTestFiles(mergedPull.number)) types.push("test");
16
+ for (const author of authors) for (const type of types) contributors.add(author, mergedPull.number, type);
17
+ }
18
+ async function touchesTestFiles(pullNumber) {
19
+ return (await collectPullFiles(defaults, octokit, pullNumber)).some((file) => options.testFiles.some((pattern) => pattern.test(file.filename)));
11
20
  }
12
21
  }
13
22
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"addMergedPulls.js","names":[],"sources":["../../../src/collect/adding/addMergedPulls.ts"],"sourcesContent":["import { createCachingCoAuthorToUsername } from \"co-author-to-username\";\nimport { Octokit } from \"octokit\";\n\nimport { ContributorsCollection } from \"../../ContributorsCollection.js\";\nimport { MergedPull } from \"../collecting/collectMergedPulls.js\";\nimport { parseMergedPullAuthors } from \"../parsing/parseMergedPullAuthors.js\";\nimport { parseMergedPullType } from \"../parsing/parseMergedPullType.js\";\n\nexport async function addMergedPulls(\n\tmergedPulls: MergedPull[],\n\tcontributors: Pick<ContributorsCollection, \"add\">,\n\toctokit: Octokit,\n) {\n\tconst cachingCoAuthorToUsername = createCachingCoAuthorToUsername({\n\t\tfetcher: octokit,\n\t});\n\n\tfor (const mergedPull of mergedPulls) {\n\t\tconst authors = await parseMergedPullAuthors(\n\t\t\tmergedPull,\n\t\t\tcachingCoAuthorToUsername,\n\t\t);\n\t\tconst type = parseMergedPullType(mergedPull.title);\n\n\t\tfor (const author of authors) {\n\t\t\tcontributors.add(author, mergedPull.number, type);\n\t\t}\n\t}\n}\n"],"mappings":";;;;AAQA,eAAsB,eACrB,aACA,cACA,SACC;CACD,MAAM,4BAA4B,gCAAgC,EACjE,SAAS,QACV,CAAC;CAED,KAAK,MAAM,cAAc,aAAa;EACrC,MAAM,UAAU,MAAM,uBACrB,YACA,yBACD;EACA,MAAM,OAAO,oBAAoB,WAAW,KAAK;EAEjD,KAAK,MAAM,UAAU,SACpB,aAAa,IAAI,QAAQ,WAAW,QAAQ,IAAI;CAElD;AACD"}
1
+ {"version":3,"file":"addMergedPulls.js","names":[],"sources":["../../../src/collect/adding/addMergedPulls.ts"],"sourcesContent":["import { createCachingCoAuthorToUsername } from \"co-author-to-username\";\nimport { Octokit } from \"octokit\";\n\nimport { ContributorsCollection } from \"../../ContributorsCollection.js\";\nimport { AllContributorsForRepositoryOptions } from \"../../options.js\";\nimport { MergedPull } from \"../collecting/collectMergedPulls.js\";\nimport { collectPullFiles } from \"../collecting/collectPullFiles.js\";\nimport { parseMergedPullAuthors } from \"../parsing/parseMergedPullAuthors.js\";\nimport { parseMergedPullType } from \"../parsing/parseMergedPullType.js\";\n\nexport async function addMergedPulls(\n\tmergedPulls: MergedPull[],\n\tcontributors: Pick<ContributorsCollection, \"add\">,\n\toctokit: Octokit,\n\toptions: Pick<\n\t\tAllContributorsForRepositoryOptions,\n\t\t\"owner\" | \"repo\" | \"testFiles\"\n\t>,\n) {\n\tconst cachingCoAuthorToUsername = createCachingCoAuthorToUsername({\n\t\tfetcher: octokit,\n\t});\n\tconst defaults = { owner: options.owner, repo: options.repo };\n\n\tfor (const mergedPull of mergedPulls) {\n\t\tconst authors = await parseMergedPullAuthors(\n\t\t\tmergedPull,\n\t\t\tcachingCoAuthorToUsername,\n\t\t);\n\t\tconst types = [parseMergedPullType(mergedPull.title)];\n\n\t\tif (\n\t\t\t!types.includes(\"test\") &&\n\t\t\toptions.testFiles.length &&\n\t\t\t(await touchesTestFiles(mergedPull.number))\n\t\t) {\n\t\t\ttypes.push(\"test\");\n\t\t}\n\n\t\tfor (const author of authors) {\n\t\t\tfor (const type of types) {\n\t\t\t\tcontributors.add(author, mergedPull.number, type);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function touchesTestFiles(pullNumber: number) {\n\t\tconst files = await collectPullFiles(defaults, octokit, pullNumber);\n\n\t\treturn files.some((file) =>\n\t\t\toptions.testFiles.some((pattern) => pattern.test(file.filename)),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;AAUA,eAAsB,eACrB,aACA,cACA,SACA,SAIC;CACD,MAAM,4BAA4B,gCAAgC,EACjE,SAAS,QACV,CAAC;CACD,MAAM,WAAW;EAAE,OAAO,QAAQ;EAAO,MAAM,QAAQ;CAAK;CAE5D,KAAK,MAAM,cAAc,aAAa;EACrC,MAAM,UAAU,MAAM,uBACrB,YACA,yBACD;EACA,MAAM,QAAQ,CAAC,oBAAoB,WAAW,KAAK,CAAC;EAEpD,IACC,CAAC,MAAM,SAAS,MAAM,KACtB,QAAQ,UAAU,UACjB,MAAM,iBAAiB,WAAW,MAAM,GAEzC,MAAM,KAAK,MAAM;EAGlB,KAAK,MAAM,UAAU,SACpB,KAAK,MAAM,QAAQ,OAClB,aAAa,IAAI,QAAQ,WAAW,QAAQ,IAAI;CAGnD;CAEA,eAAe,iBAAiB,YAAoB;EAGnD,QAAO,MAFa,iBAAiB,UAAU,SAAS,UAAU,EAAA,CAErD,MAAM,SAClB,QAAQ,UAAU,MAAM,YAAY,QAAQ,KAAK,KAAK,QAAQ,CAAC,CAChE;CACD;AACD"}
@@ -0,0 +1,18 @@
1
+ import { PaginatingOctokit, RequestDefaults } from "../api.js";
2
+ //#region src/collect/collecting/collectPullFiles.d.ts
3
+ export type PullFile = Awaited<ReturnType<typeof collectPullFiles>>[number];
4
+ export declare function collectPullFiles(defaults: RequestDefaults, octokit: PaginatingOctokit, pullNumber: number): Promise<{
5
+ sha: string | null;
6
+ filename: string;
7
+ status: "added" | "removed" | "modified" | "renamed" | "copied" | "changed" | "unchanged";
8
+ additions: number;
9
+ deletions: number;
10
+ changes: number;
11
+ blob_url: string;
12
+ raw_url: string;
13
+ contents_url: string;
14
+ patch?: string;
15
+ previous_filename?: string;
16
+ }[]>;
17
+ //#endregion
18
+ //# sourceMappingURL=collectPullFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectPullFiles.d.ts","names":[],"sources":["../../../src/collect/collecting/collectPullFiles.ts"],"mappings":";;YAOY,WAAW,QAAQ,kBAAkB;wBAE3B,iBACrB,UAAU,iBACV,SAAS,mBACT,qBAAkB"}
@@ -0,0 +1,13 @@
1
+ import { paginate } from "../api.js";
2
+ //#region src/collect/collecting/collectPullFiles.ts
3
+ async function collectPullFiles(defaults, octokit, pullNumber) {
4
+ return await paginate(octokit.paginate.iterator("GET /repos/{owner}/{repo}/pulls/{pull_number}/files", {
5
+ ...defaults,
6
+ per_page: 100,
7
+ pull_number: pullNumber
8
+ }));
9
+ }
10
+ //#endregion
11
+ export { collectPullFiles };
12
+
13
+ //# sourceMappingURL=collectPullFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collectPullFiles.js","names":[],"sources":["../../../src/collect/collecting/collectPullFiles.ts"],"sourcesContent":["import {\n\tpaginate,\n\tPaginatingOctokit,\n\tperPage,\n\tRequestDefaults,\n} from \"../api.js\";\n\nexport type PullFile = Awaited<ReturnType<typeof collectPullFiles>>[number];\n\nexport async function collectPullFiles(\n\tdefaults: RequestDefaults,\n\toctokit: PaginatingOctokit,\n\tpullNumber: number,\n) {\n\treturn await paginate(\n\t\toctokit.paginate.iterator(\n\t\t\t\"GET /repos/{owner}/{repo}/pulls/{pull_number}/files\",\n\t\t\t{\n\t\t\t\t...defaults,\n\t\t\t\tper_page: perPage,\n\t\t\t\tpull_number: pullNumber,\n\t\t\t},\n\t\t),\n\t);\n}\n"],"mappings":";;AASA,eAAsB,iBACrB,UACA,SACA,YACC;CACD,OAAO,MAAM,SACZ,QAAQ,SAAS,SAChB,uDACA;EACC,GAAG;EACH,UAAA;EACA,aAAa;CACd,CACD,CACD;AACD"}
@@ -1,6 +1,6 @@
1
1
  import { addAcceptedIssues } from "./adding/addAcceptedIssues.js";
2
- import { addMergedPulls } from "./adding/addMergedPulls.js";
3
2
  import { createOctokit } from "./api.js";
3
+ import { addMergedPulls } from "./adding/addMergedPulls.js";
4
4
  import { collectAcceptedIssues } from "./collecting/collectAcceptedIssues.js";
5
5
  import { collectIssueEvents } from "./collecting/collectIssueEvents.js";
6
6
  import { collectMergedPulls } from "./collecting/collectMergedPulls.js";
@@ -21,7 +21,7 @@ async function collect(options) {
21
21
  ]);
22
22
  const contributors = processContributors(issueEvents, repoEvents, options);
23
23
  addAcceptedIssues(Object.values(acceptedIssues), contributors, options);
24
- await addMergedPulls(mergedPulls, contributors, octokit);
24
+ await addMergedPulls(mergedPulls, contributors, octokit, options);
25
25
  return contributors.collect();
26
26
  }
27
27
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/collect/index.ts"],"sourcesContent":["import { ContributorsContributions } from \"../ContributorsCollection.js\";\nimport { AllContributorsForRepositoryOptions } from \"../options.js\";\nimport { addAcceptedIssues } from \"./adding/addAcceptedIssues.js\";\nimport { addMergedPulls } from \"./adding/addMergedPulls.js\";\nimport { createOctokit } from \"./api.js\";\nimport { collectAcceptedIssues } from \"./collecting/collectAcceptedIssues.js\";\nimport { collectIssueEvents } from \"./collecting/collectIssueEvents.js\";\nimport { collectMergedPulls } from \"./collecting/collectMergedPulls.js\";\nimport { collectRepoEvents } from \"./collecting/collectRepoEvents.js\";\nimport { processContributors } from \"./processing/processContributors.js\";\n\nexport async function collect(\n\toptions: AllContributorsForRepositoryOptions,\n): Promise<ContributorsContributions> {\n\tconst defaults = { owner: options.owner, repo: options.repo };\n\tconst octokit = await createOctokit(options.auth);\n\n\t// 1. Collect event data from the GitHub API\n\tconst [acceptedIssues, issueEvents, mergedPulls, repoEvents] =\n\t\tawait Promise.all([\n\t\t\tcollectAcceptedIssues(defaults, octokit, options.labelAcceptingPrs),\n\t\t\tcollectIssueEvents(defaults, octokit),\n\t\t\tcollectMergedPulls(defaults, octokit),\n\t\t\tcollectRepoEvents(defaults, octokit),\n\t\t]);\n\n\t// 2. Process individual contributors from those events\n\tconst contributors = processContributors(issueEvents, repoEvents, options);\n\n\t// 3. Add additional contributors based on issues and pulls\n\taddAcceptedIssues(Object.values(acceptedIssues), contributors, options);\n\tawait addMergedPulls(mergedPulls, contributors, octokit);\n\n\t// 4. Collect the contributions under each contributor\n\treturn contributors.collect();\n}\n"],"mappings":";;;;;;;;;AAWA,eAAsB,QACrB,SACqC;CACrC,MAAM,WAAW;EAAE,OAAO,QAAQ;EAAO,MAAM,QAAQ;CAAK;CAC5D,MAAM,UAAU,MAAM,cAAc,QAAQ,IAAI;CAGhD,MAAM,CAAC,gBAAgB,aAAa,aAAa,cAChD,MAAM,QAAQ,IAAI;EACjB,sBAAsB,UAAU,SAAS,QAAQ,iBAAiB;EAClE,mBAAmB,UAAU,OAAO;EACpC,mBAAmB,UAAU,OAAO;EACpC,kBAAkB,UAAU,OAAO;CACpC,CAAC;CAGF,MAAM,eAAe,oBAAoB,aAAa,YAAY,OAAO;CAGzE,kBAAkB,OAAO,OAAO,cAAc,GAAG,cAAc,OAAO;CACtE,MAAM,eAAe,aAAa,cAAc,OAAO;CAGvD,OAAO,aAAa,QAAQ;AAC7B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/collect/index.ts"],"sourcesContent":["import { ContributorsContributions } from \"../ContributorsCollection.js\";\nimport { AllContributorsForRepositoryOptions } from \"../options.js\";\nimport { addAcceptedIssues } from \"./adding/addAcceptedIssues.js\";\nimport { addMergedPulls } from \"./adding/addMergedPulls.js\";\nimport { createOctokit } from \"./api.js\";\nimport { collectAcceptedIssues } from \"./collecting/collectAcceptedIssues.js\";\nimport { collectIssueEvents } from \"./collecting/collectIssueEvents.js\";\nimport { collectMergedPulls } from \"./collecting/collectMergedPulls.js\";\nimport { collectRepoEvents } from \"./collecting/collectRepoEvents.js\";\nimport { processContributors } from \"./processing/processContributors.js\";\n\nexport async function collect(\n\toptions: AllContributorsForRepositoryOptions,\n): Promise<ContributorsContributions> {\n\tconst defaults = { owner: options.owner, repo: options.repo };\n\tconst octokit = await createOctokit(options.auth);\n\n\t// 1. Collect event data from the GitHub API\n\tconst [acceptedIssues, issueEvents, mergedPulls, repoEvents] =\n\t\tawait Promise.all([\n\t\t\tcollectAcceptedIssues(defaults, octokit, options.labelAcceptingPrs),\n\t\t\tcollectIssueEvents(defaults, octokit),\n\t\t\tcollectMergedPulls(defaults, octokit),\n\t\t\tcollectRepoEvents(defaults, octokit),\n\t\t]);\n\n\t// 2. Process individual contributors from those events\n\tconst contributors = processContributors(issueEvents, repoEvents, options);\n\n\t// 3. Add additional contributors based on issues and pulls\n\taddAcceptedIssues(Object.values(acceptedIssues), contributors, options);\n\tawait addMergedPulls(mergedPulls, contributors, octokit, options);\n\n\t// 4. Collect the contributions under each contributor\n\treturn contributors.collect();\n}\n"],"mappings":";;;;;;;;;AAWA,eAAsB,QACrB,SACqC;CACrC,MAAM,WAAW;EAAE,OAAO,QAAQ;EAAO,MAAM,QAAQ;CAAK;CAC5D,MAAM,UAAU,MAAM,cAAc,QAAQ,IAAI;CAGhD,MAAM,CAAC,gBAAgB,aAAa,aAAa,cAChD,MAAM,QAAQ,IAAI;EACjB,sBAAsB,UAAU,SAAS,QAAQ,iBAAiB;EAClE,mBAAmB,UAAU,OAAO;EACpC,mBAAmB,UAAU,OAAO;EACpC,kBAAkB,UAAU,OAAO;CACpC,CAAC;CAGF,MAAM,eAAe,oBAAoB,aAAa,YAAY,OAAO;CAGzE,kBAAkB,OAAO,OAAO,cAAc,GAAG,cAAc,OAAO;CACtE,MAAM,eAAe,aAAa,cAAc,SAAS,OAAO;CAGhE,OAAO,aAAa,QAAQ;AAC7B"}
@@ -4,13 +4,19 @@ import { repoEventIsPullRequestReviewEvent } from "./repoEventIsPullRequestRevie
4
4
  function processContributors(issueEvents, repoEvents, options) {
5
5
  const contributors = new ContributorsCollection(options.ignoredLogins);
6
6
  const maintainers = /* @__PURE__ */ new Set();
7
- for (const issueEvent of issueEvents) if (issueEvent.actor && issueEvent.issue) {
8
- contributors.add(issueEvent.actor.login, issueEvent.issue.number, "maintenance");
9
- maintainers.add(issueEvent.actor.login);
7
+ for (const issueEvent of issueEvents) {
8
+ const login = getMaintainerLogin(issueEvent);
9
+ if (login && issueEvent.issue) {
10
+ contributors.add(login, issueEvent.issue.number, "maintenance");
11
+ maintainers.add(login);
12
+ }
10
13
  }
11
14
  for (const repoEvent of repoEvents) if (repoEventIsPullRequestReviewEvent(repoEvent) && maintainers.has(repoEvent.actor.login)) contributors.add(repoEvent.actor.login, repoEvent.issue.number, "review");
12
15
  return contributors;
13
16
  }
17
+ function getMaintainerLogin(issueEvent) {
18
+ return issueEvent.event === "assigned" ? issueEvent.assigner?.login : issueEvent.actor?.login;
19
+ }
14
20
  //#endregion
15
21
  export { processContributors };
16
22
 
@@ -1 +1 @@
1
- {"version":3,"file":"processContributors.js","names":[],"sources":["../../../src/collect/processing/processContributors.ts"],"sourcesContent":["import { ContributorsCollection } from \"../../ContributorsCollection.js\";\nimport { AllContributorsForRepositoryOptions } from \"../../options.js\";\nimport { IssueEvent } from \"../collecting/collectIssueEvents.js\";\nimport { RepoEvent } from \"../collecting/collectRepoEvents.js\";\nimport { repoEventIsPullRequestReviewEvent } from \"./repoEventIsPullRequestReviewEvent.js\";\n\nexport function processContributors(\n\tissueEvents: IssueEvent[],\n\trepoEvents: Pick<RepoEvent, \"type\">[],\n\toptions: Partial<AllContributorsForRepositoryOptions>,\n) {\n\tconst contributors = new ContributorsCollection(options.ignoredLogins);\n\tconst maintainers = new Set<string>();\n\n\tfor (const issueEvent of issueEvents) {\n\t\tif (issueEvent.actor && issueEvent.issue) {\n\t\t\tcontributors.add(\n\t\t\t\tissueEvent.actor.login,\n\t\t\t\tissueEvent.issue.number,\n\t\t\t\t\"maintenance\",\n\t\t\t);\n\t\t\tmaintainers.add(issueEvent.actor.login);\n\t\t}\n\t}\n\n\tfor (const repoEvent of repoEvents) {\n\t\tif (\n\t\t\trepoEventIsPullRequestReviewEvent(repoEvent) &&\n\t\t\tmaintainers.has(repoEvent.actor.login)\n\t\t) {\n\t\t\tcontributors.add(repoEvent.actor.login, repoEvent.issue.number, \"review\");\n\t\t}\n\t}\n\n\treturn contributors;\n}\n"],"mappings":";;;AAMA,SAAgB,oBACf,aACA,YACA,SACC;CACD,MAAM,eAAe,IAAI,uBAAuB,QAAQ,aAAa;CACrE,MAAM,8BAAc,IAAI,IAAY;CAEpC,KAAK,MAAM,cAAc,aACxB,IAAI,WAAW,SAAS,WAAW,OAAO;EACzC,aAAa,IACZ,WAAW,MAAM,OACjB,WAAW,MAAM,QACjB,aACD;EACA,YAAY,IAAI,WAAW,MAAM,KAAK;CACvC;CAGD,KAAK,MAAM,aAAa,YACvB,IACC,kCAAkC,SAAS,KAC3C,YAAY,IAAI,UAAU,MAAM,KAAK,GAErC,aAAa,IAAI,UAAU,MAAM,OAAO,UAAU,MAAM,QAAQ,QAAQ;CAI1E,OAAO;AACR"}
1
+ {"version":3,"file":"processContributors.js","names":[],"sources":["../../../src/collect/processing/processContributors.ts"],"sourcesContent":["import { ContributorsCollection } from \"../../ContributorsCollection.js\";\nimport { AllContributorsForRepositoryOptions } from \"../../options.js\";\nimport { IssueEvent } from \"../collecting/collectIssueEvents.js\";\nimport { RepoEvent } from \"../collecting/collectRepoEvents.js\";\nimport { repoEventIsPullRequestReviewEvent } from \"./repoEventIsPullRequestReviewEvent.js\";\n\nexport function processContributors(\n\tissueEvents: IssueEvent[],\n\trepoEvents: Pick<RepoEvent, \"type\">[],\n\toptions: Partial<AllContributorsForRepositoryOptions>,\n) {\n\tconst contributors = new ContributorsCollection(options.ignoredLogins);\n\tconst maintainers = new Set<string>();\n\n\tfor (const issueEvent of issueEvents) {\n\t\tconst login = getMaintainerLogin(issueEvent);\n\t\tif (login && issueEvent.issue) {\n\t\t\tcontributors.add(login, issueEvent.issue.number, \"maintenance\");\n\t\t\tmaintainers.add(login);\n\t\t}\n\t}\n\n\tfor (const repoEvent of repoEvents) {\n\t\tif (\n\t\t\trepoEventIsPullRequestReviewEvent(repoEvent) &&\n\t\t\tmaintainers.has(repoEvent.actor.login)\n\t\t) {\n\t\t\tcontributors.add(repoEvent.actor.login, repoEvent.issue.number, \"review\");\n\t\t}\n\t}\n\n\treturn contributors;\n}\n\nfunction getMaintainerLogin(issueEvent: IssueEvent) {\n\treturn issueEvent.event === \"assigned\"\n\t\t? issueEvent.assigner?.login\n\t\t: issueEvent.actor?.login;\n}\n"],"mappings":";;;AAMA,SAAgB,oBACf,aACA,YACA,SACC;CACD,MAAM,eAAe,IAAI,uBAAuB,QAAQ,aAAa;CACrE,MAAM,8BAAc,IAAI,IAAY;CAEpC,KAAK,MAAM,cAAc,aAAa;EACrC,MAAM,QAAQ,mBAAmB,UAAU;EAC3C,IAAI,SAAS,WAAW,OAAO;GAC9B,aAAa,IAAI,OAAO,WAAW,MAAM,QAAQ,aAAa;GAC9D,YAAY,IAAI,KAAK;EACtB;CACD;CAEA,KAAK,MAAM,aAAa,YACvB,IACC,kCAAkC,SAAS,KAC3C,YAAY,IAAI,UAAU,MAAM,KAAK,GAErC,aAAa,IAAI,UAAU,MAAM,OAAO,UAAU,MAAM,QAAQ,QAAQ;CAI1E,OAAO;AACR;AAEA,SAAS,mBAAmB,YAAwB;CACnD,OAAO,WAAW,UAAU,aACzB,WAAW,UAAU,QACrB,WAAW,OAAO;AACtB"}
package/lib/options.d.ts CHANGED
@@ -9,6 +9,7 @@ export interface AllContributorsForRepositoryOptions {
9
9
  labelTypeTool: string;
10
10
  owner: string;
11
11
  repo: string;
12
+ testFiles: RegExp[];
12
13
  }
13
14
  export interface RawAllContributorsForRepositoryOptions {
14
15
  /**
@@ -47,6 +48,10 @@ export interface RawAllContributorsForRepositoryOptions {
47
48
  * The name of the repository to query, such as `"all-contributors-for-repository"`.
48
49
  */
49
50
  repo: string;
51
+ /**
52
+ * Regular expressions for file paths that count as tests, for merged PRs to be given a `test` contribution.
53
+ */
54
+ testFiles?: RegExp[];
50
55
  }
51
56
  export declare function fillInOptions(rawOptions: RawAllContributorsForRepositoryOptions): AllContributorsForRepositoryOptions;
52
57
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","names":[],"sources":["../src/options.ts"],"mappings":";iBAgBiB;EAChB;EACA,eAAe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGgB;;;;EAIhB;;;;EAKA,gBAAgB;;;;EAKhB;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;wBAGe,cACf,YAAY,yCACV"}
1
+ {"version":3,"file":"options.d.ts","names":[],"sources":["../src/options.ts"],"mappings":";iBAiBiB;EAChB;EACA,eAAe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;;iBAGK;;;;EAIhB;;;;EAKA,gBAAgB;;;;EAKhB;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA;;;;EAKA,YAAY;;wBAGG,cACf,YAAY,yCACV"}
package/lib/options.js CHANGED
@@ -12,7 +12,8 @@ const defaultOptions = {
12
12
  labelTypeBug: "type: bug",
13
13
  labelTypeDocs: "type: documentation",
14
14
  labelTypeIdeas: "type: feature",
15
- labelTypeTool: "area: tooling"
15
+ labelTypeTool: "area: tooling",
16
+ testFiles: [/\.(spec|test)\.[^/]+$/i, /(^|\/)(__tests__|tests?)\//i]
16
17
  };
17
18
  function fillInOptions(rawOptions) {
18
19
  return {
@@ -24,7 +25,8 @@ function fillInOptions(rawOptions) {
24
25
  labelTypeIdeas: rawOptions.labelTypeIdeas ?? defaultOptions.labelTypeIdeas,
25
26
  labelTypeTool: rawOptions.labelTypeTool ?? defaultOptions.labelTypeTool,
26
27
  owner: rawOptions.owner,
27
- repo: rawOptions.repo
28
+ repo: rawOptions.repo,
29
+ testFiles: rawOptions.testFiles ?? defaultOptions.testFiles
28
30
  };
29
31
  }
30
32
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","names":[],"sources":["../src/options.ts"],"sourcesContent":["const defaultOptions = {\n\tignoredLogins: [\n\t\t/\\[bot\\]$/i,\n\t\t/^allcontributors$/i,\n\t\t/^copilot$/i,\n\t\t/^dependabot$/i,\n\t\t/^github-actions$/i,\n\t\t/^renovate$/i,\n\t],\n\tlabelAcceptingPrs: \"status: accepting prs\",\n\tlabelTypeBug: \"type: bug\",\n\tlabelTypeDocs: \"type: documentation\",\n\tlabelTypeIdeas: \"type: feature\",\n\tlabelTypeTool: \"area: tooling\",\n};\n\nexport interface AllContributorsForRepositoryOptions {\n\tauth?: string;\n\tignoredLogins: RegExp[];\n\tlabelAcceptingPrs: string;\n\tlabelTypeBug: string;\n\tlabelTypeDocs: string;\n\tlabelTypeIdeas: string;\n\tlabelTypeTool: string;\n\towner: string;\n\trepo: string;\n}\n\nexport interface RawAllContributorsForRepositoryOptions {\n\t/**\n\t * GitHub auth token to query the API with, if necessary for private repositories and/or to avoid rate limiting.\n\t */\n\tauth?: string;\n\n\t/**\n\t * Regular expressions for usernames to ignore commits from, such as bot users.\n\t */\n\tignoredLogins?: RegExp[];\n\n\t/**\n\t * Label to indicate an issue is accepting pull requests.\n\t */\n\tlabelAcceptingPrs?: string;\n\n\t/**\n\t * Label to indicate an issue is for a bug.\n\t */\n\tlabelTypeBug?: string;\n\n\t/**\n\t * Label to indicate an issue is for documentation.\n\t */\n\tlabelTypeDocs?: string;\n\n\t/**\n\t * Label to indicate an issue is for a feature.\n\t */\n\tlabelTypeIdeas?: string;\n\n\t/**\n\t * Label to indicate an issue is for tooling.\n\t */\n\tlabelTypeTool?: string;\n\n\t/**\n\t * The owner of the repository to query, such as `\"JoshuaKGoldberg\"`.\n\t */\n\towner: string;\n\n\t/**\n\t * The name of the repository to query, such as `\"all-contributors-for-repository\"`.\n\t */\n\trepo: string;\n}\n\nexport function fillInOptions(\n\trawOptions: RawAllContributorsForRepositoryOptions,\n): AllContributorsForRepositoryOptions {\n\treturn {\n\t\tauth: rawOptions.auth,\n\t\tignoredLogins: rawOptions.ignoredLogins ?? defaultOptions.ignoredLogins,\n\t\tlabelAcceptingPrs:\n\t\t\trawOptions.labelAcceptingPrs ?? defaultOptions.labelAcceptingPrs,\n\t\tlabelTypeBug: rawOptions.labelTypeBug ?? defaultOptions.labelTypeBug,\n\t\tlabelTypeDocs: rawOptions.labelTypeDocs ?? defaultOptions.labelTypeDocs,\n\t\tlabelTypeIdeas: rawOptions.labelTypeIdeas ?? defaultOptions.labelTypeIdeas,\n\t\tlabelTypeTool: rawOptions.labelTypeTool ?? defaultOptions.labelTypeTool,\n\t\towner: rawOptions.owner,\n\t\trepo: rawOptions.repo,\n\t};\n}\n"],"mappings":";AAAA,MAAM,iBAAiB;CACtB,eAAe;EACd;EACA;EACA;EACA;EACA;EACA;CACD;CACA,mBAAmB;CACnB,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,eAAe;AAChB;AA6DA,SAAgB,cACf,YACsC;CACtC,OAAO;EACN,MAAM,WAAW;EACjB,eAAe,WAAW,iBAAiB,eAAe;EAC1D,mBACC,WAAW,qBAAqB,eAAe;EAChD,cAAc,WAAW,gBAAgB,eAAe;EACxD,eAAe,WAAW,iBAAiB,eAAe;EAC1D,gBAAgB,WAAW,kBAAkB,eAAe;EAC5D,eAAe,WAAW,iBAAiB,eAAe;EAC1D,OAAO,WAAW;EAClB,MAAM,WAAW;CAClB;AACD"}
1
+ {"version":3,"file":"options.js","names":[],"sources":["../src/options.ts"],"sourcesContent":["const defaultOptions = {\n\tignoredLogins: [\n\t\t/\\[bot\\]$/i,\n\t\t/^allcontributors$/i,\n\t\t/^copilot$/i,\n\t\t/^dependabot$/i,\n\t\t/^github-actions$/i,\n\t\t/^renovate$/i,\n\t],\n\tlabelAcceptingPrs: \"status: accepting prs\",\n\tlabelTypeBug: \"type: bug\",\n\tlabelTypeDocs: \"type: documentation\",\n\tlabelTypeIdeas: \"type: feature\",\n\tlabelTypeTool: \"area: tooling\",\n\ttestFiles: [/\\.(spec|test)\\.[^/]+$/i, /(^|\\/)(__tests__|tests?)\\//i],\n};\n\nexport interface AllContributorsForRepositoryOptions {\n\tauth?: string;\n\tignoredLogins: RegExp[];\n\tlabelAcceptingPrs: string;\n\tlabelTypeBug: string;\n\tlabelTypeDocs: string;\n\tlabelTypeIdeas: string;\n\tlabelTypeTool: string;\n\towner: string;\n\trepo: string;\n\ttestFiles: RegExp[];\n}\n\nexport interface RawAllContributorsForRepositoryOptions {\n\t/**\n\t * GitHub auth token to query the API with, if necessary for private repositories and/or to avoid rate limiting.\n\t */\n\tauth?: string;\n\n\t/**\n\t * Regular expressions for usernames to ignore commits from, such as bot users.\n\t */\n\tignoredLogins?: RegExp[];\n\n\t/**\n\t * Label to indicate an issue is accepting pull requests.\n\t */\n\tlabelAcceptingPrs?: string;\n\n\t/**\n\t * Label to indicate an issue is for a bug.\n\t */\n\tlabelTypeBug?: string;\n\n\t/**\n\t * Label to indicate an issue is for documentation.\n\t */\n\tlabelTypeDocs?: string;\n\n\t/**\n\t * Label to indicate an issue is for a feature.\n\t */\n\tlabelTypeIdeas?: string;\n\n\t/**\n\t * Label to indicate an issue is for tooling.\n\t */\n\tlabelTypeTool?: string;\n\n\t/**\n\t * The owner of the repository to query, such as `\"JoshuaKGoldberg\"`.\n\t */\n\towner: string;\n\n\t/**\n\t * The name of the repository to query, such as `\"all-contributors-for-repository\"`.\n\t */\n\trepo: string;\n\n\t/**\n\t * Regular expressions for file paths that count as tests, for merged PRs to be given a `test` contribution.\n\t */\n\ttestFiles?: RegExp[];\n}\n\nexport function fillInOptions(\n\trawOptions: RawAllContributorsForRepositoryOptions,\n): AllContributorsForRepositoryOptions {\n\treturn {\n\t\tauth: rawOptions.auth,\n\t\tignoredLogins: rawOptions.ignoredLogins ?? defaultOptions.ignoredLogins,\n\t\tlabelAcceptingPrs:\n\t\t\trawOptions.labelAcceptingPrs ?? defaultOptions.labelAcceptingPrs,\n\t\tlabelTypeBug: rawOptions.labelTypeBug ?? defaultOptions.labelTypeBug,\n\t\tlabelTypeDocs: rawOptions.labelTypeDocs ?? defaultOptions.labelTypeDocs,\n\t\tlabelTypeIdeas: rawOptions.labelTypeIdeas ?? defaultOptions.labelTypeIdeas,\n\t\tlabelTypeTool: rawOptions.labelTypeTool ?? defaultOptions.labelTypeTool,\n\t\towner: rawOptions.owner,\n\t\trepo: rawOptions.repo,\n\t\ttestFiles: rawOptions.testFiles ?? defaultOptions.testFiles,\n\t};\n}\n"],"mappings":";AAAA,MAAM,iBAAiB;CACtB,eAAe;EACd;EACA;EACA;EACA;EACA;EACA;CACD;CACA,mBAAmB;CACnB,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,WAAW,CAAC,0BAA0B,6BAA6B;AACpE;AAmEA,SAAgB,cACf,YACsC;CACtC,OAAO;EACN,MAAM,WAAW;EACjB,eAAe,WAAW,iBAAiB,eAAe;EAC1D,mBACC,WAAW,qBAAqB,eAAe;EAChD,cAAc,WAAW,gBAAgB,eAAe;EACxD,eAAe,WAAW,iBAAiB,eAAe;EAC1D,gBAAgB,WAAW,kBAAkB,eAAe;EAC5D,eAAe,WAAW,iBAAiB,eAAe;EAC1D,OAAO,WAAW;EAClB,MAAM,WAAW;EACjB,WAAW,WAAW,aAAa,eAAe;CACnD;AACD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "all-contributors-for-repository",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "description": "Generates an allcontributors list for an existing repository. 🤝",
5
5
  "repository": {
6
6
  "type": "git",