Bitrot.
The curse of being a prolific publisher is a long list of once-cherished, now-neglected modules.
Earlier this week, I got a depressing Github notification. The author of a pull request who has politely pestered me for a while to review his PR, added this comment:
Ouch!
Sadly, after taking time to review the PR, I actually decided it wasn’t a great fit and politely (I hope), rejected it. And then I felt even WORSE, because I’d made someone wait around a year for me to say “no”.
Much like my weight hitting a local maxima on the scale, goading me to rededicate myself to healthier eating [dear startups, enough with the constant junk food, already!], this PR felt like a low point in my open-source maintenance.
And, so, just like I now have an app to show me a dashboard of my food consumption, I decided I needed a birds eye view of what I’d been ignoring on Github.
Here, paraphrased, is my “conversation” with Github.
Me: Github, show me a dashboard! GH: Here's a feed of events on repos you watch Me: No, I want a dashboard. GH: Here's a list of issues created, assigned or mentioning you. Me: No, I want a dashboard. Maybe I need an organization view. [my CPAN repos are in an organization] GH: Here's a feed of events on repos in the organization. Me: No, I want a dashboard of issues. GH: Here's a list of issues for repos in the organization. Me: Uh, can you summarize that? GH: No. Me: Github, you suck. But you have an API. Time to bust out some Perl.
So I wrote my own github-dashboard program, using Net::GitHub. (Really, I adapted it from other Net::GitHub programs I already use.) I keep my Github user id and API token in my .gitconfig
, so the program pulls my credentials from there.
Below, you can see my Github dashboard of neglect (top 40 only!). The three columns of numbers are (respectively) PRs, non-wishlist issues and wishlist issues. (Wishlist items are identified either by label or by “wishlist” in the title.)
$ ./github-dashboard | head -40 Capture-Tiny 3 18 0 Meerkat 2 8 0 getopt-lucid 2 1 0 Path-Tiny 1 21 0 HTTP-Tiny-UA 1 5 0 Path-Iterator-Rule 1 5 0 Dist-Zilla-Plugin-BumpVersionAfterRelease 1 3 2 Metabase-Fact 1 3 0 dist-zilla-plugin-osprereqs 1 2 0 Dist-Zilla-Plugin-Test-ReportPrereqs 1 2 0 ToolSet 1 2 0 Dist-Zilla-Plugin-Meta-Contributors 1 1 0 Dist-Zilla-Plugin-MakeMaker-Highlander 1 0 0 Task-CPAN-Reporter 1 0 0 IO-CaptureOutput 0 7 0 pantry 0 7 2 TAP-Harness-Restricted 0 4 0 class-insideout 0 3 0 Hash-Ordered 0 3 0 Log-Any 0 3 4 perl-chef 0 3 0 Term-Title 0 3 0 Test-DiagINC 0 3 0 Acme-require-case 0 2 0 Class-Tiny 0 2 0 Data-Fake 0 2 2 dist-zilla-plugin-twitter 0 2 0 Log-Any-Adapter-Log4perl 0 2 0 math-random-oo 0 2 0 superclass 0 2 0 Test-Roo 0 2 0 universal-new 0 2 0 zzz-rt-to-github 0 2 0 app-ylastic-costagent 0 1 0 Dancer-Session-Cookie 0 1 0 Dist-Zilla-Plugin-CheckExtraTests 0 1 0 Dist-Zilla-Plugin-InsertCopyright 0 1 0 Dist-Zilla-Plugin-ReleaseStatus-FromVersion 0 1 0 File-chdir 0 1 0 File-pushd 0 1 0
Now, when I set aside maintenance time, I know where to work.