git ssb

0+

cel / ssb-pull-requests



Tree: 7e241844ed915ae5fab01bad3e8bbed493a3e6ca

Files: 7e241844ed915ae5fab01bad3e8bbed493a3e6ca / index.js

3623 bytesRaw
1var pull = require('pull-stream')
2var paramap = require('pull-paramap')
3var asyncMemo = require('asyncmemo')
4var Issues = require('ssb-issues')
5
6function readNext(fn) {
7 var next
8 return function (end, cb) {
9 if (next) return next(end, cb)
10 fn(function (err, _next) {
11 if (err) return cb(err)
12 next = _next
13 next(null, cb)
14 })
15 }
16}
17
18module.exports = {
19 name: 'pull-requests',
20 version: '1.0.0',
21 manifest: {
22 get: 'async',
23 getRevs: 'async',
24 list: 'source'
25 },
26 schemas: require('./lib/schemas'),
27 init: function (sbot) {
28
29 var issues = Issues.init(sbot)
30 var getMsg = asyncMemo(sbot.get)
31
32 var getPullReq = asyncMemo(function (id, cb) {
33 issues.get(id, function (err, issue) {
34 if (err) return cb(err)
35 var c = issue.msg.value.content
36 issue.baseRepo = c.repo
37 issue.baseBranch = c.branch
38 issue.headRepo = c.head_repo
39 issue.headBranch = c.head_branch
40 cb(null, issue)
41 })
42 })
43
44 function getBranchLastUpdate(repoId, branch, lte, cb) {
45 // TODO: detect and skip updates from subsequent PR with same branch name
46 getMsg(repoId, function (err, msg) {
47 if (err) return cb(err)
48 var repoAuthor = msg.author
49 pull(
50 sbot.links({
51 dest: repoId,
52 rel: 'repo',
53 values: true,
54 reverse: true
55 }),
56 pull.filter(function (link) {
57 return link.value.content.type == 'git-update'
58 }),
59 pull.map(function (link) {
60 return {
61 timestamp: link.value.timestamp,
62 rev: (link.value.content.refs || {})['refs/heads/' + branch]
63 }
64 }),
65 pull.filter(function (update) {
66 return update.rev
67 && (lte ? update.timestamp <= lte : true)
68 }),
69 pull.take(1),
70 pull.collect(function (err, links) {
71 cb(err, links && links[0])
72 })
73 )
74 })
75 }
76
77 function getRevs(prId, cb) {
78 getPullReq(prId, function (err, pr) {
79 if (err) return cb(err)
80 // get the latest rev of the head branch before it was deleted or the
81 // PR closed
82 var lastTime = pr.open ? null : pr.updated_at
83 getBranchLastUpdate(pr.headRepo, pr.headBranch, lastTime,
84 function (err, headUpdate) {
85 if (err) return cb(err)
86 // get the rev of base when head was last updated
87 getBranchLastUpdate(pr.baseRepo, pr.baseBranch,
88 headUpdate && headUpdate.timestamp, function (err, baseUpdate) {
89 if (err) return cb(err)
90 cb(null, {
91 base: baseUpdate && baseUpdate.rev,
92 head: headUpdate && headUpdate.rev
93 })
94 })
95 })
96 })
97 }
98
99 function listPullReqs(opts) {
100 opts = opts || {}
101 opts.type = 'pull-request'
102 return pull(
103 sbot.messagesByType(opts),
104 pull.unique('key'),
105 pull.filter(function (msg) {
106 return (!opts.repo || opts.repo == msg.value.content.repo)
107 && (!opts.headRepo || opts.headRepo == msg.value.content.head_repo)
108 && (!opts.author || opts.author == msg.value.author)
109 }),
110 paramap(function (msg, cb) {
111 getPullReq(msg.key, cb)
112 }, 8),
113 pull.filter(opts.open != null && function (pr) {
114 return pr.open == opts.open
115 })
116 )
117 }
118
119 return {
120 deinit: issues.deinit,
121 get: getPullReq,
122 getRevs: getRevs,
123 list: listPullReqs
124 }
125 }
126}
127

Built with git-ssb-web