Skip to content

Commit

Permalink
0.5.0
Browse files Browse the repository at this point in the history
- adds  functionality for event streams and response streams
  • Loading branch information
gabrielcsapo committed Nov 27, 2018
1 parent 21dc88e commit dd20baf
Show file tree
Hide file tree
Showing 6 changed files with 989 additions and 645 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.5.0 (11/27/2018)

- adds `log` functionality for event streams and response streams

# 0.4.3 (04/30/2018)

- removes deprecated `Buffer` interface
Expand Down
105 changes: 104 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,109 @@ npm install node-git-server

# Usage

## Simple

```javascript
const path = require('path');
const Server = require('node-git-server');

const repos = new Server(path.resolve(__dirname, 'tmp'), {
autoCreate: true
});
const port = process.env.PORT || 7005;

repos.on('push', (push) => {
console.log(`push ${push.repo}/${push.commit} (${push.branch})`);
push.accept();
});

repos.on('fetch', (fetch) => {
console.log(`fetch ${fetch.commit}`);
fetch.accept();
});

repos.listen(port, () => {
console.log(`node-git-server running at http://localhost:${port}`)
});
```

then start up the node-git-server server...

```
$ node example/index.js
```

meanwhile...

```
$ git push http://localhost:7005/beep master
Counting objects: 356, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (133/133), done.
Writing objects: 100% (356/356), 46.20 KiB, done.
Total 356 (delta 210), reused 355 (delta 210)
To http://localhost:7005/beep
* [new branch] master -> master
```

## Sending logs

```javascript
const path = require('path');
const Server = require('node-git-server');

const repos = new Server(path.resolve(__dirname, 'tmp'), {
autoCreate: true
});
const port = process.env.PORT || 7005;

repos.on('push', (push) => {
console.log(`push ${push.repo}/${push.commit} (${push.branch})`);

repos.list((err, results) => {
push.log(' ');
push.log('Hey!');
push.log('Checkout these other repos:');
for(const repo of results) {
push.log(`- ${repo}`);
}
push.log(' ');
});

push.accept();
});

repos.listen(port, () => {
console.log(`node-git-server running at http://localhost:${port}`)
});
```

then start up the node-git-server server...

```
$ node example/index.js
```

meanwhile...

```
$ git push http://localhost:7005/beep master
Counting objects: 356, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (133/133), done.
Writing objects: 100% (356/356), 46.20 KiB, done.
Total 356 (delta 210), reused 355 (delta 210)
remote:
remote: Hey!
remote: Checkout these other repos:
remote: - test.git
remote:
To http://localhost:7005/test
77bb26e..22918d5 master -> master
```

### Authentication

```javascript
const path = require('path');
const Server = require('node-git-server');
Expand Down Expand Up @@ -73,7 +176,7 @@ To http://localhost:7005/beep
* [new branch] master -> master
```

## Example
# Example

Running the following command will start up a simple http server:

Expand Down
16 changes: 12 additions & 4 deletions example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,17 @@ const repos = new Server(path.normalize(path.resolve(__dirname, 'tmp')), {

repos.on('push', (push) => {
console.log(`push ${push.repo} / ${push.commit} ( ${push.branch} )`); // eslint-disable-line
repos.list((err, result) => {
console.log(result); // eslint-disable-line

repos.list((err, results) => {
push.log(' ');
push.log('Hey!');
push.log('Checkout these other repos:');
for(const repo of results) {
push.log(`- ${repo}`);
}
push.log(' ');
});

push.accept();
});

Expand All @@ -53,8 +61,8 @@ repos.on('fetch', (fetch) => {

repos.listen(port, {
type,
key: fs.readFileSync('./privatekey.pem'),
cert: fs.readFileSync('./certificate.pem')
key: fs.readFileSync(path.resolve(__dirname, 'privatekey.pem')),
cert: fs.readFileSync(path.resolve(__dirname, 'certificate.pem'))
}, (error) => {
if(error) return console.error(`failed to start git-server because of error ${error}`); // eslint-disable-line
console.log(`node-git-server running at ${type}://localhost:${port}`); // eslint-disable-line
Expand Down
56 changes: 48 additions & 8 deletions lib/service.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
const through = require('through');
const HttpDuplex = require('./http-duplex');
const zlib = require('zlib');

const util = require('util');
const { spawn } = require('child_process');

const HttpDuplex = require('./http-duplex');

const headerRE = {
'receive-pack': '([0-9a-fA-F]+) ([0-9a-fA-F]+) refs\/(heads|tags)\/(.*?)( |00|\u0000)|^(0000)$', // eslint-disable-line
'upload-pack': '^\\S+ ([0-9a-fA-F]+)'
};

const packSideband = s => {
const n = (4 + s.length).toString(16);
return Array(4 - n.length + 1).join('0') + n + s;
};

class Service extends HttpDuplex {
/**
* Handles invoking the git-*-pack binaries
Expand All @@ -28,6 +34,7 @@ class Service extends HttpDuplex {
this.repo = opts.repo;
this.service = opts.service;
this.cwd = opts.cwd;
this.logs = [];

var buffered = through().pause();

Expand Down Expand Up @@ -96,35 +103,59 @@ class Service extends HttpDuplex {

self.once('accept', function onAccept() {
process.nextTick(function() {
var cmd = ['git-' + opts.service, '--stateless-rpc', opts.cwd];
var ps = spawn(cmd[0], cmd.slice(1));
const cmd = ['git-' + opts.service, '--stateless-rpc', opts.cwd];
const ps = spawn(cmd[0], cmd.slice(1));

ps.on('error', function(err) {
self.emit('error', new Error(`${err.message} running command ${cmd.join(' ')}`));
});

self.emit('service', ps);

var respStream = through(function(c) {
if (self.listeners('response').length === 0) return this.queue(c);
var respStream = through(function write(c) {
if (self.listeners('response').length === 0) {
if(self.logs.length > 0) {
while(self.logs.length > 0) {
this.queue(self.logs.pop());
}
}

return this.queue(c);
}
// prevent git from sending the close signal
if (c.length === 4 && c.toString() === '0000') return;
this.queue(c);
}, function() {
}, function end() {
if (self.listeners('response').length > 0) return;

this.queue(null);
});

respStream.log = function() {
self.log(...arguments);
};

self.emit('response', respStream, function endResponse() {
res.queue(new Buffer.from('0000'));
res.queue(null);
});

ps.stdout.pipe(respStream).pipe(res);

buffered.pipe(ps.stdin);
buffered.resume();

ps.on('exit', self.emit.bind(self, 'exit'));
ps.on('exit', () => {
if(self.logs.length > 0) {
while(self.logs.length > 0) {
respStream.queue(self.logs.pop());
}
respStream.queue(Buffer.from('0000'));
respStream.queue(null);
}

self.emit.bind(self, 'exit');
});
});
});

Expand All @@ -133,6 +164,15 @@ class Service extends HttpDuplex {
res.end(msg);
});
}

log() {
const _log = util.format(...arguments);
const SIDEBAND = String.fromCharCode(2); // PROGRESS
const message = `${SIDEBAND}${_log}\n`;
const formattedMessage = Buffer.from(packSideband(message));

this.logs.unshift(formattedMessage);
}
/**
* reject request in flight
* @method reject
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "node-git-server",
"version": "0.4.3",
"version": "0.5.0",
"description": "🎡 A configurable git server written in Node.js",
"author": "Gabriel J. Csapo <[email protected]>",
"contributors": [
Expand Down
Loading

0 comments on commit dd20baf

Please sign in to comment.