gabrielcsapo / node-git-server

🎡 A configurable git server written in Node.js
https://gabrielcsapo.github.io/node-git-server
MIT License
253 stars 73 forks source link

Q: Can you write more data to client http connection? #37

Closed stevepeak closed 5 years ago

stevepeak commented 6 years ago

I would like to write data back to client after a push event. I could not find a clear way to do this:

repos.on('push', (push) => {
  push.accept();
  push.client.write('---> Building Application.')
  // ...
  push.client.write('Done.')
})

Think of this like git push heroku master for deploying code. Heroku outputs the build logs during the push command.

$ git push foobar master

Counting objects: 3, done.
Writing objects: 100% (3/3), 633 bytes | 633.00 KiB/s, done.
Total 3 (delta 0), reused 3 (delta 0)
To http://localhost:7005/beep
 * [new branch]      master -> master

---> Building Application.
Done.

Thanks 🙏

gabrielcsapo commented 6 years ago

good question, this did work before, looking into it now!

stevepeak commented 6 years ago

Thanks! 😄 I tried the push.client.write() (I think it was) but there is an issue requiring you to chunk the data yourself. A simple way may be to expose a new method that does this for you automatically.

Full spec of what I'm looking for:

  1. Write streaming event logs to the client.
  2. Reject the push if there are issues during the accepting period
  3. Call my own external method that yields output

Would be great to do this:

repos.on('push', (push) => {
  push.accept(function(push, client){
     // repo.git is uploaded
     client.write('---> Building');
     try {
        // do some long operations
        client.write('     Done.');
      }
      catch(error) {
        console.error(error);
        throw ("Failed to build");
      }
  });
})
gabrielcsapo commented 6 years ago

ohhh, that is interesting, so push is overloaded with the client stream?

shouldn't it look like

repos.on('push', (push) => {
  push.accept(function(client){
     // repo.git is uploaded
     client.write('---> Building\n');
     try {
        // do some long operations
        client.write('     Done.\n');
      }
      catch(error) {
        console.error(error);
        throw ("Failed to build");
      }
  });
})
stevepeak commented 6 years ago

Sorry, that was just an example and mistype. Your implementation above is what functionality I'm seeking.

gabrielcsapo commented 6 years ago

Still looking for a good solution, I might have to rethink a some things, also the git additional text protocol is super confusing -_-

gabrielcsapo commented 6 years ago

so after tons of research, we can only send sideband data to the client when done through info and not on an upload-pack... which means sending data via the push is not possible from what I am seeing / endless trying to implement.

gabrielcsapo commented 6 years ago

Hold on, I think I just figured something out... 💻

xanf commented 5 years ago

For those, who are looking for solution like me, here comes a code to get you started:

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

repos.on('push', push => {
  push.on('response', str => {
    push.once('exit', () => {
      const SIDEBAND = String.fromCharCode(2); // PROGRESS
      const message = `${SIDEBAND}hello long long long\n`;
      const formattedMessage = Buffer.from(pack(message));
      str.queue(formattedMessage);
      str.queue(Buffer.from('0000'));
      str.queue(null);
    });
  });

  console.log(`push ${push.repo}/${push.commit} (${push.branch})`);
  push.accept();
});
gabrielcsapo commented 5 years ago

@xanf will look into putting this into an API you can call thanks for this 🎉

gabrielcsapo commented 5 years ago

got'em~

gabrielcsapoair:test gabrielcsapo$ echo "ddhiii"> ddhdiiiiiiiddddddidsdd.txt && git add -A && git commit -m "wip" && git push
[master 57cd81a] wip
 1 file changed, 1 insertion(+)
 create mode 100644 ddhdiiiiiiiddddddidsdd.txt
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 448 bytes | 448.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Hey!
remote: Thanks for pushing!
To http://localhost:7005/test
   d0dc84b..57cd81a  master -> master
gabrielcsapo commented 5 years ago

after months of this being an issue https://github.com/gabrielcsapo/node-git-server/releases/tag/0.5.0 we have landed 🚀

xanf commented 5 years ago

Yay :)