Skip to content
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

Add statistics API. #477

Merged
merged 12 commits into from
Oct 5, 2019
Merged

Conversation

martinvanzijl
Copy link
Contributor

Fixes #330 - Implements the statistics API as per https://developer.github.com/v3/repos/statistics/.
Adds the following to the GHRepository class:

  • getContributorStats()
  • getCommitActivity()
  • getCodeFrequency()
  • getParticipation()
  • getPunchCard()

Copy link
Member

@bitwiseman bitwiseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I haven't looked at the code yet, but can you add some tests? That would help with reviewing.

@martinvanzijl
Copy link
Contributor Author

@bitwiseman Thanks for your comment. I apologize for taking so long to respond. (I've updated my Github notification settings now.)

Do you mean unit tests?

@bitwiseman
Copy link
Member

@martinvanzijl
My turn to be slow to respond. :)
Yes, I unit tests. We now have the start of WireMock based framework where you can make sure the values from the server are being processed correctly.

Fixed issue with getCodeFrequency() where it would occasionally throw
an exception when the statistics were still being generated.

Added comment about throwing an exception as a possibility when
202 is returned.
@martinvanzijl
Copy link
Contributor Author

@bitwiseman I've added some unit tests (and pushed a fix). So far the tests just check that the methods run successfully. I'll aim to add more detailed tests to see that the statistics returned are correct.

Should I be using WireMock for these?

Added another accessor method.
@martinvanzijl
Copy link
Contributor Author

@bitwiseman I've added more detail to the unit tests. Could you please review?

GitHub caches statistics, and if they are out of date it will return "202" while it refreshes them. I return "null" in that case, but I could instead throw an exception, or simply call sleep() and try again in five seconds within the method itself. What do you think?

@bitwiseman
Copy link
Member

@martinvanzijl
Please use the WireMock testing utility, similar to the GistTest or PullRequestTest. This will let us run tests in CI.

I've also add you as a maintainer on
https://github.com/github-api-test-org/github-api . Please point your tests at that repository if possible, and if not let's discuss if there is anything else you need.

@bitwiseman
Copy link
Member

@martinvanzijl

GitHub caches statistics, and if they are out of date it will return "202" while it refreshes them. I return "null" in that case, but I could instead throw an exception, or simply call sleep() and try again in five seconds within the method itself. What do you think?

I'm not sure, I'm not familiar with this part of the code yet.

Copy link
Member

@bitwiseman bitwiseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I've had a chance to look at it, here's what I think needs to happen:

Move your added code from GHRepository to a new class called GHRepositoryStatistics. GHRepository will have a method called getStatistics(). This will keep these classes separate from the rest of GHRepository for clarity.

GHRepositoryStatistics will cache the results of any query locally - see the GHPullRequest class and how it handles merge state. The methods can still return null, but once one gets a non-null value it keeps them until you get a new instance of GHRepositoryStatistics.

This seems like a reasonable balance to me. I'm open to alternatives.

@martinvanzijl
Copy link
Contributor Author

@bitwiseman Thanks, makes sense. I'll try to make the changes as suggested.

- Moved statistics methods from GHRepository to new class GHRepositoryStatistics
- Updated StatisticsTest to suit.
- For ContributorStats, put the "wait-till-ready" loop in the accessor method.
  I'm planning to do something similar for the rest.
@martinvanzijl
Copy link
Contributor Author

I've uploaded my progress so far. I moved the code to a new class GHRepositoryStatistics as suggested, and used the Wiremock framework.

There is more I would like to do:

  • getContributorStats() has the "wait-till-ready" loop in the method itself, which can be turned off with a boolean parameter. Do the same for the other "get..." methods.
  • Return classes with accessor methods (e.g. ContributorStats.getAuthor("name")) instead of just the PagedIterables or Lists.
  • Cache the statistics and add a "refresh()" method to force a reload of data.

Copy link
Member

@bitwiseman bitwiseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martinvanzijl
I'm happy to wait for you to make any changes you'd like. On the other hand, I'm a fan of incremental improvement. This PR has been open for months. I rather see a basic version of these changes go live and then have you iterate on them. I had a couple more tweak requests, but otherwise, It seems to me like we could merge these changes and further improvements in another PR.

Great work!

*/
@SuppressWarnings("SleepWhileInLoop")
@SuppressFBWarnings(value = {"RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE"}, justification = "JSON API")
public PagedIterable<ContributorStats> getContributorStats(boolean waitTillReady) throws IOException, InterruptedException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a similar need for retry loop with PullRequests and checking for whether they are mergable (and getting mergeCommitSha). Onc we publish this, we are commited to supporting it going forward, but I'm not sure yet that this is model I'd like for follow.

Would you be willing to mark this as @Preview @Deprecated? That will give the project the freedom to make breaking changes (such as moving this behavior to a common helper the does pollFor(...)).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I've marked it as suggested.

Should I make the default value false, to bring it in line with the other getters?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meh. Let's leave it. It is definitely better behavior.

- Marked getContributorStats(bool) as deprecated, preview
- Moved "stats/" string to getApiTailUrl()
@bitwiseman bitwiseman merged commit 7c065c1 into hub4j:master Oct 5, 2019
@martinvanzijl martinvanzijl deleted the issue_330_statistics branch October 7, 2019 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Missing repository statistics
2 participants