do not strictly require config; fix req

This commit is contained in:
Radek Stepan 2013-09-26 23:10:56 +01:00
parent 8873441737
commit 2769a83035
5 changed files with 26 additions and 87 deletions

View File

@ -1,76 +1,6 @@
#GitHub Burndown Chart #GitHub Burndown Chart
##Rework in Progress ##Rework in Progress
Displays a burndown chart from a set of GitHub issues in the current milestone.
[ ![Codeship Status for radekstepan/github-burndown-chart](https://www.codeship.io/projects/d69f4420-e5b0-0130-bbae-1632ddfb80f8/status?branch=rework)](https://www.codeship.io/projects/5855) [ ![Codeship Status for radekstepan/github-burndown-chart](https://www.codeship.io/projects/d69f4420-e5b0-0130-bbae-1632ddfb80f8/status?branch=rework)](https://www.codeship.io/projects/5855)
##Project Charter
The app is to display a burndown chart from a set of GitHub issues in a milestone.
If we can, do all processing and storage on the client which makes the app run for "free" on `gh-pages` etc.
Show:
* Upcoming issues by size.
* Issues closed today.
* For each issue show other tags and assignee (avatar).
* Number of working days left.
* To whom open issues still belong.
* Projected ship date (project running late/not).
* For each user/avatar what is their % progress and number of open/closed issues.
* Heat: if we are struck/very productive for a period of time, colorize the chart line.
* For milestones with no due date, show an estimate as to when it will probably be finished.
Allow:
* Toggle non working days.
* Have a print view.
* Customization of the theme (own logo/colors etc.).
Configure:
* Repos for users/orgs.
* Private api keys.
* Non working days.
* Label pattern to determine size (?).
* How often to poll for updates (limited by GH API).
Be:
* Responsive.
* As lightweight as possible (do we need Backbone/jQuery?).
* Well documented and modularized.
* Handling upstream API downtimes.
* Testing the algo by way of using the proxy service to fake responses.
* Handling daylight savings et al.
Usage envisaged in these three scenarios:
1. Use the `gh-pages` branch of this repo to connect and visualize a public repo.
* App requesting a static JSON config file, merging with LocalStorage.
1. Deploy the app on a static server elsewhere with custom `config`.
* App requesting a static JSON config file, merging with LocalStorage.
1. Proxy requests through a service to not disclose private api keys publicly.
* Proxy app wrapping a request with API credentials. When requesting the config file we get the file dynamically stating which URL to use to make requests. API keys are scrubbed from the JSON file. When someone makes a request to us, wrap their request (only GET requests to specific endpoints!) and pipe the response back.
* All this works as a Connect Middleware.
* Also, make this cache responses for a given amount of time (poll time). This way people concerned with a big amount of requests can share the same resource.
##Design
###Initialization
1. Get [milestones](http://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository) and determine which one is ending the soonest.
1. For this milestone get both [open & closed](http://developer.github.com/v3/issues/#list-issues-for-a-repository) issues (can span [multiple pages](http://developer.github.com/v3/#pagination)).
1. Filter out issues not matching our pattern. For those that do keep tally and insert them to a map of days. Keep track of issue ids of open and closed issues.
1. Determine what the average velocity per day needs to be.
1. Go from the front (milestone creation date) to the back (milestone due date) day by day.
1. For each day that has an entry in the map, add them to the end array (for actual).
1. For expected just keep reducing the total by velocity every day.
1. Profit.
###Poll
Assuming it is quicker to get issue events and update existing data than it is to get all the issue over again.
1. Get [changes](http://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository) to tickets doing pagination if need be up to the last check time.
1. If events are closed/opened ones that ref an issue in our milestone & matching pattern then update/add to our collections.

BIN
example.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -30,14 +30,18 @@ module.exports = (cb) ->
wait = yes wait = yes
# Make the request. # Make the request.
request.config (err, result) -> request.config (err, result) ->
# Save config? # We do not strictly require config files.
unless err config = ( if err then { } else result )
config = result
# Tack on defaults? # Tack on defaults?
( config[k] ?= v for k, v of defaults ) ( config[k] ?= v for k, v of defaults )
# RegExpify the size label? # RegExpify the size label?
config.size_label = new RegExp(config.size_label) or regex.size_label if config.size_label
config.size_label = new RegExp config.size_label
else
config.size_label = regex.size_label
# Call back for each enqueued. # Call back for each enqueued.
_.each queue, (cb) -> _.each queue, (cb) ->
cb err, config # is either null or provided by now cb null, config

View File

@ -6,11 +6,11 @@ module.exports =
# Get current milestones for a repo.. # Get current milestones for a repo..
'get_current': (repo, cb) -> 'get_current': (repo, cb) ->
request.all_milestones repo, (err, data) -> request.all_milestones repo, (err, data) ->
# Request errors. # Request errors?
return cb err if err return cb err if err
# GitHub errors. # GitHub errors?
return cb data.message if data.message return cb data.message if data.message
# Empty warning. # Empty warning?
return cb null, 'No open milestones for repo' unless data.length return cb null, 'No open milestones for repo' unless data.length
# The first milestone should be ending soonest. # The first milestone should be ending soonest.
m = data[0] m = data[0]

View File

@ -19,8 +19,7 @@ module.exports =
sa sa
.get("http://#{window.location.host}/config.json") .get("http://#{window.location.host}/config.json")
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
.end (err, data) -> .end _.partialRight respond, cb
cb err, data?.body
# Make a request using SuperAgent to GitHub. # Make a request using SuperAgent to GitHub.
request = ({ protocol, host, token, path }, query, noun, cb) -> request = ({ protocol, host, token, path }, query, noun, cb) ->
@ -39,5 +38,11 @@ request = ({ protocol, host, token, path }, query, noun, cb) ->
req = req.set('Authorization', "token #{token}") if token req = req.set('Authorization', "token #{token}") if token
# Send. # Send.
req.end (err, data) -> req.end _.partialRight respond, cb
cb err, data?.body
# How do we respond to a response?
respond = (data, cb) ->
# 2xx?
return cb data.error.message if data.statusType isnt 2
# All good.
cb null, data?.body