Permalink
Browse files

Merge pull request #928 from apiaryio/honzajavorek/gopath

Use GOPATH if GOBIN isn't set
  • Loading branch information...
honzajavorek committed Dec 1, 2017
2 parents e961205 + b8f9197 commit ed234f5a99a0c5794d274c6f31209bf532aa35d0
Showing with 179 additions and 23 deletions.
  1. +24 −0 src/get-go-bin.coffee
  2. +18 −20 src/hooks-worker-client.coffee
  3. +115 −0 test/unit/get-go-bin-test.coffee
  4. +22 −3 test/unit/hooks-worker-client-test.coffee
View
@@ -0,0 +1,24 @@
path = require('path')
childProcess = require('child_process')
# Docs:
# - https://golang.org/doc/code.html#GOPATH
# - https://golang.org/cmd/go/#hdr-GOPATH_environment_variable
getGoBin = (callback) ->
goBin = process.env.GOBIN
if goBin
process.nextTick( -> callback(null, goBin))
else
if process.env.GOPATH
process.nextTick( ->
callback(null, path.join(process.env.GOPATH, 'bin'))
)
else
childProcess.exec('go env GOPATH', (err, stdout) ->
return callback(err) if err
callback(null, path.join(stdout.trim(), 'bin'))
)
module.exports = getGoBin
@@ -1,11 +1,13 @@
net = require('net')
path = require('path')
{EventEmitter} = require('events')
spawnArgs = require('spawn-args')
generateUuid = require('uuid').v4
{spawn} = require('./child-process')
logger = require('./logger')
which = require('./which')
getGoBin = require('./get-go-bin')
class HooksWorkerClient
@@ -134,26 +136,22 @@ class HooksWorkerClient
return callback(new Error(msg))
else if @language == 'go'
# https://golang.org/cmd/go/
# "you can add DIR/bin to your PATH to get at the installed commands.
# If the GOBIN environment variable is set, commands are installed to the
# directory it names instead of DIR/bin. GOBIN must be an absolute path."
# Use the gobin if provided, otherwise fall back to gopath
gobin = process.env.GOBIN
if !gobin
gobin = "#{process.env.GOPATH}/bin"
@handlerCommand = "#{gobin}/goodman"
@handlerCommandArgs = []
unless which.which @handlerCommand
msg = '''\
Go hooks handler command not found in $GOBIN or $GOPATH/bin
Install go hooks handler by running:
$ go get github.com/snikch/goodman/cmd/goodman
'''
return callback(new Error(msg))
else
callback()
getGoBin((err, goBin) =>
if err
callback(new Error("Go doesn't seem to be installed: #{err.message}"))
else
@handlerCommand = path.join(goBin, 'goodman')
@handlerCommandArgs = []
if which.which(@handlerCommand)
callback()
else
msg = """\
Go hooks handler command not found: #{@handlerCommand}
Install go hooks handler by running:
$ go get github.com/snikch/goodman/cmd/goodman
"""
return callback(new Error(msg))
)
else
parsedArgs = spawnArgs(@language)
@handlerCommand = parsedArgs.shift()
@@ -0,0 +1,115 @@
{assert} = require('chai')
sinon = require('sinon')
path = require('path')
childProcess = require('child_process')
getGoBin = require('../../src/get-go-bin')
describe('getGoBin()', ->
goBin = undefined
goPath = undefined
beforeEach( ->
goBin = process.env.GOBIN
delete process.env.GOBIN
goPath = process.env.GOPATH
delete process.env.GOPATH
)
afterEach( ->
process.env.GOBIN = goBin
process.env.GOPATH = goPath
)
describe('when $GOBIN is set', ->
callbackArgs = undefined
beforeEach((done) ->
process.env.GOBIN = path.join('dummy', 'gobin', 'path')
getGoBin((args...) ->
callbackArgs = args
done()
)
)
it('resolves as $GOBIN', ->
assert.deepEqual(callbackArgs, [null, path.join('dummy', 'gobin', 'path')])
)
)
describe('when $GOPATH is set', ->
callbackArgs = undefined
beforeEach((done) ->
process.env.GOPATH = path.join('dummy', 'gopath', 'path')
getGoBin((args...) ->
callbackArgs = args
done()
)
)
it('resolves as $GOPATH + /bin', ->
assert.deepEqual(callbackArgs, [null, path.join('dummy', 'gopath', 'path', 'bin')])
)
)
describe('when both $GOBIN and $GOPATH are set', ->
callbackArgs = undefined
beforeEach((done) ->
process.env.GOBIN = path.join('dummy', 'gobin', 'path')
process.env.GOPATH = path.join('dummy', 'gopath', 'path')
getGoBin((args...) ->
callbackArgs = args
done()
)
)
it('resolves as $GOBIN', ->
assert.deepEqual(callbackArgs, [null, path.join('dummy', 'gobin', 'path')])
)
)
describe('when neither $GOBIN nor $GOPATH are set', ->
callbackArgs = undefined
beforeEach((done) ->
sinon.stub(childProcess, 'exec').callsFake((command, callback) ->
callback(null, path.join('dummy', 'gopath', 'path'))
)
getGoBin((args...) ->
callbackArgs = args
done()
)
)
afterEach( ->
childProcess.exec.restore()
)
it('calls \'go env GOPATH\' + /bin', ->
assert.deepEqual(callbackArgs, [null, path.join('dummy', 'gopath', 'path', 'bin')])
)
)
describe('when \'go env GOPATH\' fails', ->
error = new Error('Ouch!')
callbackArgs = undefined
beforeEach((done) ->
sinon.stub(childProcess, 'exec').callsFake((command, callback) ->
callback(error)
)
getGoBin((args...) ->
callbackArgs = args
done()
)
)
afterEach( ->
childProcess.exec.restore()
)
it('propagates the error', ->
assert.deepEqual(callbackArgs, [error])
)
)
)
@@ -4,6 +4,7 @@ sinon = require 'sinon'
net = require 'net'
{assert} = require 'chai'
clone = require 'clone'
childProcess = require('child_process')
crossSpawnStub = require('cross-spawn')
whichStub = require('../../src/which')
@@ -345,7 +346,14 @@ describe 'Hooks worker client', ->
done()
describe 'when --language=go option is given and the worker is not installed', ->
goBin = undefined
goPath = undefined
beforeEach ->
goBin = process.env.GOBIN
goPath = process.env.GOPATH
process.env.GOBIN = '/dummy/gobin/path'
delete process.env.GOPATH
sinon.stub(whichStub, 'which').callsFake (command) -> false
runner.hooks['configuration'] =
@@ -354,6 +362,8 @@ describe 'Hooks worker client', ->
hookfiles: 'gobinary'
afterEach ->
whichStub.which.restore()
process.env.GOBIN = goBin
process.env.GOPATH = goPath
it 'should write a hint how to install', (done) ->
loadWorkerClient (err) ->
@@ -362,7 +372,15 @@ describe 'Hooks worker client', ->
done()
describe 'when --language=go option is given and the worker is installed', ->
dummyPath = path.join('dummy', 'gobin', 'path')
goBin = undefined
goPath = undefined
beforeEach ->
goBin = process.env.GOBIN
goPath = process.env.GOPATH
process.env.GOBIN = dummyPath
delete process.env.GOPATH
sinon.stub(crossSpawnStub, 'spawn').callsFake( ->
emitter = new EventEmitter
emitter.stdout = new EventEmitter
@@ -387,16 +405,17 @@ describe 'Hooks worker client', ->
whichStub.which.restore()
HooksWorkerClient.prototype.terminateHandler.restore()
process.env.GOBIN = goBin
process.env.GOPATH = goPath
it 'should spawn the server process with command "$GOPATH/bin/goodman"', (done) ->
process.env.GOPATH = 'gopath'
it 'should spawn the server process with command "$GOBIN/goodman"', (done) ->
loadWorkerClient (err) ->
assert.isUndefined err
hooksWorkerClient.stop (err) ->
assert.isUndefined err
assert.isTrue crossSpawnStub.spawn.called
assert.equal crossSpawnStub.spawn.getCall(0).args[0], 'gopath/bin/goodman'
assert.equal crossSpawnStub.spawn.getCall(0).args[0], path.join(dummyPath, 'goodman')
done()
it 'should pass --hookfiles option as an array of arguments', (done) ->

0 comments on commit ed234f5

Please sign in to comment.