aboutsummaryrefslogtreecommitdiff
path: root/lib/serve.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/serve.js')
-rw-r--r--lib/serve.js182
1 files changed, 146 insertions, 36 deletions
diff --git a/lib/serve.js b/lib/serve.js
index 4e8c15d..f1ec351 100644
--- a/lib/serve.js
+++ b/lib/serve.js
@@ -1296,16 +1296,49 @@ Serve.prototype.gitRaw = function (rev) {
self.respondSink(400, {'Content-Type': 'text/plain'})
)
}
-
- var headMsgId = self.query.head
- pull(
- self.app.git.readObject({
- id: rev,
- headMsgId: headMsgId,
- }),
- catchTextError(),
- self.respondSink(200, {'Content-type': 'text/plain'})
+ if (!u.isRef(self.query.msg)) return pull(
+ ph('div.error', 'missing message id'),
+ self.wrapPage('git tree ' + rev),
+ self.respondSink(400)
)
+
+ self.app.git.openObject({
+ obj: rev,
+ msg: self.query.msg,
+ }, 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'})
+ )
+ pull(
+ self.app.git.readObject(obj),
+ catchTextError(),
+ ident(function (type) {
+ type = type && mime.lookup(type)
+ if (type) self.res.setHeader('Content-Type', type)
+ self.res.setHeader('Cache-Control', 'public, max-age=315360000')
+ self.res.setHeader('etag', rev)
+ self.res.writeHead(200)
+ }),
+ self.respondSink()
+ )
+ })
+}
+
+Serve.prototype.gitAuthorLink = function (author) {
+ if (author.feed) {
+ var myName = this.app.getNameSync(author.feed)
+ var sigil = author.name === author.localpart ? '@' : ''
+ return ph('a', {
+ href: this.app.render.toUrl(author.feed),
+ title: author.localpart + (myName ? ' (' + myName + ')' : '')
+ }, u.escapeHTML(sigil + author.name))
+ } else {
+ return ph('a', {href: this.app.render.toUrl('mailto:' + author.email)},
+ u.escapeHTML(author.name))
+ }
}
Serve.prototype.gitCommit = function (rev) {
@@ -1317,23 +1350,95 @@ Serve.prototype.gitCommit = function (rev) {
self.respondSink(400)
)
}
+ if (!u.isRef(self.query.msg)) return pull(
+ ph('div.error', 'missing message id'),
+ self.wrapPage('git commit ' + rev),
+ self.respondSink(400)
+ )
- self.app.git.getCommit({
- id: rev,
- headMsgId: self.query.head,
- }, function (err, commit) {
+ self.app.git.openObject({
+ obj: rev,
+ msg: self.query.msg,
+ }, function (err, obj) {
if (err && err.name === 'BlobNotFoundError')
return self.askWantBlobs(err.links)
if (err) return pull(
pull.once(u.renderError(err).outerHTML),
- self.wrapPage('git object ' + rev),
+ self.wrapPage('git commit ' + rev),
self.respondSink(400)
)
- pull(
- pull.once(h('pre', self.app.render.linkify(commit.body)).outerHTML),
- self.wrapPage('git object ' + rev),
- self.respondSink(200)
- )
+ var msgDate = new Date(obj.msg.value.timestamp)
+ self.app.git.getCommit(obj, function (err, commit) {
+ var missingBlobs
+ if (err && err.name === 'BlobNotFoundError')
+ missingBlobs = err.links, err = null
+ if (err) return pull(
+ pull.once(u.renderError(err).outerHTML),
+ self.wrapPage('git commit ' + rev),
+ self.respondSink(400)
+ )
+ pull(
+ ph('section', [
+ ph('h3', ph('a', {href: ''}, rev)),
+ ph('div', [
+ self.phIdLink(obj.msg.value.author), ' pushed ',
+ ph('a', {
+ href: self.app.render.toUrl(obj.msg.key),
+ title: msgDate.toLocaleString(),
+ }, htime(msgDate))
+ ]),
+ missingBlobs ? self.askWantBlobsForm(missingBlobs) : [
+ ph('div', [
+ self.gitAuthorLink(commit.committer),
+ ' committed ',
+ ph('span', {title: commit.committer.date.toLocaleString()},
+ htime(commit.committer.date)),
+ ' in ', commit.committer.tz
+ ]),
+ commit.author ? ph('div', [
+ self.gitAuthorLink(commit.author),
+ ' authored ',
+ ph('span', {title: commit.author.date.toLocaleString()},
+ htime(commit.author.date)),
+ ' in ', commit.author.tz
+ ]) : '',
+ commit.parents.length ? ph('div', ['parents: ', pull(
+ pull.values(commit.parents),
+ paramap(function (id, cb) {
+ self.app.git.getObjectMsg({
+ obj: id,
+ headMsgId: obj.msg.key,
+ }, function (err, msg) {
+ var path = '/git/commit/' + id
+ + '?msg=' + encodeURIComponent(msg.key)
+ cb(null, [ph('code', ph('a', {
+ href: self.app.render.toUrl(path)
+ }, id.substr(0, 8))), ' '])
+ })
+ }, 4)
+ )]) : '',
+ commit.tree ? ph('div', ['tree: ', pull(
+ pull.once(commit.tree),
+ pull.asyncMap(function (id, cb) {
+ self.app.git.getObjectMsg({
+ obj: id,
+ headMsgId: obj.msg.key,
+ }, function (err, msg) {
+ var path = '/git/tree/' + id
+ + '?msg=' + encodeURIComponent(msg.key)
+ cb(null, [ph('code', ph('a', {
+ href: self.app.render.toUrl(path)
+ }, id.substr(0, 8))), ' '])
+ })
+ })
+ )]) : '',
+ h('pre', self.app.render.linkify(commit.body)).outerHTML,
+ ]
+ ]),
+ self.wrapPage('git commit ' + rev),
+ self.respondSink(missingBlobs ? 409 : 200)
+ )
+ })
})
}
@@ -1352,26 +1457,31 @@ Serve.prototype.wrapPublic = function (opts) {
})
}
+Serve.prototype.askWantBlobsForm = function (links) {
+ var self = this
+ return ph('form', {action: '', method: 'post'}, [
+ ph('section', [
+ ph('h3', 'Missing blobs'),
+ ph('p', 'The application needs these blobs to continue:'),
+ ph('table', links.map(u.toLink).map(function (link) {
+ if (!u.isRef(link.link)) return
+ return ph('tr', [
+ ph('td', ph('code', link.link)),
+ ph('td', self.app.render.formatSize(link.size)),
+ ])
+ })),
+ ph('input', {type: 'hidden', name: 'action', value: 'want-blobs'}),
+ ph('input', {type: 'hidden', name: 'blob_ids',
+ value: links.map(u.linkDest).join(',')}),
+ ph('p', ph('input', {type: 'submit', value: 'Want Blobs'}))
+ ])
+ ])
+}
+
Serve.prototype.askWantBlobs = function (links) {
var self = this
pull(
- ph('form', {action: '', method: 'post'}, [
- ph('section', [
- ph('h3', 'Missing blobs'),
- ph('p', 'The application needs these blobs to continue:'),
- ph('table', links.map(u.toLink).map(function (link) {
- if (!u.isRef(link.link)) return
- return ph('tr', [
- ph('td', ph('code', link.link)),
- ph('td', self.app.render.formatSize(link.size)),
- ])
- })),
- ph('input', {type: 'hidden', name: 'action', value: 'want-blobs'}),
- ph('input', {type: 'hidden', name: 'blob_ids',
- value: links.map(u.linkDest).join(',')}),
- ph('p', ph('input', {type: 'submit', value: 'Want Blobs'}))
- ])
- ]),
+ self.askWantBlobsForm(links),
self.wrapPage('missing blobs'),
self.respondSink(409)
)