Comparing version 0.0.0 to 0.2.0
@@ -1,1 +0,49 @@ | ||
var | ||
// Bootstrap the platform to run on node.js | ||
require('../lib/platform.js')(require('./node')); | ||
// Load the libraries | ||
var fsDb = require('../lib/fs-db.js'); | ||
var wrap = require('../lib/repo.js'); | ||
var each = require('../helpers/each.js'); | ||
var autoProto = require('../protocols/auto.js'); | ||
var urlParse = require('url').parse; | ||
var serial = require('../helpers/serial.js'); | ||
var parallel = require('../helpers/parallel.js'); | ||
var parallelData = require('../helpers/parallel-data.js'); | ||
var url = process.argv[2] || "git://github.com/creationix/conquest.git"; | ||
var opts = urlParse(url); | ||
if (!opts.protocol) { | ||
opts = urlParse("ssh://" + url); | ||
} | ||
var path = opts.pathname.match(/[^\/]*$/)[0]; | ||
var connection = autoProto(opts); | ||
var repo = wrap(fsDb(path, true)); | ||
var config = { | ||
includeTag: true, | ||
onProgress: function (data) { | ||
process.stdout.write(data); | ||
}, | ||
onError: function (data) { | ||
process.stderr.write(data); | ||
} | ||
}; | ||
parallelData({ | ||
init: repo.init(), | ||
pack: connection.fetch(config), | ||
}, function (err, result) { | ||
if (err) throw err; | ||
serial( | ||
parallel( | ||
repo.importRefs(result.pack.refs), | ||
repo.unpack(result.pack, config) | ||
), | ||
connection.close() | ||
)(function (err) { | ||
if (err) throw err; | ||
console.log("DONE"); | ||
}); | ||
}); |
@@ -1,6 +0,9 @@ | ||
// Inject the dependencies to fsDb to work using node.js | ||
var fsDb = require('../lib/fs-db.js')(require('./node')); | ||
var bops = require('bops'); | ||
// Bootstrap the platform to run on node.js | ||
require('../lib/platform.js')(require('./node')); | ||
// Mock data for creating generating some history | ||
// Load the libraries | ||
var fsDb = require('../lib/fs-db.js'); | ||
var wrap = require('../lib/repo.js'); | ||
// Mock data for generating some history | ||
var author = "Tim Caswell <tim@creationix.com>"; | ||
@@ -24,12 +27,14 @@ var committer = "JS-Git <js-git@creationix.com>"; | ||
fsDb("test.git", { bare: true, init: true}, function (err, db) { | ||
var repo = wrap(fsDb("test.git", true)); | ||
repo.init(function (err) { | ||
if (err) throw err; | ||
console.log("Git database Initialized"); | ||
var parent; | ||
asyncEach(commits, function (message, files, next) { | ||
serialEach(commits, function (message, files, next) { | ||
// Start building a tree object. | ||
var tree = {}; | ||
asyncEach(files, function (name, contents, next) { | ||
db.save(encodeBlob(contents), function (err, hash) { | ||
parallelEach(files, function (name, contents, next) { | ||
repo.saveBlob(contents, function (err, hash) { | ||
if (err) return next(err); | ||
@@ -44,3 +49,3 @@ tree[name] = { | ||
if (err) return next(err); | ||
db.save(encodeTree(tree), function (err, hash) { | ||
repo.saveTree(tree, function (err, hash) { | ||
if (err) return next(err); | ||
@@ -56,6 +61,6 @@ var now = gitDate(new Date); | ||
if (!parent) delete commit.parent; | ||
db.save(encodeCommit(commit), function (err, hash) { | ||
repo.saveCommit(commit, function (err, hash) { | ||
if (err) return next(err); | ||
parent = hash; | ||
updateHead(hash, next); | ||
repo.updateHead(hash, next); | ||
}); | ||
@@ -69,15 +74,13 @@ }); | ||
function updateHead(hash, callback) { | ||
db.read("HEAD")(function (err, value) { | ||
if (err) return callback(err); | ||
if (value.substr(0, 4) !== "ref:") { | ||
return callback(new Error("HEAD must be symbolic ref")); | ||
} | ||
db.write(value.substr(4).trim(), hash + "\n", callback); | ||
}); | ||
} | ||
}); | ||
function asyncEach(object, fn, callback) { | ||
// Format a js data object into the data format expected in git commits. | ||
function gitDate(date) { | ||
var timezone = date.getTimezoneOffset() / 60; | ||
var seconds = Math.floor(date.getTime() / 1000); | ||
return seconds + " " + (timezone > 0 ? "-0" : "0") + timezone + "00"; | ||
} | ||
// Mini control-flow library | ||
function serialEach(object, fn, callback) { | ||
var keys = Object.keys(object); | ||
@@ -92,62 +95,21 @@ next(); | ||
} | ||
function encodeBlob(buffer) { | ||
if (typeof buffer === "string") buffer = bops.from(buffer); | ||
return { | ||
type: "blob", | ||
size: buffer.length, | ||
body: buffer | ||
}; | ||
} | ||
function pathCmp(a, b) { | ||
a += "/"; b += "/"; | ||
return a < b ? -1 : a > b ? 1 : 0; | ||
} | ||
function encodeTree(tree) { | ||
var chunks = []; | ||
Object.keys(tree).sort(pathCmp).forEach(function (name) { | ||
var entry = tree[name]; | ||
chunks.push( | ||
bops.from(entry.mode.toString(8) + " " + name + "\0"), | ||
bops.from(entry.hash, "hex") | ||
); | ||
function parallelEach(object, fn, callback) { | ||
var keys = Object.keys(object); | ||
var left = keys.length + 1; | ||
var done = false; | ||
keys.forEach(function (key) { | ||
fn(key, object[key], check); | ||
}); | ||
var body = bops.join(chunks); | ||
return { | ||
type: "tree", | ||
size: body.length, | ||
body: body | ||
}; | ||
} | ||
function encodeCommit(commit) { | ||
var str = ""; | ||
Object.keys(commit).forEach(function (key) { | ||
if (key === "message") return; | ||
var value = commit[key]; | ||
if (key === "parents") { | ||
value.forEach(function (value) { | ||
str += "parent " + value + "\n"; | ||
}); | ||
check(); | ||
function check(err) { | ||
if (done) return; | ||
if (err) { | ||
done = true; | ||
return callback(err); | ||
} | ||
else { | ||
str += key + " " + value + "\n"; | ||
} | ||
}); | ||
var body = bops.from(str + "\n" + commit.message); | ||
return { | ||
type: "commit", | ||
size: body.length, | ||
body: body | ||
}; | ||
if (--left) return; | ||
done = true; | ||
callback(); | ||
} | ||
} | ||
// Format a js data object into the data format expected in git commits. | ||
function gitDate(date) { | ||
var timezone = date.getTimezoneOffset() / 60; | ||
var seconds = Math.floor(date.getTime() / 1000); | ||
return seconds + " " + (timezone > 0 ? "-0" : "0") + timezone + "00"; | ||
} |
@@ -66,2 +66,6 @@ var fs = require('fs'); | ||
function read(path, encoding, callback) { | ||
if (typeof encoding === "function") { | ||
callback = encoding; | ||
encoding = undefined; | ||
} | ||
if (!callback) return read.bind(this, path, encoding); | ||
@@ -68,0 +72,0 @@ fs.readFile(path, encoding, callback); |
module.exports = { | ||
fs: require('./fs.js'), | ||
tcp: require('./tcp.js'), | ||
http: require('./http.js'), | ||
ssh: require('./ssh.js'), | ||
sha1: require('./sha1.js'), | ||
inflate: require('./inflate.js'), | ||
deflate: require('./deflate.js') | ||
deflate: require('./deflate.js'), | ||
trace: require('./trace.js'), | ||
agent: "jsgit/" + require('../../package.json').version, | ||
}; |
var crypto = require('crypto'); | ||
module.exports = sha1; | ||
function sha1(buffer) { | ||
module.exports = function (buffer) { | ||
if (buffer === undefined) return create(); | ||
var shasum = crypto.createHash('sha1'); | ||
@@ -10,1 +10,15 @@ shasum.update(buffer); | ||
// A streaming interface for when nothing is passed in. | ||
function create() { | ||
var sha1sum = crypto.createHash('sha1'); | ||
return { update: update, digest: digest }; | ||
function update(data) { | ||
sha1sum.update(data); | ||
} | ||
function digest() { | ||
return sha1sum.digest('hex'); | ||
} | ||
} | ||
294
lib/fs-db.js
var bops = require('bops'); | ||
var each = require('./each.js'); | ||
var parallel = require('./parallel.js'); | ||
var serial = require('./serial.js'); | ||
var each = require('../helpers/each.js'); | ||
var parallel = require('../helpers/parallel.js'); | ||
var serial = require('../helpers/serial.js'); | ||
var platform = require('../lib/platform.js'); | ||
var sha1 = platform.require("sha1"); | ||
var inflate = platform.require("inflate"); | ||
var deflate = platform.require("deflate"); | ||
var root = platform.require("fs"); | ||
module.exports = function (interfaces) { | ||
var sha1 = extract(interfaces, "sha1"); | ||
var inflate = extract(interfaces, "inflate"); | ||
var deflate = extract(interfaces, "deflate"); | ||
var root = extract(interfaces, "fs"); | ||
module.exports = function fsDb(path, bare) { | ||
var fs = root(path); | ||
return fsDb; | ||
function fsDb(path, options, callback) { | ||
if (typeof options === "function") { | ||
callback = options; | ||
options = null; | ||
} | ||
if (!callback) return fsDb.bind(this, fs, options); | ||
if (!options) options = {}; | ||
var fs = root(path); | ||
if (!options.bare) fs = fs(".git"); | ||
return { | ||
root: fs.root, | ||
write: write, | ||
read: read, | ||
save: save, | ||
load: load, | ||
remove: remove, | ||
init: init | ||
}; | ||
var db = { | ||
root: fs.root, | ||
write: write, | ||
read: read, | ||
save: save, | ||
load: load, | ||
remove: remove | ||
}; | ||
function hashToPath(hash) { | ||
return "objects/" + hash.substr(0, 2) + "/" + hash.substr(2); | ||
} | ||
if (options.init) { | ||
var config = { core: { | ||
repositoryformatversion: 0, | ||
filemode: true, | ||
bare: !!options.bare | ||
}}; | ||
return init(config)(function (err) { | ||
if (err) return callback(err); | ||
callback(null, db); | ||
}); | ||
} | ||
function write(path, data, callback) { | ||
if (!callback) return write.bind(this, path, data); | ||
mkdirp(dirname(path), function (err) { | ||
if (err) return callback(err); | ||
fs.write(path, data)(callback); | ||
}); | ||
} | ||
return callback(null, db); | ||
function read(path, callback) { | ||
if (!callback) return fs.read(path, "ascii"); | ||
fs.read(path, "ascii")(callback); | ||
} | ||
function hashToPath(hash) { | ||
return "objects/" + hash.substr(0, 2) + "/" + hash.substr(2); | ||
} | ||
function write(path, data, callback) { | ||
if (!callback) return write.bind(this, path, data); | ||
mkdirp(dirname(path), function (err) { | ||
function save(object, callback) { | ||
if (!callback) return save.bind(this, object); | ||
var buffer = encode(object); | ||
var hash = sha1(buffer); | ||
deflate(buffer, function (err, deflated) { | ||
if (err) return callback(err); | ||
write(hashToPath(hash), deflated, function (err) { | ||
if (err) return callback(err); | ||
fs.write(path, data)(callback); | ||
callback(null, hash); | ||
}); | ||
} | ||
}); | ||
} | ||
function read(path, callback) { | ||
if (!callback) return fs.read(path, "ascii"); | ||
fs.read(path, "ascii")(callback); | ||
} | ||
function save(object, callback) { | ||
if (!callback) return save.bind(this, object); | ||
var buffer = encode(object); | ||
var hash = sha1(buffer); | ||
deflate(buffer, function (err, deflated) { | ||
function load(hash, callback) { | ||
if (!callback) return load.bind(this, hash); | ||
fs.read(hashToPath(hash), function (err, deflated) { | ||
if (err) return callback(err); | ||
inflate(deflated, function (err, buffer) { | ||
if (err) return callback(err); | ||
write(hashToPath(hash), deflated, function (err) { | ||
if (err) return callback(err); | ||
callback(null, hash); | ||
}); | ||
if (sha1(buffer) !== hash) { | ||
return callback(new Error("SHA1 checksum failed for " + hash)); | ||
} | ||
var object; | ||
try { object = decode(buffer); } | ||
catch (err) { return callback(err); } | ||
callback(null, object); | ||
}); | ||
} | ||
}); | ||
} | ||
function load(hash, callback) { | ||
if (!callback) return load.bind(this, hash); | ||
fs.read(hashToPath(hash), function (err, deflated) { | ||
if (err) return callback(err); | ||
inflate(deflated, function (err, buffer) { | ||
if (err) return callback(err); | ||
var object; | ||
try { object = parse(buffer); } | ||
catch (err) { return callback(err); } | ||
callback(null, object); | ||
}); | ||
function remove(hash, callback) { | ||
if (!callback) return remove.bind(this, hash); | ||
fs.unlink(hashToPath(hash), function (err) { | ||
if (err) return callback(err); | ||
fs.rmdir(dirname(path), function (err) { | ||
if (err && err.code !== "ENOTEMPTY") { | ||
return callback(err); | ||
} | ||
callback(); | ||
}); | ||
} | ||
}); | ||
} | ||
function remove(hash, callback) { | ||
if (!callback) return remove.bind(this, hash); | ||
fs.unlink(hashToPath(hash), function (err) { | ||
if (err) return callback(err); | ||
fs.rmdir(dirname(path), function (err) { | ||
if (err && err.code !== "ENOTEMPTY") { | ||
return callback(err); | ||
} | ||
callback(); | ||
}); | ||
}); | ||
} | ||
function init(callback) { | ||
if (!callback) return init.bind(this); | ||
var config = { core: { | ||
repositoryformatversion: 0, | ||
filemode: true, | ||
bare: !!bare | ||
}}; | ||
function init(config) { | ||
var conf = ""; | ||
each(config, function (key, section) { | ||
conf += "[" + key + "]\n"; | ||
each(section, function (key, value) { | ||
conf += "\t" + key + " = " + JSON.stringify(value) + "\n"; | ||
}); | ||
var conf = ""; | ||
each(config, function (key, section) { | ||
conf += "[" + key + "]\n"; | ||
each(section, function (key, value) { | ||
conf += "\t" + key + " = " + JSON.stringify(value) + "\n"; | ||
}); | ||
var description = "Unnamed repository; edit this file 'description' to name the repository.\n"; | ||
var exclude = | ||
"# Lines that start with '#' are comments.\n" + | ||
"# For a project mostly in C, the following would be a good set of\n" + | ||
"# exclude patterns (uncomment them if you want to use them):\n" + | ||
"# *.[oa]\n" + | ||
"# *~\n"; | ||
return serial( | ||
fs.mkdir("."), | ||
parallel( | ||
fs.mkdir("branches"), | ||
write("config", conf), | ||
write("description", description), | ||
write("HEAD", "ref: refs/heads/master\n"), | ||
fs.mkdir("hooks"), | ||
serial( | ||
fs.mkdir("info"), | ||
write("info/exclude", exclude) | ||
), | ||
serial( | ||
fs.mkdir("objects"), | ||
parallel( | ||
fs.mkdir("objects/info"), | ||
fs.mkdir("objects/pack") | ||
) | ||
), | ||
serial( | ||
fs.mkdir("refs"), | ||
parallel( | ||
fs.mkdir("refs/heads"), | ||
fs.mkdir("refs/tags") | ||
) | ||
}); | ||
var description = "Unnamed repository; edit this file 'description' to name the repository.\n"; | ||
var exclude = | ||
"# Lines that start with '#' are comments.\n" + | ||
"# For a project mostly in C, the following would be a good set of\n" + | ||
"# exclude patterns (uncomment them if you want to use them):\n" + | ||
"# *.[oa]\n" + | ||
"# *~\n"; | ||
serial( | ||
fs.mkdir("."), | ||
parallel( | ||
fs.mkdir("branches"), | ||
write("config", conf), | ||
write("description", description), | ||
write("HEAD", "ref: refs/heads/master\n"), | ||
fs.mkdir("hooks"), | ||
serial( | ||
fs.mkdir("info"), | ||
write("info/exclude", exclude) | ||
), | ||
serial( | ||
fs.mkdir("objects"), | ||
parallel( | ||
fs.mkdir("objects/info"), | ||
fs.mkdir("objects/pack") | ||
) | ||
), | ||
serial( | ||
fs.mkdir("refs"), | ||
parallel( | ||
fs.mkdir("refs/heads"), | ||
fs.mkdir("refs/tags") | ||
) | ||
) | ||
); | ||
} | ||
) | ||
)(callback); | ||
} | ||
function mkdirp(path, callback) { | ||
if (!callback) return mkdirp.bind(this, path); | ||
fs.mkdir(path)(function (err) { | ||
if (!err || err.code === "EEXIST") return callback(); | ||
if (err.code === "ENOENT") { | ||
return mkdirp(dirname(path), function (err) { | ||
if (err) return callback(err); | ||
mkdirp(path, callback); | ||
}); | ||
} | ||
return callback(err); | ||
}); | ||
} | ||
function mkdirp(path, callback) { | ||
if (!callback) return mkdirp.bind(this, path); | ||
fs.mkdir(path)(function (err) { | ||
if (!err || err.code === "EEXIST") return callback(); | ||
if (err.code === "ENOENT") { | ||
return mkdirp(dirname(path), function (err) { | ||
if (err) return callback(err); | ||
mkdirp(path, callback); | ||
}); | ||
} | ||
return callback(err); | ||
}); | ||
} | ||
}; | ||
function extract(hash, name) { | ||
var implementation = hash[name]; | ||
if (!implementation) throw new TypeError(name + " interface implementation instance required"); | ||
return implementation; | ||
} | ||
function encode(object) { | ||
return bops.join([ | ||
bops.from(object.type + " " + object.size + "\0"), | ||
bops.from(object.type + " " + object.body.length + "\0"), | ||
object.body | ||
@@ -180,9 +160,8 @@ ]); | ||
function indexOf(buffer, byte, i) { | ||
i = i || 0; | ||
i |= 0; | ||
var length = buffer.length; | ||
while (buffer[i] !== byte) { | ||
if (i === length) return -1; | ||
i += 1; | ||
for (;;i++) { | ||
if (i >= length) return -1; | ||
if (buffer[i] === byte) return i; | ||
} | ||
return i; | ||
} | ||
@@ -212,6 +191,8 @@ | ||
if (nil < 0) throw new Error("Invalid git object buffer"); | ||
var body = bops.subarray(buffer, nil + 1); | ||
var size = parseDec(buffer, space + 1, nil); | ||
if (size !== body.length) throw new Error("Invalid body length."); | ||
return { | ||
type: parseAscii(buffer, 0, space), | ||
size: parseDec(buffer, space + 1, nil), | ||
body: bops.subarray(buffer, nil + 1) | ||
body: body | ||
}; | ||
@@ -222,4 +203,5 @@ } | ||
var index = path.lastIndexOf("/"); | ||
if (index < 0) return "/"; | ||
if (index < 0) return "."; | ||
if (index === 0) return "/"; | ||
return path.substr(0, index); | ||
} |
{ | ||
"name": "js-git", | ||
"version": "0.0.0", | ||
"version": "0.2.0", | ||
"description": "Git Implemented in JavaScript", | ||
"main": "index.js", | ||
"bin": { | ||
"js-git": "clone.js" | ||
}, | ||
"directories": { | ||
"example": "examples" | ||
}, | ||
"scripts": { | ||
"test": "node test.js" | ||
}, | ||
"repository": { | ||
@@ -29,4 +19,10 @@ "type": "git", | ||
"dependencies": { | ||
"bops": "0.0.6" | ||
"bops": "~0.0.6", | ||
"git-apply-delta": "0.0.7" | ||
}, | ||
"devDependencies": { | ||
"ssh2": "~0.2.11", | ||
"gen-run": "~0.1.0", | ||
"push-to-pull": "~0.1.0" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 4 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
348625
143
2966
2
3
6
11
+ Addedgit-apply-delta@0.0.7
+ Addedbops@0.0.7(transitive)
+ Addedgit-apply-delta@0.0.7(transitive)
+ Addedvarint@0.0.3(transitive)
- Removedbops@0.0.6(transitive)
Updatedbops@~0.0.6