From 16a3027dc258d934ce38f4ab143c41246a5c1862 Mon Sep 17 00:00:00 2001 From: cel Date: Tue, 9 May 2017 15:17:00 -1000 Subject: Add another way to lookup names --- lib/render.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'lib/render.js') diff --git a/lib/render.js b/lib/render.js index aa2a6da..ea94329 100644 --- a/lib/render.js +++ b/lib/render.js @@ -257,3 +257,36 @@ Render.prototype.renderFeeds = function (opts) { self.renderMsg(msg, opts, cb) }, 4) } + +Render.prototype.getName = function (id, cb) { + // TODO: consolidate the get name/link functions + var self = this + switch (id && id[0]) { + case '%': + return self.app.getMsgDecrypted(id, function (err, msg) { + if (err && err.name == 'NotFoundError') + return cb(null, String(id).substring(0, 8) + '…(missing)') + if (err) return fallback() + new RenderMsg(self, self.app, msg, {wrap: false}).title(cb) + }) + case '@': // fallthrough + case '&': + return self.app.getAbout(id, function (err, about) { + if (err || !about || !about.name) return fallback() + cb(null, about.name) + }) + default: + return cb(null, String(id)) + } + function fallback() { + cb(null, String(id).substr(0, 8) + '…') + } +} + +Render.prototype.getNameLink = function (id, cb) { + var self = this + self.getName(id, function (err, name) { + if (err) return cb(err) + cb(null, h('a', {href: self.toUrl(id)}, name)) + }) +} -- cgit v1.2.3 From 2aa94754c9a09e5ea707a30c6e937b7bfb3dd05a Mon Sep 17 00:00:00 2001 From: cel Date: Fri, 2 Jun 2017 18:34:51 -1000 Subject: Use existing function for rendering git commit bodies --- lib/render-msg.js | 10 +--------- lib/render.js | 8 ++++++++ lib/serve.js | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'lib/render.js') diff --git a/lib/render-msg.js b/lib/render-msg.js index 48a5777..8346baf 100644 --- a/lib/render-msg.js +++ b/lib/render-msg.js @@ -536,7 +536,7 @@ RenderMsg.prototype.gitUpdate = function (cb) { return h('li', h('a', {href: self.render.toUrl(path)}, h('code', String(commit.sha1).substr(0, 8))), ' ', self.linkify(String(commit.title)), - self.gitCommitBody(commit.body) + self.render.gitCommitBody(commit.body) ) })) : '', Array.isArray(self.c.tags) ? @@ -559,14 +559,6 @@ RenderMsg.prototype.gitUpdate = function (cb) { }) } -RenderMsg.prototype.gitCommitBody = function (body) { - if (!body) return '' - var isMarkdown = !/^# Conflicts:$/m.test(body) - return isMarkdown - ? h('div', {innerHTML: this.render.markdown('\n' + body)}) - : h('pre', this.linkify('\n' + body)) -} - RenderMsg.prototype.gitPullRequest = function (cb) { var self = this var done = multicb({pluck: 1, spread: true}) diff --git a/lib/render.js b/lib/render.js index 21cdbda..d28f4b4 100644 --- a/lib/render.js +++ b/lib/render.js @@ -304,3 +304,11 @@ Render.prototype.renderFeeds = function (opts) { self.renderMsg(msg, opts, cb) }, 4) } + +Render.prototype.gitCommitBody = function (body) { + if (!body) return '' + var isMarkdown = !/^# Conflicts:$/m.test(body) + return isMarkdown + ? h('div', {innerHTML: this.markdown('\n' + body)}) + : h('pre', this.linkify('\n' + body)) +} diff --git a/lib/serve.js b/lib/serve.js index 9d5eb82..d2510e1 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -1438,7 +1438,8 @@ Serve.prototype.gitCommit = function (rev) { pull.once(commit.tree), self.gitObjectLinks(obj.msg.key, 'tree') )]) : '', - h('pre', self.app.render.linkify(commit.body)).outerHTML, + h('blockquote', + self.app.render.gitCommitBody(commit.body)).outerHTML, ] ]), self.wrapPage('git commit ' + rev), -- cgit v1.2.3 From 4d96b6e0f7b726a5d96742e51fcb6c05b1d3f85f Mon Sep 17 00:00:00 2001 From: cel Date: Sat, 3 Jun 2017 11:53:21 -1000 Subject: Show commit files changed --- lib/git.js | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/render.js | 1 + lib/serve.js | 26 +++++++++--- lib/util.js | 1 + package.json | 1 + 5 files changed, 154 insertions(+), 7 deletions(-) (limited to 'lib/render.js') diff --git a/lib/git.js b/lib/git.js index d4a071e..fa889ef 100644 --- a/lib/git.js +++ b/lib/git.js @@ -8,6 +8,8 @@ var Reader = require('pull-reader') var toPull = require('stream-to-pull-stream') var zlib = require('zlib') var looper = require('looper') +var multicb = require('multicb') +var kvdiff = require('pull-kvdiff') var ObjectNotFoundError = u.customError('ObjectNotFoundError') @@ -16,6 +18,7 @@ var types = { commit: true, tree: true, } +var emptyBlobHash = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391' module.exports = Git @@ -82,6 +85,7 @@ Git.prototype.openObject = function (opts, cb) { } Git.prototype.readObject = function (obj) { + if (obj.offset === obj.next) return pull.empty() return pull( this.app.readBlobSlice(obj.packLink, {start: obj.offset, end: obj.next}), this.decodeObject({ @@ -100,6 +104,19 @@ Git.prototype._findObject = function (opts, cb) { if (!opts.obj) return cb(new TypeError('missing object id')) var self = this var objId = opts.obj + if (objId === emptyBlobHash) { + // special case: the empty blob may be found anywhere + self.app.getMsgDecrypted(opts.headMsgId, function (err, msg) { + if (err) return cb(err) + return cb(null, { + offset: 0, + next: 0, + packLink: null, + idx: null, + msg: msg, + }) + }) + } self.findObjectMsgs(opts, function (err, msgs) { if (err) return cb(err) if (msgs.length === 0) @@ -515,6 +532,7 @@ function readCString(reader, cb) { } Git.prototype.readTree = function (obj) { + var self = this var reader = Reader() reader(this.readObject(obj)) return function (abort, cb) { @@ -529,9 +547,121 @@ Git.prototype.readTree = function (obj) { cb(null, { name: name, mode: mode, - hash: hash.toString('hex') + hash: hash.toString('hex'), + type: mode === 0040000 ? 'tree' : + mode === 0160000 ? 'commit' : 'blob', }) }) }) } } + +Git.prototype.readCommitChanges = function (commit) { + var self = this + return u.readNext(function (cb) { + var done = multicb({pluck: 1}) + commit.parents.forEach(function (rev) { + var cb = done() + self.getObjectMsg({ + obj: rev, + headMsgId: commit.msg.key, + type: 'commit', + }, function (err, msg) { + if (err) return cb(err) + self.openObject({ + obj: rev, + msg: msg.key, + }, function (err, obj) { + if (err) return cb(err) + self.getCommit(obj, cb) + }) + }) + }) + done()(null, commit) + done(function (err, commits) { + if (err) return cb(err) + var done = multicb({pluck: 1}) + commits.forEach(function (commit) { + var cb = done() + if (!commit.tree) return cb(null, pull.empty()) + self.getObjectMsg({ + obj: commit.tree, + headMsgId: commit.msg.key, + type: 'tree', + }, function (err, msg) { + if (err) return cb(err) + self.openObject({ + obj: commit.tree, + msg: commit.msg.key, + }, cb) + }) + }) + done(function (err, trees) { + if (err) return cb(err) + cb(null, self.diffTreesRecursive(trees)) + }) + }) + }) +} + +Git.prototype.diffTrees = function (objs) { + var self = this + return pull( + kvdiff(objs.map(function (obj) { + return self.readTree(obj) + }), 'name'), + pull.map(function (item) { + var diff = item.diff || {} + var head = item.values[item.values.length-1] + var created = true + for (var k = 0; k < item.values.length-1; k++) + if (item.values[k]) created = false + return { + name: item.key, + hash: diff.hash, + mode: diff.mode, + type: item.values.map(function (val) { return val.type }), + deleted: !head, + created: created + } + }) + ) +} + +Git.prototype.diffTreesRecursive = function (objs) { + var self = this + return pull( + self.diffTrees(objs), + paramap(function (item, cb) { + if (!item.type.some(function (t) { return t === 'tree' })) + return cb(null, [item]) + var done = multicb({pluck: 1}) + item.type.forEach(function (type, i) { + var cb = done() + if (type !== 'tree') return cb(null, pull.once(item)) + var hash = item.hash[i] + self.getObjectMsg({ + obj: hash, + headMsgId: objs[i].msg.key, + }, function (err, msg) { + if (err) return cb(err) + self.openObject({ + obj: hash, + msg: msg.key, + }, cb) + }) + }) + done(function (err, objs) { + if (err) return cb(err) + cb(null, pull( + self.diffTreesRecursive(objs), + pull.map(function (f) { + f.name = item.name + '/' + f.name + return f + }) + )) + }) + }, 4), + pull.flatten() + ) +} diff --git a/lib/render.js b/lib/render.js index d28f4b4..880470a 100644 --- a/lib/render.js +++ b/lib/render.js @@ -104,6 +104,7 @@ Render.prototype.emoji = function (emoji) { src: this.opts.emoji_base + emoji + '.png', alt: name, height: 17, + align: 'absmiddle', title: name, }) } diff --git a/lib/serve.js b/lib/serve.js index d2510e1..59a09d5 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -1440,6 +1440,21 @@ Serve.prototype.gitCommit = function (rev) { )]) : '', h('blockquote', self.app.render.gitCommitBody(commit.body)).outerHTML, + ph('h4', 'files'), + ph('table', pull( + self.app.git.readCommitChanges(commit), + pull.map(function (file) { + return ph('tr', [ + ph('td', ph('code', u.escapeHTML(file.name))), + // ph('td', ph('code', u.escapeHTML(JSON.stringify(file.msg)))), + ph('td', file.deleted ? 'deleted' + : file.created ? 'created' + : file.hash ? 'changed' + : file.mode ? 'mode changed' + : JSON.stringify(file)) + ]) + }) + )) ] ]), self.wrapPage('git commit ' + rev), @@ -1572,20 +1587,19 @@ Serve.prototype.gitTree = function (rev) { }) }, 8), pull.map(function (item) { - var type = item.mode === 0040000 ? 'tree' : - item.mode === 0160000 ? 'commit' : 'blob' if (!item.msg) return ph('tr', [ ph('td', - u.escapeHTML(item.name) + (type === 'tree' ? '/' : '')), + u.escapeHTML(item.name) + (item.type === 'tree' ? '/' : '')), + ph('td', u.escapeHTML(item.hash)), ph('td', 'missing') ]) - var path = '/git/' + type + '/' + item.hash + var path = '/git/' + item.type + '/' + item.hash + '?msg=' + encodeURIComponent(item.msg.key) var fileDate = new Date(item.msg.value.timestamp) return ph('tr', [ ph('td', ph('a', {href: self.app.render.toUrl(path)}, - u.escapeHTML(item.name) + (type === 'tree' ? '/' : ''))), + u.escapeHTML(item.name) + (item.type === 'tree' ? '/' : ''))), ph('td', self.phIdLink(item.msg.value.author)), ph('td', @@ -1748,7 +1762,7 @@ Serve.prototype.askWantBlobsForm = function (links) { if (!u.isRef(link.link)) return return ph('tr', [ ph('td', ph('code', link.link)), - ph('td', self.app.render.formatSize(link.size)), + !isNaN(link.size) ? ph('td', self.app.render.formatSize(link.size)) : '', ]) })), ph('input', {type: 'hidden', name: 'action', value: 'want-blobs'}), diff --git a/lib/util.js b/lib/util.js index a5f14f5..e4cf415 100644 --- a/lib/util.js +++ b/lib/util.js @@ -153,6 +153,7 @@ u.customError = function (name) { } u.escapeHTML = function (html) { + if (!html) return '' return html.toString('utf8') .replace(//g, '>') diff --git a/package.json b/package.json index 42311a4..816c115 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "pull-hash": "^1.0.0", "pull-hyperscript": "^0.2.2", "pull-identify-filetype": "^1.1.0", + "pull-kvdiff": "^0.0.1", "pull-paginate": "^1.0.0", "pull-paramap": "^1.2.1", "pull-reader": "^1.2.9", -- cgit v1.2.3