ssb-git-repo
Advanced tools
Comparing version 1.2.0 to 1.3.0
13
index.js
@@ -30,3 +30,12 @@ var ref = require('ssb-ref') | ||
if (!options) options = {} | ||
sbot.get(id, function (err, msg) { | ||
if (typeof id == 'object') { | ||
var msg = id.value | ||
id = id.key | ||
gotMsg(null, msg) | ||
} else { | ||
sbot.get(id, gotMsg) | ||
} | ||
function gotMsg(err, msg) { | ||
if (err) return cb(err) | ||
@@ -36,3 +45,3 @@ var repo = new Repo(sbot, id, msg) | ||
cb(null, repo) | ||
}) | ||
} | ||
} | ||
@@ -39,0 +48,0 @@ |
168
lib/repo.js
@@ -5,40 +5,19 @@ var pull = require('pull-stream') | ||
var cat = require('pull-cat') | ||
var cache = require('pull-cache') | ||
var reverse = require('pull-reverse') | ||
var pushable = require('pull-pushable') | ||
var ref = require('ssb-ref') | ||
var createGitHash = require('pull-hash/ext/git') | ||
var createSSBBlobHash = require('pull-hash/ext/ssb') | ||
module.exports = Repo | ||
function createHash(type, onEnd) { | ||
var hash = (typeof type == 'string') ? crypto.createHash(type) : type | ||
var digest | ||
var ended | ||
function hasher(read) { | ||
return function (abort, cb) { | ||
read(abort, function (end, data) { | ||
if (end === true && !digest) digest = hash.digest() | ||
else if (!end) hash.update(data) | ||
cb(end, data) | ||
if (end && onEnd && !ended) { | ||
onEnd(end === true ? null : end, digest) | ||
ended = true | ||
} | ||
}) | ||
} | ||
} | ||
hasher.hash = hash | ||
return hasher | ||
function addSSBBlob(sbot, cb) { | ||
// work around sbot.blobs.add not calling back with blob id | ||
var done = multicb({ pluck: 1, spread: true }) | ||
var hashCb = done() | ||
done(cb) | ||
return pull(createSSBBlobHash(hashCb), sbot.blobs.add(done())) | ||
} | ||
function createGitHash(object, onEnd) { | ||
var hasher = createHash('sha1', onEnd) | ||
hasher.hash.update(object.type + ' ' + object.length + '\0') | ||
return hasher | ||
} | ||
function createSSBBlobHash(onEnd) { | ||
return createHash('sha256', function (err, digest) { | ||
onEnd(err, digest && ('&' + digest.toString('base64') + '.sha256')) | ||
}) | ||
} | ||
function Repo(sbot, id, msg) { | ||
@@ -56,2 +35,7 @@ this.sbot = sbot | ||
this._headCbs = [] | ||
this._oldPacksPushable = pushable() | ||
this._newPacksPushable = pushable() | ||
this._oldPacks = cache(this._oldPacksPushable) | ||
this._newPacks = reverse(this._newPacksPushable) | ||
} | ||
@@ -112,2 +96,9 @@ | ||
} | ||
if (c.packs) for (var i = 0; i < c.packs.length; i++) { | ||
this._oldPacksPushable.push({ | ||
packId: c.packs[i].pack.link, | ||
idxId: c.packs[i].idx.link, | ||
}) | ||
} | ||
} | ||
@@ -137,5 +128,13 @@ | ||
} | ||
if (c.packs) for (var i = 0; i < c.packs.length; i++) { | ||
this._newPacksPushable.push({ | ||
packId: c.packs[i].pack.link, | ||
idxId: c.packs[i].idx.link, | ||
}) | ||
} | ||
} | ||
Repo.prototype._getBlob = function (key, cb) { | ||
if (!key) return cb(new Error('Missing blob key')) | ||
var blobs = this.sbot.blobs | ||
@@ -250,2 +249,4 @@ blobs.want(key, function (err, got) { | ||
pull.drain(this._processOldMsg.bind(this), function (err) { | ||
this._oldPacksPushable.end(err) | ||
this._oldRefPushables.forEach(function (pushable) { | ||
@@ -328,4 +329,40 @@ pushable.end(err) | ||
Repo.prototype.getPackfile = function (id, cb) { | ||
this._getBlob(id, cb) | ||
} | ||
Repo.prototype.getPackIndex = function (id, cb) { | ||
this._getBlob(id, cb) | ||
} | ||
Repo.prototype.packs = function () { | ||
return cat([ | ||
this._newPacks(), | ||
this._oldPacks() | ||
]) | ||
} | ||
Repo_readRefUpdates = function (updates, cb) { | ||
var oldRefs = this._refs | ||
var refs | ||
var ended | ||
updates(null, function next(end, update) { | ||
if (ended = end) return cb(end === true ? null : end, refs) | ||
if (update.old != oldRefs[update.name]) | ||
return cb(new Error( | ||
'Ref update old value is incorrect. ' + | ||
'ref: ' + update.name + ', ' + | ||
'old in update: ' + update.old + ', ' + | ||
'old in repo: ' + oldRefs[update.name] | ||
)) | ||
;(refs || (refs = {}))[update.name] = update.new | ||
if (!ended) | ||
updates(null, next) | ||
}) | ||
} | ||
Repo.prototype.update = function (readRefUpdates, readObjects, cb) { | ||
var done = multicb({pluck: 1}) | ||
if (this.sbot.id && this.sbot.id != this.feed) | ||
return cb(new Error('You do not have permission to push to this repo')) | ||
var done = multicb({ pluck: 1, spread: true }) | ||
var sbot = this.sbot | ||
@@ -339,23 +376,5 @@ var allObjects = this._objects | ||
} | ||
var gotRefUpdates | ||
if (readRefUpdates) { | ||
var doneReadingRefs = done() | ||
var oldRefs = this._refs | ||
var refs = msg.refs = {} | ||
readRefUpdates(null, function next(end, update) { | ||
if (end) return doneReadingRefs(end === true ? null : end) | ||
if (update.old != oldRefs[update.name]) | ||
return doneReadingRefs(new Error( | ||
'Ref update old value is incorrect. ' + | ||
'ref: ' + update.name + ', ' + | ||
'old in update: ' + update.old + ', ' + | ||
'old in repo: ' + oldRefs[update.name] | ||
)) | ||
refs[update.name] = update.new | ||
gotRefUpdates = true | ||
if (!ended) | ||
readRefUpdates(null, next) | ||
}) | ||
} | ||
if (readRefUpdates) | ||
Repo_readRefUpdates.call(this, readRefUpdates, done()) | ||
@@ -371,4 +390,3 @@ if (readObjects) { | ||
createGitHash(object, hashDone()), | ||
createSSBBlobHash(hashDone()), | ||
sbot.blobs.add(hashDone()) | ||
addSSBBlob(sbot, hashDone()) | ||
) | ||
@@ -391,9 +409,10 @@ hashDone(function (err, gitHash, blobKey) { | ||
var self = this | ||
done(function (err) { | ||
done(function (err, refUpdatesObj) { | ||
ended = true | ||
if (err) return cb(err) | ||
if (!objects.length && !gotRefUpdates) | ||
if (!objects.length && !refUpdatesObj) | ||
return cb() | ||
msg.objects = objects | ||
msg.refs = refUpdatesObj | ||
sbot.publish(msg, function (err, msgPublished) { | ||
@@ -418,1 +437,38 @@ if (err) { | ||
} | ||
Repo.prototype.uploadPack = function (readRefUpdates, readPacks, cb) { | ||
if (this.sbot.id && this.sbot.id != this.feed) | ||
return cb(new Error('You do not have permission to push to this repo')) | ||
var self = this | ||
var done = multicb({ pluck: 1, spread: true }) | ||
pull( | ||
readPacks, | ||
pull.asyncMap(function (pack, cb) { | ||
var done = multicb({ pluck: 1, spread: true }) | ||
pull(pack.pack, addSSBBlob(self.sbot, done())) | ||
pull(pack.idx, addSSBBlob(self.sbot, done())) | ||
done(function (err, packId, idxId) { | ||
cb(err, {pack: {link: packId}, idx: {link: idxId}}) | ||
}) | ||
}), | ||
pull.collect(done()) | ||
) | ||
if (readRefUpdates) | ||
Repo_readRefUpdates.call(this, readRefUpdates, done()) | ||
done(function (err, packs, refUpdatesObj) { | ||
if (err) return cb(err) | ||
self.sbot.publish({ | ||
type: 'git-update', | ||
repo: self.id, | ||
packs: packs, | ||
refs: refUpdatesObj | ||
}, function (err, msg) { | ||
if (err) return cb(err) | ||
self._processNewMsg(msg.value.content) | ||
setTimeout(cb, 10) | ||
}) | ||
}) | ||
} |
{ | ||
"name": "ssb-git-repo", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "git repos in secure-scuttlebutt", | ||
@@ -25,3 +25,6 @@ "main": "index.js", | ||
"multicb": "^1.2.1", | ||
"pull-cache": "^0.0.0", | ||
"pull-reverse": "^0.0.0", | ||
"pull-cat": "^1.1.8", | ||
"pull-hash": "^0.0.0", | ||
"pull-pushable": "^2.0.0", | ||
@@ -34,5 +37,5 @@ "pull-stream": "^3.1.0", | ||
"scuttlebot": "^7.5.1", | ||
"ssb-keys": "^4.0.10", | ||
"tape": "^4.4.0" | ||
"ssb-keys": "^5.0.0", | ||
"tape": "^4.5.1" | ||
} | ||
} |
@@ -31,3 +31,3 @@ # ssb-git-repo | ||
#### `ssbGit.getRepo(sbot, repoId[, options], cb(err, repo))` | ||
#### `ssbGit.getRepo(sbot, msgOrId[, options], cb(err, repo))` | ||
@@ -37,3 +37,3 @@ Get a repo. | ||
- `sbot`: a [scuttlebot][] or [ssb-client][] object | ||
- `id`: ID of the SSB message that started the repo | ||
- `msgOrId`: SSB message that started the repo, or the ID of it | ||
- `options.live`: keep the repo updated as changes are pushed to it | ||
@@ -87,4 +87,5 @@ - `cb`: function called when the repo is retrieved | ||
repo: MsgId, | ||
refs: { <ref>: String|null }, | ||
objects: [ { type: String, length: Number, sha1: String, link: BlobId } ], | ||
refs: { <ref>: String? }?, | ||
objects: [ { type: String, length: Number, sha1: String, link: BlobId } ]?, | ||
packs: [ { pack: BlobLink, idx: BlobLink } ]?, | ||
} | ||
@@ -100,3 +101,6 @@ ``` | ||
- `object.sha1`: SHA1 hash of the git object | ||
- `object.link`: id of the ssb blob containing the git object's data. | ||
- `object.link`: link to ssb blob containing the git object's data | ||
- `packs`: git packfiles being added to the repo | ||
- `pack.pack` link to ssb blob containing the packfile data | ||
- `pack.idx`: link to ssb blob containing the pack index data | ||
@@ -106,3 +110,2 @@ ## TODO | ||
- reuse index between a user's repos | ||
- handle push with more object IDs than fit in a message | ||
@@ -109,0 +112,0 @@ ## License |
22539
628
116
8
+ Addedpull-cache@^0.0.0
+ Addedpull-hash@^0.0.0
+ Addedpull-reverse@^0.0.0
+ Addedpull-cache@0.0.0(transitive)
+ Addedpull-hash@0.0.0(transitive)
+ Addedpull-reverse@0.0.0(transitive)