Skip to content

Commit

Permalink
Add ngo.bin, tweak readme a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
doesdev committed Mar 21, 2018
1 parent d9dc8f8 commit 80fdf88
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 24 deletions.
47 changes: 30 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ngo [![NPM version](https://badge.fury.io/js/ngo.svg)](https://npmjs.org/package/ngo) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) [![Dependency Status](https://dependencyci.com/github/doesdev/ngo/badge)](https://dependencyci.com/github/doesdev/ngo) [![Build status](https://ci.appveyor.com/api/projects/status/0wutjytsl4hmha1j?svg=true)](https://ci.appveyor.com/project/doesdev/ngo) [![Build Status](https://travis-ci.org/doesdev/ngo.svg)](https://travis-ci.org/doesdev/ngo)

> Run Go commands, whether your Go env is in place or not
> Run Go commands from Node or CLI, Go env not required
Will download latest binaries locally if Go isn't already in PATH

Expand Down Expand Up @@ -39,6 +39,7 @@ returns promise that resolves to `execa` style object without the `child_process
```js
const goOpts = {}
const ngo = require('ngo')(goOpts)
const golint = ngo.bin('golint')

ngo('version').then(console.log).catch(console.error)
/* {
Expand All @@ -50,26 +51,38 @@ ngo('version').then(console.log).catch(console.error)
signal: null,
cmd: 'C:\\Go\\bin\\go version'
} */

golint('main.go').then(console.log).catch(console.error)
```

## api

### const ngo = require('ngo')(opts)
accepts `opts` as below, returns `ngo` function which executes Go commands,
- **options** *[Object - optional]*
- **useLocal** *[Boolean `false`] - use locally downloaded Go binaries)*
- **update** *[Boolean `false`] - update local install to latest*
- **installDeps** *[Boolean `true`] - attempt to install missing packages*
- **env** *[Object] - environment vars to set for the Go command*
- **goRoot** *[String] - Go root path (ex. `/usr/local/go`)*
- **goPath** *[String] - Go workspace path (ex. `~/work`)*

### ngo(arguments, options)
returns promise which resolves to [`execa`](https://github.com/sindresorhus/execa) styled object
- **arguments** *[Array | String - required] - argument(s) to call with `go` command*
- **options** *[Object - optional]*
- same options as [`child_process.spawn`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)
- additonal options available same as [`execa`](https://github.com/sindresorhus/execa#options)
### const ngo = require('ngo')(`options`)
- **Purpose:** initialize `ngo`
- **Arguments:**
- **options** *[`Object` - optional]*
- **useLocal** *[`Boolean` `false`] - use locally downloaded Go binaries)*
- **update** *[`Boolean` `false`] - update local install to latest*
- **installDeps** *[`Boolean` `true`] - attempt to install missing packages*
- **env** *[`Object`] - environment vars to set for the Go command*
- **goRoot** *[`String`] - Go root path (ex. `/usr/local/go`)*
- **goPath** *[`String`] - Go workspace path (ex. `~/work`)*
- **Returns:** `Function` (`ngo`) which executes Go commands

### ngo(`commandArgs`, `options`)
- **Purpose:** - execute `go` commands
- **Arguments:**
- **commandArgs** *[`Array` | `String` - required] - argument(s) to call with `go` command*
- **options** *[`Object` - optional]*
- same options as [`child_process.spawn`](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)
- additonal options available same as [`execa`](https://github.com/sindresorhus/execa#options)
- **Returns:** `Promise` which resolves to [`execa`](https://github.com/sindresorhus/execa) styled object

### ngo.bin(`binary`)
- **Purpose:** - execute commands on binaries in the `GOBIN` directory
- **Arguments:**
- **binary** [`String`] - name of binary file to be executed in returned function
- **Returns:** `Function` (identical to `ngo`, but runs specified binary instead of `go`)

### ngo.env
this is a copy of ngo's `process.env` with the Go environment variables added to it
Expand Down
10 changes: 6 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,23 @@ module.exports = (opts = {}) => {
env.ngoBin = path.join(goRoot, 'bin', 'go')
try { env.hasBin = exists(path.join(goRoot, 'bin')) } catch (ex) {}
if (opts.update) delete env.hasBin
let ngoRunner = (args, cmdOpts = {}) => {
let ngoRunner = (args, cmdOpts = {}, binary) => {
if (opts.update) args = args || ['version']
return runner(args, Object.assign({}, cmdOpts, {env}))
return runner(args, Object.assign({}, cmdOpts, {env}), binary)
}
ngoRunner.env = env
ngoRunner.bin = (binary) => (args, opts) => ngoRunner(args, opts, binary)
return ngoRunner
}

function runner (args, opts) {
function runner (args, opts, binary) {
if (!args) return Promise.reject(new Error(`No Go command specified`))
args = Array.isArray(args) ? args : [args]
let env = opts.env
if (binary && env.GOBIN) binary = path.join(env.GOBIN, binary)
let lastDep
let run = () => {
let go = execa(env.ngoBin, args, opts)
let go = execa(binary || env.ngoBin, args, opts)
if (opts.installDeps === false) return go
go.catch((err) => {
let dep = (`${err}`.match(/cannot find package "(.+?)"/) || [])[1]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ngo",
"version": "2.4.5",
"description": "Run Go commands, whether your Go env is in place or not",
"description": "Run Go commands from Node or CLI, Go env not required",
"engines": {
"node": ">=6.0.0"
},
Expand Down
38 changes: 38 additions & 0 deletions test/fixtures/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2013 The Go Authors. All rights reserved.
// Source: https://github.com/golang/lint/blob/master/testdata/errors.go
// Test for naming errors.

// Package foo ...
package foo

import (
"errors"
"fmt"
)

var unexp = errors.New("some unexported error") // MATCH /error var.*unexp.*errFoo/

// Exp ...
var Exp = errors.New("some exported error") // MATCH /error var.*Exp.*ErrFoo/

var (
e1 = fmt.Errorf("blah %d", 4) // MATCH /error var.*e1.*errFoo/
// E2 ...
E2 = fmt.Errorf("blah %d", 5) // MATCH /error var.*E2.*ErrFoo/
)

func f() {
var whatever = errors.New("ok") // ok
_ = whatever
}

// Check for the error strings themselves.

func g(x int) error {
if x < 1 {
return fmt.Errorf("This %d is too low", x) // MATCH /error strings.*not be capitalized/
} else if x == 0 {
return fmt.Errorf("XML time") // ok
}
return errors.New(`too much stuff.`) // MATCH /error strings.*not end with punctuation/
}
7 changes: 7 additions & 0 deletions test/fixtures/good.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Package foo ...
package foo

import (
"errors"
"fmt"
)
19 changes: 17 additions & 2 deletions test.js → test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import path from 'path'
import { remove } from 'fs-extra'
import test from 'ava'
import ngo from './index'
import ngo from './../index'
const goBinPath = path.resolve(__dirname, '..', 'vendor', 'go')

test.before(() => {
let finish = () => ngo({useLocal: true})('version')
return remove(goBinPath).then(finish).catch(finish)
})

test(`go.env returns environment`, (assert) => {
test.serial(`go.env returns environment`, (assert) => {
let go = ngo({useLocal: true})
assert.truthy(go.env.GOPATH)
assert.truthy(go.env.GOROOT)
Expand All @@ -33,3 +33,18 @@ test.serial(`go(['get', 'somepackage']) works`, async (assert) => {
let go = ngo({useLocal: true})
await assert.notThrows(go(['get', '-u', 'golang.org/x/lint/golint']))
})

test.serial(`go.bin('golint')('errors.go') works`, async (assert) => {
let golint = ngo({useLocal: true}).bin('golint')
let goFile = path.join(__dirname, 'fixtures', 'errors.go')
let anError = /var unexp should have name of the form/
let results = (await golint(goFile)).stdout
assert.regex(results, anError)
})

test.serial(`go.bin('golint')('good.go') works`, async (assert) => {
let golint = ngo({useLocal: true}).bin('golint')
let goFile = path.join(__dirname, 'fixtures', 'good.go')
let results = (await golint(goFile)).stdout
assert.falsy(results)
})

0 comments on commit 80fdf88

Please sign in to comment.