aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2018-01-08 22:03:51 -1000
committercel <cel@f/6sQ6d2CMxRUhLpspgGIulDxDCwYD7DzFzPNr7u5AU=.ed25519>2018-01-08 22:03:51 -1000
commit09cf04663fe2a772d5a06bbcf86b9014dc4f5228 (patch)
treeae755d9bf9757a807938718acf5910b291f90198
parentcbf9a1d87eb43eaea73e6c019e7b4a2dca3bbaa6 (diff)
downloadpatchfoo-09cf04663fe2a772d5a06bbcf86b9014dc4f5228.tar.gz
patchfoo-09cf04663fe2a772d5a06bbcf86b9014dc4f5228.zip
Render line comments on diffs
-rw-r--r--lib/app.js75
-rw-r--r--lib/render-msg.js5
-rw-r--r--lib/serve.js133
3 files changed, 174 insertions, 39 deletions
diff --git a/lib/app.js b/lib/app.js
index 21f45a4..9166eb2 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -905,3 +905,78 @@ App.prototype.expandOoo = function (opts, cb) {
}
}
}
+
+App.prototype.getLineComments = function (opts, cb) {
+ // get line comments for a git-update message and git object id.
+ // line comments include message id, commit id and path
+ // but we have message id and git object hash.
+ // look up the git object hash for each line-comment
+ // to verify that it is for the git object file we want
+ var updateId = opts.obj.msg.key
+ var objId = opts.hash
+ var self = this
+ var lineComments = {}
+ pull(
+ self.sbot.backlinks ? self.sbot.backlinks.read({
+ query: [
+ {$filter: {
+ dest: updateId,
+ value: {
+ content: {
+ type: 'line-comment',
+ updateId: updateId,
+ }
+ }
+ }}
+ ]
+ }) : pull(
+ self.sbot.links({
+ dest: updateId,
+ rel: 'updateId',
+ values: true
+ }),
+ pull.filter(function (msg) {
+ var c = msg && msg.value && msg.value.content
+ return c && c.type === 'line-comment'
+ && c.updateId === updateId
+ })
+ ),
+ paramap(function (msg, cb) {
+ var c = msg.value.content
+ self.git.getObjectAtPath({
+ msg: updateId,
+ obj: c.commitId,
+ path: c.filePath,
+ }, function (err, info) {
+ if (err) return cb(err)
+ cb(null, {
+ obj: info.obj,
+ hash: info.hash,
+ msg: msg,
+ })
+ })
+ }, 4),
+ pull.filter(function (info) {
+ return info.hash === objId
+ }),
+ pull.drain(function (info) {
+ lineComments[info.msg.value.content.line] = info
+ }, function (err) {
+ cb(err, lineComments)
+ })
+ )
+}
+
+App.prototype.getThread = function (msg) {
+ return cat([
+ pull.once(msg),
+ this.sbot.backlinks ? this.sbot.backlinks.read({
+ query: [
+ {$filter: {dest: msg.key}}
+ ]
+ }) : this.sbot.links({
+ dest: msg.key,
+ values: true
+ })
+ ])
+}
diff --git a/lib/render-msg.js b/lib/render-msg.js
index 0835fee..78c7d5c 100644
--- a/lib/render-msg.js
+++ b/lib/render-msg.js
@@ -1668,7 +1668,10 @@ RenderMsg.prototype.lineComment = function (cb) {
h('a', {
href: self.toUrl('/git/commit/' + self.c.commitId + '?msg=' + encodeURIComponent(self.c.updateId))
}, String(self.c.commitId).substr(0, 8)), ' ',
- h('code', self.c.filePath + ':' + self.c.line)
+ h('a', {
+ href: self.toUrl('/git/line-comment/' +
+ encodeURIComponent(self.msg.key))
+ }, h('code', self.c.filePath + ':' + self.c.line))
)),
self.c.text ?
h('div', {innerHTML: self.render.markdown(self.c.text)}) : ''), cb)
diff --git a/lib/serve.js b/lib/serve.js
index f191b77..78ff104 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -1651,6 +1651,7 @@ Serve.prototype.git = function (url) {
case 'blob': return this.gitBlob(m[2])
case 'raw': return this.gitRaw(m[2])
case 'diff': return this.gitDiff(m[2])
+ case 'line-comment': return this.gitLineComment(m[2])
default: return this.respond(404, 'Not found')
}
}
@@ -2114,12 +2115,16 @@ Serve.prototype.gitDiff = function (revs) {
var done = multicb({pluck: 1, spread: true})
pull.collect(done())(self.app.git.readObject(obj1))
pull.collect(done())(self.app.git.readObject(obj2))
- done(function (err, bufs1, bufs2) {
+ self.app.getLineComments({obj: obj2, hash: rev2}, done())
+ done(function (err, bufs1, bufs2, lineComments) {
if (err) return cb(err)
var str1 = Buffer.concat(bufs1, obj1.length).toString('utf8')
var str2 = Buffer.concat(bufs2, obj2.length).toString('utf8')
var diff = Diff.structuredPatch('', '', str1, str2)
- cb(null, self.gitDiffTable(diff))
+ cb(null, self.gitDiffTable(diff, lineComments, {
+ obj: obj2,
+ hash: rev2,
+ }))
})
})
})
@@ -2130,12 +2135,10 @@ Serve.prototype.gitDiff = function (revs) {
})
}
-Serve.prototype.gitDiffTable = function (diff) {
+Serve.prototype.gitDiffTable = function (diff, lineComments, lineCommentInfo) {
var self = this
return pull(
ph('table', [
- ph('tr', [
- ]),
pull(
pull.values(diff.hunks),
pull.map(function (hunk) {
@@ -2157,39 +2160,42 @@ Serve.prototype.gitDiffTable = function (diff) {
var lineNums = [s == '+' ? '' : oldLine++, s == '-' ? '' : newLine++]
// var id = [filename].concat(lineNums).join('-')
var newLineNum = lineNums[lineNums.length-1]
- return ph('tr', {
- class: s == '+' ? 'diff-new' : s == '-' ? 'diff-old' : ''
- }, [
- lineNums.map(function (num, i) {
- return ph('td', String(num))
- // TODO: allow linking to comments
- /*
- var idEnc = encodeURIComponent(id)
- return '<td class="code-linenum">' +
- (num ? '<a href="#' + idEnc + '">' +
- num + '</a>' +
- (updateId && i === lineNums.length-1 && s !== '-' ?
- ' <a href="?comment=' + idEnc + '#' + idEnc + '">…</a>'
- : '')
- : '') + '</td>'
- }
- */
- }),
- ph('td', ph('pre', u.escapeHTML(html)))
- ])
-
- // TODO: line-comments
- /*
- (lineCommentThreads[newLineNum] ?
- '<tr><td colspan=4>' +
- lineCommentThreads[newLineNum] +
- '</td></tr>'
- : commit && query.comment === id ?
- '<tr><td colspan=4>' +
- forms.lineComment(req, repo, updateId, commit, filename, newLineNum) +
- '</td></tr>'
- : '')
- */
+ return [
+ ph('tr', {
+ class: s == '+' ? 'diff-new' : s == '-' ? 'diff-old' : ''
+ }, [
+ lineNums.map(function (num, i) {
+ return ph('td', String(num))
+ // TODO: allow linking to comments
+ /*
+ var idEnc = encodeURIComponent(id)
+ return '<td class="code-linenum">' +
+ (num ? '<a href="#' + idEnc + '">' +
+ num + '</a>' +
+ (updateId && i === lineNums.length-1 && s !== '-' ?
+ ' <a href="?comment=' + idEnc + '#' + idEnc + '">…</a>'
+ : '')
+ : '') + '</td>'
+ }
+ */
+ }),
+ ph('td', ph('pre', u.escapeHTML(html)))
+ ]),
+ (lineComments[newLineNum] ?
+ ph('tr',
+ ph('td', {colspan: 4},
+ self.renderLineCommentThread(lineComments[newLineNum])
+ )
+ )
+ : /*commit && query.comment === id ?
+ ph('tr',
+ ph('td', {colspan: 4},
+ // self.renderLineCommentForm(req, repo, updateId, commit, filename, newLineNum)
+ self.renderLineCommentForm(lineCommentInfo)
+ )
+ )
+ :*/ '')
+ ]
})
)
]
@@ -2199,6 +2205,57 @@ Serve.prototype.gitDiffTable = function (diff) {
)
}
+Serve.prototype.renderLineCommentThread = function (lineComment) {
+ var self = this
+ return ph('table', {class: 'ssb-msgs'}, pull(
+ this.app.getThread(lineComment.msg),
+ self.renderThread()
+ ))
+}
+
+Serve.prototype.renderLineCommentForm = function (info) {
+ var obj = info.obj
+ var hash = info.hash
+ return ph('pre', JSON.stringify(info, 0, 2))
+}
+
+Serve.prototype.gitLineComment = function (path) {
+ var self = this
+ var id = decodeURIComponent(String(path))
+ self.getMsgDecryptedMaybeOoo(id, function (err, msg) {
+ if (err) return pull(
+ pull.once(u.renderError(err).outerHTML),
+ self.respondSink(400, {'Content-Type': ctype('html')})
+ )
+ var c = msg && msg.value && msg.value.content
+ if (!c) return pull(
+ pull.once('Missing message ' + id),
+ self.respondSink(500, {'Content-Type': ctype('html')})
+ )
+ self.app.git.getObjectAtPath({
+ msg: c.updateId,
+ obj: c.commitId,
+ path: c.filePath,
+ }, function (err, obj) {
+ if (err && err.name === 'BlobNotFoundError')
+ return self.askWantBlobs(err.links)
+ if (err) return pull(
+ pull.once(err.stack),
+ self.respondSink(400, {'Content-Type': 'text/plain'})
+ )
+
+ self.redirect(self.app.render.toUrl(publishedMsg.key))
+
+ /*
+ pull(
+ ph('pre', JSON.stringify(obj, 0, 2)),
+ self.respondSink(200)
+ )
+ */
+ })
+ })
+}
+
Serve.prototype.gitObjectLinks = function (headMsgId, type) {
var self = this
return paramap(function (id, cb) {