11const through = require ( 'through' ) ;
2- const HttpDuplex = require ( './http-duplex' ) ;
32const zlib = require ( 'zlib' ) ;
4-
3+ const util = require ( 'util' ) ;
54const { spawn } = require ( 'child_process' ) ;
65
6+ const HttpDuplex = require ( './http-duplex' ) ;
7+
78const headerRE = {
89 'receive-pack' : '([0-9a-fA-F]+) ([0-9a-fA-F]+) refs\/(heads|tags)\/(.*?)( |00|\u0000)|^(0000)$' , // eslint-disable-line
910 'upload-pack' : '^\\S+ ([0-9a-fA-F]+)'
1011} ;
1112
13+ const packSideband = s => {
14+ const n = ( 4 + s . length ) . toString ( 16 ) ;
15+ return Array ( 4 - n . length + 1 ) . join ( '0' ) + n + s ;
16+ } ;
17+
1218class Service extends HttpDuplex {
1319 /**
1420 * Handles invoking the git-*-pack binaries
@@ -28,6 +34,7 @@ class Service extends HttpDuplex {
2834 this . repo = opts . repo ;
2935 this . service = opts . service ;
3036 this . cwd = opts . cwd ;
37+ this . logs = [ ] ;
3138
3239 var buffered = through ( ) . pause ( ) ;
3340
@@ -96,35 +103,59 @@ class Service extends HttpDuplex {
96103
97104 self . once ( 'accept' , function onAccept ( ) {
98105 process . nextTick ( function ( ) {
99- var cmd = [ 'git-' + opts . service , '--stateless-rpc' , opts . cwd ] ;
100- var ps = spawn ( cmd [ 0 ] , cmd . slice ( 1 ) ) ;
106+ const cmd = [ 'git-' + opts . service , '--stateless-rpc' , opts . cwd ] ;
107+ const ps = spawn ( cmd [ 0 ] , cmd . slice ( 1 ) ) ;
108+
101109 ps . on ( 'error' , function ( err ) {
102110 self . emit ( 'error' , new Error ( `${ err . message } running command ${ cmd . join ( ' ' ) } ` ) ) ;
103111 } ) ;
104112
105113 self . emit ( 'service' , ps ) ;
106114
107- var respStream = through ( function ( c ) {
108- if ( self . listeners ( 'response' ) . length === 0 ) return this . queue ( c ) ;
115+ var respStream = through ( function write ( c ) {
116+ if ( self . listeners ( 'response' ) . length === 0 ) {
117+ if ( self . logs . length > 0 ) {
118+ while ( self . logs . length > 0 ) {
119+ this . queue ( self . logs . pop ( ) ) ;
120+ }
121+ }
122+
123+ return this . queue ( c ) ;
124+ }
109125 // prevent git from sending the close signal
110126 if ( c . length === 4 && c . toString ( ) === '0000' ) return ;
111127 this . queue ( c ) ;
112- } , function ( ) {
128+ } , function end ( ) {
113129 if ( self . listeners ( 'response' ) . length > 0 ) return ;
130+
114131 this . queue ( null ) ;
115132 } ) ;
116133
134+ respStream . log = function ( ) {
135+ self . log ( ...arguments ) ;
136+ } ;
117137
118138 self . emit ( 'response' , respStream , function endResponse ( ) {
119139 res . queue ( new Buffer . from ( '0000' ) ) ;
120140 res . queue ( null ) ;
121141 } ) ;
142+
122143 ps . stdout . pipe ( respStream ) . pipe ( res ) ;
123144
124145 buffered . pipe ( ps . stdin ) ;
125146 buffered . resume ( ) ;
126147
127- ps . on ( 'exit' , self . emit . bind ( self , 'exit' ) ) ;
148+ ps . on ( 'exit' , ( ) => {
149+ if ( self . logs . length > 0 ) {
150+ while ( self . logs . length > 0 ) {
151+ respStream . queue ( self . logs . pop ( ) ) ;
152+ }
153+ respStream . queue ( Buffer . from ( '0000' ) ) ;
154+ respStream . queue ( null ) ;
155+ }
156+
157+ self . emit . bind ( self , 'exit' ) ;
158+ } ) ;
128159 } ) ;
129160 } ) ;
130161
@@ -133,6 +164,15 @@ class Service extends HttpDuplex {
133164 res . end ( msg ) ;
134165 } ) ;
135166 }
167+
168+ log ( ) {
169+ const _log = util . format ( ...arguments ) ;
170+ const SIDEBAND = String . fromCharCode ( 2 ) ; // PROGRESS
171+ const message = `${ SIDEBAND } ${ _log } \n` ;
172+ const formattedMessage = Buffer . from ( packSideband ( message ) ) ;
173+
174+ this . logs . unshift ( formattedMessage ) ;
175+ }
136176 /**
137177 * reject request in flight
138178 * @method reject
0 commit comments