Skip to content

Issue #764: Add custom year #2107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default async (req, res) => {
hide_rank,
show_icons,
include_all_commits,
commits_year,
line_height,
title_color,
ring_color,
Expand Down Expand Up @@ -75,6 +76,7 @@ export default async (req, res) => {
showStats.includes("prs_merged_percentage"),
showStats.includes("discussions_started"),
showStats.includes("discussions_answered"),
parseInt(commits_year, 10),
);

let cacheSeconds = clampValue(
Expand Down Expand Up @@ -102,6 +104,7 @@ export default async (req, res) => {
card_width: parseInt(card_width, 10),
hide_rank: parseBoolean(hide_rank),
include_all_commits: parseBoolean(include_all_commits),
commits_year: parseInt(commits_year, 10),
line_height,
title_color,
ring_color,
Expand Down
9 changes: 9 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,14 @@ You can pass a query parameter `&show=` to show any specific additional stats wi
![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&show=reviews,discussions_started,discussions_answered,prs_merged,prs_merged_percentage)
```

### Showing commits count for specified year

You can specify a year and fetch only the commits that were made in that year by passing `&commits_year=YYYY` to the parameter.

```md
![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&commits_year=2020)
```

### Showing icons

To enable icons, you can pass `&show_icons=true` in the query param, like so:
Expand Down Expand Up @@ -383,6 +391,7 @@ If we don't support your language, please consider contributing! You can find mo
| `ring_color` | Color of the rank circle. | string (hex color) | `2f80ed` |
| `number_format` | Switches between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). | enum | `short` |
| `show` | Shows [additional items](#showing-additional-individual-stats) on stats card (i.e. `reviews`, `discussions_started`, `discussions_answered`, `prs_merged` or `prs_merged_percentage`). | string (comma-separated values) | `null` |
| `commits_year` | Count commits of the entire year | integer _(YYYY)_ | `<current year> (one year to date)`.

> [!NOTE]\
> When hide\_rank=`true`, the minimum card width is 270 px + the title length and padding.
Expand Down
29 changes: 23 additions & 6 deletions src/cards/stats-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,20 @@ const getStyles = ({
`;
};

/**
* Return the label for commits according to the selected options
*
* @param {boolean} include_all_commits Option to include all years
* @param {number|undefined} commits_year Option to include only selected year
* @returns {string} The label corresponding to the options.
*/
const getTotalCommitsYearLabel = (include_all_commits, commits_year) =>
include_all_commits
? ""
: commits_year
? ` (${commits_year})`
: ` (last year)`;

/**
* @typedef {import('../fetchers/types').StatsData} StatsData
* @typedef {import('./types').StatCardOptions} StatCardOptions
Expand Down Expand Up @@ -222,6 +236,7 @@ const renderStatsCard = (stats, options = {}) => {
card_width,
hide_rank = false,
include_all_commits = false,
commits_year,
line_height = 25,
title_color,
ring_color,
Expand Down Expand Up @@ -273,9 +288,10 @@ const renderStatsCard = (stats, options = {}) => {
};
STATS.commits = {
icon: icons.commits,
label: `${i18n.t("statcard.commits")}${
include_all_commits ? "" : ` (${new Date().getFullYear()})`
}`,
label: `${i18n.t("statcard.commits")}${getTotalCommitsYearLabel(
include_all_commits,
commits_year,
)}`,
value: totalCommits,
id: "commits",
};
Expand Down Expand Up @@ -516,9 +532,10 @@ const renderStatsCard = (stats, options = {}) => {
.filter((key) => !hide.includes(key))
.map((key) => {
if (key === "commits") {
return `${i18n.t("statcard.commits")} ${
include_all_commits ? "" : `in ${new Date().getFullYear()}`
} : ${totalStars}`;
return `${i18n.t("statcard.commits")} ${getTotalCommitsYearLabel(
include_all_commits,
commits_year,
)} : ${totalStars}`;
}
return `${STATS[key].label}: ${STATS[key].value}`;
})
Expand Down
1 change: 1 addition & 0 deletions src/cards/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type StatCardOptions = CommonOptions & {
card_width: number;
hide_rank: boolean;
include_all_commits: boolean;
commits_year: number;
line_height: number | string;
custom_title: string;
disable_animations: boolean;
Expand Down
17 changes: 12 additions & 5 deletions src/fetchers/stats-fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ const GRAPHQL_REPOS_QUERY = `
`;

const GRAPHQL_STATS_QUERY = `
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!) {
query userInfo($login: String!, $after: String, $includeMergedPullRequests: Boolean!, $includeDiscussions: Boolean!, $includeDiscussionsAnswers: Boolean!, $startTime: DateTime) {
user(login: $login) {
name
login
contributionsCollection {
commits: contributionsCollection (from: $startTime) {
totalCommitContributions,
}
reviews: contributionsCollection {
totalPullRequestReviewContributions
}
repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
Expand Down Expand Up @@ -109,6 +111,7 @@ const fetcher = (variables, token) => {
* @param {boolean} variables.includeMergedPullRequests Include merged pull requests.
* @param {boolean} variables.includeDiscussions Include discussions.
* @param {boolean} variables.includeDiscussionsAnswers Include discussions answers.
* @param {string|undefined} variables.startTime Time to start the count of total commits.
* @returns {Promise<AxiosResponse>} Axios response.
*
* @description This function supports multi-page fetching if the 'FETCH_MULTI_PAGE_STARS' environment variable is set to true.
Expand All @@ -118,6 +121,7 @@ const statsFetcher = async ({
includeMergedPullRequests,
includeDiscussions,
includeDiscussionsAnswers,
startTime,
}) => {
let stats;
let hasNextPage = true;
Expand All @@ -130,6 +134,7 @@ const statsFetcher = async ({
includeMergedPullRequests,
includeDiscussions,
includeDiscussionsAnswers,
startTime,
};
let res = await retryer(fetcher, variables);
if (res.data.errors) {
Expand Down Expand Up @@ -217,6 +222,7 @@ const totalCommitsFetcher = async (username) => {
* @param {boolean} include_merged_pull_requests Include merged pull requests.
* @param {boolean} include_discussions Include discussions.
* @param {boolean} include_discussions_answers Include discussions answers.
* @param {number|undefined} commits_year Year to count total commits
* @returns {Promise<StatsData>} Stats data.
*/
const fetchStats = async (
Expand All @@ -226,6 +232,7 @@ const fetchStats = async (
include_merged_pull_requests = false,
include_discussions = false,
include_discussions_answers = false,
commits_year,
) => {
if (!username) {
throw new MissingParamError(["username"]);
Expand All @@ -251,6 +258,7 @@ const fetchStats = async (
includeMergedPullRequests: include_merged_pull_requests,
includeDiscussions: include_discussions,
includeDiscussionsAnswers: include_discussions_answers,
startTime: commits_year ? `${commits_year}-01-01T00:00:00Z` : undefined,
});

// Catch GraphQL errors.
Expand Down Expand Up @@ -282,7 +290,7 @@ const fetchStats = async (
if (include_all_commits) {
stats.totalCommits = await totalCommitsFetcher(username);
} else {
stats.totalCommits = user.contributionsCollection.totalCommitContributions;
stats.totalCommits = user.commits.totalCommitContributions;
}

stats.totalPRs = user.pullRequests.totalCount;
Expand All @@ -291,8 +299,7 @@ const fetchStats = async (
stats.mergedPRsPercentage =
(user.mergedPullRequests.totalCount / user.pullRequests.totalCount) * 100;
}
stats.totalReviews =
user.contributionsCollection.totalPullRequestReviewContributions;
stats.totalReviews = user.reviews.totalPullRequestReviewContributions;
stats.totalIssues = user.openIssues.totalCount + user.closedIssues.totalCount;
if (include_discussions) {
stats.totalDiscussionsStarted = user.repositoryDiscussions.totalCount;
Expand Down
4 changes: 3 additions & 1 deletion tests/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ const data_stats = {
user: {
name: stats.name,
repositoriesContributedTo: { totalCount: stats.contributedTo },
contributionsCollection: {
commits: {
totalCommitContributions: stats.totalCommits,
},
reviews: {
totalPullRequestReviewContributions: stats.totalReviews,
},
pullRequests: { totalCount: stats.totalPRs },
Expand Down
4 changes: 3 additions & 1 deletion tests/bench/api.bench.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ const data_stats = {
user: {
name: stats.name,
repositoriesContributedTo: { totalCount: stats.contributedTo },
contributionsCollection: {
commits: {
totalCommitContributions: stats.totalCommits,
},
reviews: {
totalPullRequestReviewContributions: stats.totalReviews,
},
pullRequests: { totalCount: stats.totalPRs },
Expand Down
56 changes: 54 additions & 2 deletions tests/fetchStats.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ const data_stats = {
user: {
name: "Anurag Hazra",
repositoriesContributedTo: { totalCount: 61 },
contributionsCollection: {
commits: {
totalCommitContributions: 100,
},
reviews: {
totalPullRequestReviewContributions: 50,
},
pullRequests: { totalCount: 300 },
Expand All @@ -38,6 +40,9 @@ const data_stats = {
},
};

const data_year2003 = JSON.parse(JSON.stringify(data_stats));
data_year2003.data.user.commits.totalCommitContributions = 428;

const data_repo = {
data: {
user: {
Expand Down Expand Up @@ -91,9 +96,18 @@ const mock = new MockAdapter(axios);
beforeEach(() => {
process.env.FETCH_MULTI_PAGE_STARS = "false"; // Set to `false` to fetch only one page of stars.
mock.onPost("https://api.github.com/graphql").reply((cfg) => {
let req = JSON.parse(cfg.data);

if (
req.variables &&
req.variables.startTime &&
req.variables.startTime.startsWith("2003")
) {
return [200, data_year2003];
}
return [
200,
cfg.data.includes("contributionsCollection") ? data_stats : data_repo,
req.query.includes("totalCommitContributions") ? data_stats : data_repo,
];
});
});
Expand Down Expand Up @@ -409,4 +423,42 @@ describe("Test fetchStats", () => {
rank,
});
});

it("should get commits of provided year", async () => {
let stats = await fetchStats(
"anuraghazra",
false,
[],
false,
false,
false,
2003,
);

const rank = calculateRank({
all_commits: false,
commits: 428,
prs: 300,
reviews: 50,
issues: 200,
repos: 5,
stars: 300,
followers: 100,
});

expect(stats).toStrictEqual({
contributedTo: 61,
name: "Anurag Hazra",
totalCommits: 428,
totalIssues: 200,
totalPRs: 300,
totalPRsMerged: 0,
mergedPRsPercentage: 0,
totalReviews: 50,
totalStars: 300,
totalDiscussionsStarted: 0,
totalDiscussionsAnswered: 0,
rank,
});
});
});
4 changes: 1 addition & 3 deletions tests/renderStatsCard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,7 @@ describe("Test renderStatsCard", () => {
document.querySelector(
'g[transform="translate(0, 25)"]>.stagger>.stat.bold',
).textContent,
).toMatchInlineSnapshot(
`"累计提交数(commit) (${new Date().getFullYear()}):"`,
);
).toMatchInlineSnapshot(`"累计提交数(commit) (last year):"`);
expect(
document.querySelector(
'g[transform="translate(0, 50)"]>.stagger>.stat.bold',
Expand Down