fbp-diffbot
Version:
Bot producing fbp-diff for Github PRs
206 lines (175 loc) • 5.66 kB
text/coffeescript
common = require './common'
axios = require 'axios'
bluebird = require 'bluebird'
debug = require('debug')('fbp-diffbot:github')
class HttpError extends Error
constructor: (msg, code) ->
= code or 500
= msg
super msg
HttpError.hasErrorCode = (code) ->
return (err) ->
return err.code == code
getFile = (config, repo, path) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/contents/#{path}"
axios.get url, request
fileCouldBeGraph = (name) ->
ext = name.split('.').pop()
if ext == 'fbp'
return true
else if ext == 'json'
return name not in ['package.json', 'component.json']
else
return false
# TODO: get the graphs as blobs, before and after change
prGraphsChanged = (config, repo, number) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/pulls/#{number}/files"
axios.get(url, request)
.then (req) ->
files = req.data
graphs = files.filter (f) -> return fileCouldBeGraph f.filename
return graphs
prGet = (config, repo, number) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/pulls/#{number}"
axios.get(url, request).then (request) ->
return request.data
getAuthenticated = (config, url) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
axios.get(url, request)
fileAtRevision = (config, repo, revision, filepath) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
debug 'fetching file', repo, revision, filepath
axios.get "#{config.endpoint}/repos/#{repo}/git/commits/#{revision}", request
.then (req) ->
commit = req.data
return commit.tree.url
.then (treeUrl) ->
r =
headers: request.headers
params:
recursive: 1
axios.get treeUrl, r
.then (req) ->
tree = req.data.tree
foundUrl = null
for file in tree
if file.path == filepath
foundUrl = file.url
throw new HttpError "File #{filepath} does not exist in #{revision} of #{repo}", 404 if not foundUrl
return foundUrl
.then (u) ->
axios.get u, request
.then (res) ->
contents = new Buffer(res.data.content, 'base64').toString()
return contents
# NOTE: PRs are issues
issuePostComment = (config, repo, issue, body) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/issues/#{issue}/comments"
comment =
body: body
return axios.post url, comment, request
module.exports.issuePostComment = issuePostComment
issueListComments = (config, repo, issue) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/issues/#{issue}/comments"
return axios.get url, request
exports.issueListComments = issueListComments
prGetChanges = (config, repo, number) ->
prGet config, repo, number
.then (pr) ->
ret =
base:
sha: pr.base.sha
repo: pr.base.repo.full_name
head:
sha: pr.head.sha
repo: pr.head.repo.full_name
return ret
exports.prGetChanges = prGetChanges
graphsFromPR = (config, repo, number) ->
prGetChanges config, repo, number
.then (data) ->
prGraphsChanged config, repo, number
.then (graphs) ->
data.graphsChanged = graphs.map (g) ->
g.patch = 'hidden'
return g
return data
.then (data) ->
bluebird.map data.graphsChanged, (graph) ->
ret =
filename: graph.filename
bluebird.resolve(fileAtRevision config, data.head.repo, data.head.sha, graph.filename)
.catch HttpError.hasErrorCode(404), (err) ->
debug 'to graph not found', graph.filename, data.head.sha
ret.to = ""
.then (contents) ->
ret.to = contents
.then (_) ->
bluebird.resolve(fileAtRevision config, repo, data.base.sha, graph.filename)
.catch HttpError.hasErrorCode(404), (err) ->
debug 'from graph not found', graph.filename, data.base.sha
ret.from = ""
.then (contents) ->
ret.from = contents
return ret
.catch (req) ->
console.log 'ERROR', req
ret.error =
code: req.status
msg: req.statusText
return ret
.then (graphs) ->
data.graphs = graphs
return data
exports.graphsFromPR = graphsFromPR
repoAddHook = (config, repo, data) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/hooks"
return axios.post url, data, request
exports.repoAddHook = repoAddHook
repoListHooks = (config, repo, data) ->
request =
headers: {}
request.headers.Authorization = "token #{config.token}" if config.token
url = "#{config.endpoint}/repos/#{repo}/hooks"
return axios.get url, request
exports.repoListHooks = repoListHooks
main = () ->
config = common.getConfig()
d =
name: 'web'
active: true
config:
url: config.ownurl+'/hooks/github'
content_type: 'json'
'fbp-diffbot-hook-version': 1
events: ['pull_request']
repo = 'imgflo/imgflo-server'
repoAddHook config, repo, d
.then (r) ->
console.log 'added webhook', r.data
.catch (err) ->
console.error err
process.exit 2
main() if not module.parent