%PDF- %PDF-
Direktori : /lib/node_modules/pm2/node_modules/js-git/net/ |
Current File : //lib/node_modules/pm2/node_modules/js-git/net/git-fetch-pack.js |
"use strict"; var makeChannel = require('culvert'); var wrapHandler = require('../lib/wrap-handler'); var bodec = require('bodec'); module.exports = fetchPack; function fetchPack(transport, onError) { if (!onError) onError = throwIt; // Wrap our handler functions to route errors properly. onRef = wrapHandler(onRef, onError); onWant = wrapHandler(onWant, onError); onNak = wrapHandler(onNak, onError); onMore = wrapHandler(onMore, onError); onReady = wrapHandler(onReady, onError); var caps = null; var capsSent = false; var refs = {}; var haves = {}; var havesCount = 0; // Create a duplex channel for talking with the agent. var libraryChannel = makeChannel(); var agentChannel = makeChannel(); var api = { put: libraryChannel.put, drain: libraryChannel.drain, take: agentChannel.take }; // Start the connection and listen for the response. var socket = transport("git-upload-pack", onError); socket.take(onRef); // Return the other half of the duplex API channel. return { put: agentChannel.put, drain: agentChannel.drain, take: libraryChannel.take }; function onRef(line) { if (line === undefined) { throw new Error("Socket disconnected"); } if (line === null) { api.put(refs); api.take(onWant); return; } else if (!caps) { caps = {}; Object.defineProperty(refs, "caps", {value: caps}); Object.defineProperty(refs, "shallows", {value:[]}); var index = line.indexOf("\0"); if (index >= 0) { line.substring(index + 1).split(" ").forEach(function (cap) { var i = cap.indexOf("="); if (i >= 0) { caps[cap.substring(0, i)] = cap.substring(i + 1); } else { caps[cap] = true; } }); line = line.substring(0, index); } } var match = line.match(/(^[0-9a-f]{40}) (.*)$/); if (!match) { if (typeof line === "string" && /^ERR/i.test(line)) { throw new Error(line); } throw new Error("Invalid line: " + JSON.stringify(line)); } refs[match[2]] = match[1]; socket.take(onRef); } var packChannel; var progressChannel; var errorChannel; function onWant(line) { if (line === undefined) return socket.put(); if (line === null) { socket.put(null); return api.take(onWant); } if (line.deepen) { socket.put("deepen " + line.deepen + "\n"); return api.take(onWant); } if (line.have) { haves[line.have] = true; havesCount++; socket.put("have " + line.have + "\n"); return api.take(onWant); } if (line.want) { var extra = ""; if (!capsSent) { capsSent = true; if (caps["ofs-delta"]) extra += " ofs-delta"; if (caps["thin-pack"]) extra += " thin-pack"; // if (caps["multi_ack_detailed"]) extra += " multi_ack_detailed"; // else if (caps["multi_ack"]) extra +=" multi_ack"; if (caps["side-band-64k"]) extra += " side-band-64k"; else if (caps["side-band"]) extra += " side-band"; // if (caps["agent"]) extra += " agent=" + agent; if (caps.agent) extra += " agent=" + caps.agent; } extra += "\n"; socket.put("want " + line.want + extra); return api.take(onWant); } if (line.done) { socket.put("done\n"); return socket.take(onNak); } throw new Error("Invalid have/want command"); } function onNak(line) { if (line === undefined) return api.put(); if (line === null) return socket.take(onNak); if (bodec.isBinary(line) || line.progress || line.error) { packChannel = makeChannel(); progressChannel = makeChannel(); errorChannel = makeChannel(); api.put({ pack: { take: packChannel.take }, progress: { take: progressChannel.take }, error: { take: errorChannel.take }, }); return onMore(null, line); } var match = line.match(/^shallow ([0-9a-f]{40})$/); if (match) { refs.shallows.push(match[1]); return socket.take(onNak); } match = line.match(/^ACK ([0-9a-f]{40})$/); if (match) { return socket.take(onNak); } if (line === "NAK") { return socket.take(onNak); } throw new Error("Expected NAK, but got " + JSON.stringify(line)); } function onMore(line) { if (line === undefined) { packChannel.put(); progressChannel.put(); errorChannel.put(); return api.put(); } if (line === null) { api.put(line); } else { if (line.progress) { progressChannel.put(line.progress); } else if (line.error) { errorChannel.put(line.error); } else { if (!packChannel.put(line)) { return packChannel.drain(onReady); } } } socket.take(onMore); } function onReady() { socket.take(onMore); } } var defer = require('js-git/lib/defer'); function throwIt(err) { defer(function () { throw err; }); // throw err; }