Skip to content

Commit

Permalink
feat: Slay the Dragon! (#165)
Browse files Browse the repository at this point in the history
* chore: update deps

* test: check tests

* fix

* refactor npm installs tests, make sure to capture both api and gw match

* moar refactoring

* slayed two of the dragons, one to go

* what a beautiful dragon to be slayed

* apply cr
  • Loading branch information
daviddias authored Sep 6, 2017
1 parent ee3c86a commit 80377cd
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 136 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"dependencies": {
"async": "^2.5.0",
"go-ipfs-dep": "0.4.10",
"ipfs-api": "^14.3.1",
"ipfs-api": "^14.3.2",
"multiaddr": "^3.0.0",
"once": "^1.4.0",
"rimraf": "^2.6.1",
Expand Down
60 changes: 43 additions & 17 deletions src/node.js → src/daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ function findIpfsExecutable () {
const npm3Path = path.join(appRoot, '../', depPath)
const npm2Path = path.join(appRoot, 'node_modules', depPath)

let npmPath
try {
fs.statSync(npm3Path)
return npm3Path
npmPath = npm3Path
} catch (e) {
return npm2Path
npmPath = npm2Path
}

return npmPath
}

function setConfigValue (node, key, value, callback) {
Expand Down Expand Up @@ -201,11 +204,26 @@ class Node {

callback = once(callback)

// Check if there were explicit options to want or not want. Otherwise,
// assume values will be in the local daemon config
// TODO: This should check the local daemon config
const want = {
gateway: typeof this.opts['Addresses.Gateway'] === 'string'
? this.opts['Addresses.Gateway'].length > 0
: true,
api: typeof this.opts['Addresses.API'] === 'string'
? this.opts['Addresses.API'].length > 0
: true
}

parseConfig(this.path, (err, conf) => {
if (err) {
return callback(err)
}

let output = ''
let returned = false

this.subprocess = this._run(args, {env: this.env}, {
error: (err) => {
// Only look at the last error
Expand All @@ -225,18 +243,28 @@ class Node {
}
},
data: (data) => {
const str = String(data).trim()
const match = str.match(/API server listening on (.*)/)
const gwmatch = str.match(/Gateway (.*) listening on (.*)/)

if (match) {
this._apiAddr = multiaddr(match[1])
this.api = ipfs(match[1])
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port

if (gwmatch) {
this._gatewayAddr = multiaddr(gwmatch[2])
output += String(data)

const apiMatch = want.api
? output.trim().match(/API server listening on (.*)/)
: true

const gwMatch = want.gateway
? output.trim().match(/Gateway (.*) listening on (.*)/)
: true

if (apiMatch && gwMatch && !returned) {
returned = true

if (want.api) {
this._apiAddr = multiaddr(apiMatch[1])
this.api = ipfs(apiMatch[1])
this.api.apiHost = this.apiAddr.nodeAddress().address
this.api.apiPort = this.apiAddr.nodeAddress().port
}

if (want.gateway) {
this._gatewayAddr = multiaddr(gwMatch[2])
this.api.gatewayHost = this.gatewayAddr.nodeAddress().address
this.api.gatewayPort = this.gatewayAddr.nodeAddress().port
}
Expand All @@ -255,9 +283,7 @@ class Node {
* @returns {undefined}
*/
stopDaemon (callback) {
if (!callback) {
callback = () => {}
}
callback = callback || function noop () {}

if (!this.subprocess) {
return callback()
Expand Down
55 changes: 30 additions & 25 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
const os = require('os')
const join = require('path').join

const Node = require('./node')
const Node = require('./daemon')

// Note how defaultOptions are Addresses.Swarm and not Addresses: { Swarm : <> }
const defaultOptions = {
'Addresses.Swarm': ['/ip4/0.0.0.0/tcp/0'],
'Addresses.Gateway': '',
Expand Down Expand Up @@ -33,6 +34,7 @@ const IpfsDaemonController = {
version (callback) {
(new Node()).version(callback)
},

/**
* Create a new local node.
*
Expand All @@ -47,37 +49,17 @@ const IpfsDaemonController = {
callback = opts
opts = {}
}

if (!callback) {
callback = path
path = process.env.IPFS_PATH ||
join(process.env.HOME ||
process.env.USERPROFILE, '.ipfs')
}
process.nextTick(() => {
callback(null, new Node(path, opts))
})
},
/**
* Create a new disposable node and already start the daemon.
*
* @memberof IpfsDaemonController
* @param {Object} [opts={}]
* @param {function(Error, Node)} callback
* @returns {undefined}
*/
disposableApi (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = {}
}
this.disposable(opts, (err, node) => {
if (err) {
return callback(err)
}

node.startDaemon(callback)
})
process.nextTick(() => callback(null, new Node(path, opts)))
},

/**
* Create a new disposable node.
* This means the repo is created in a temporary location and cleaned up on process exit.
Expand All @@ -90,7 +72,7 @@ const IpfsDaemonController = {
disposable (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = {}
opts = defaultOptions
}

let options = {}
Expand All @@ -109,6 +91,29 @@ const IpfsDaemonController = {
} else {
node.init((err) => callback(err, node))
}
},

/**
* Create a new disposable node and already started the daemon.
*
* @memberof IpfsDaemonController
* @param {Object} [opts={}]
* @param {function(Error, Node)} callback
* @returns {undefined}
*/
disposableApi (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = defaultOptions
}

this.disposable(opts, (err, node) => {
if (err) {
return callback(err)
}

node.startDaemon(callback)
})
}
}

Expand Down
53 changes: 53 additions & 0 deletions test/npm-installs.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* eslint-env mocha */
/* eslint max-nested-callbacks: ["error", 8] */
'use strict'

const chai = require('chai')
const dirtyChai = require('dirty-chai')
const expect = chai.expect
chai.use(dirtyChai)
const fs = require('fs')
const rimraf = require('rimraf')
const mkdirp = require('mkdirp')
const path = require('path')

describe('ipfs executable path', () => {
it('has the correct path when installed with npm3', (done) => {
process.env.testpath = '/tmp/ipfsd-ctl-test/node_modules/ipfsd-ctl/lib' // fake __dirname
let npm3Path = '/tmp/ipfsd-ctl-test/node_modules/go-ipfs-dep/go-ipfs'

mkdirp(npm3Path, (err) => {
expect(err).to.not.exist()

fs.writeFileSync(path.join(npm3Path, 'ipfs'))
delete require.cache[require.resolve('../src/daemon.js')]
const Daemon = require('../src/daemon.js')

const node = new Daemon()
expect(node.exec)
.to.eql(path.normalize('/tmp/ipfsd-ctl-test/node_modules/go-ipfs-dep/go-ipfs/ipfs'))
rimraf('/tmp/ipfsd-ctl-test', done)
})
})

it('has the correct path when installed with npm2', (done) => {
process.env.testpath = '/tmp/ipfsd-ctl-test/node_modules/ipfsd-ctl/lib' // fake __dirname
let npm2Path = '/tmp/ipfsd-ctl-test/node_modules/ipfsd-ctl/node_modules/go-ipfs-dep/go-ipfs'

mkdirp(npm2Path, (err) => {
expect(err).to.not.exist()

fs.writeFileSync(path.join(npm2Path, 'ipfs'))
delete require.cache[require.resolve('../src/daemon.js')]
const Daemon = require('../src/daemon.js')

const node = new Daemon()

expect(node.exec)
.to.eql(
path.normalize('/tmp/ipfsd-ctl-test/node_modules/ipfsd-ctl/node_modules/go-ipfs-dep/go-ipfs/ipfs')
)
rimraf('/tmp/ipfsd-ctl-test', done)
})
})
})
Loading

0 comments on commit 80377cd

Please sign in to comment.