Skip to content

Commit

Permalink
Merge branch 'master' into jon-usb-close
Browse files Browse the repository at this point in the history
* master:
  Make slim build code path testable; Adds tests
  Only detatch usb listeners if we have a usb controller
  fixes tessel/t2-start#53
  Respect .tesselignore in --slim builds
  Corrected browserify options
  fix(slim bundles): fixes jshint errors
  fix(slim bundles): acknowledges .tesselignore & successfully runs
  feat(slim bundles): generates slim bundle for running on Tessel
  • Loading branch information
rwaldron committed Oct 26, 2015
2 parents 0eae87f + c976c80 commit 55552c8
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 51 deletions.
14 changes: 14 additions & 0 deletions bin/tessel-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ makeCommand('run')
abbr: 'v',
help: 'Choose to view more debugging information'
})
.option('slim', {
flag: true,
help: 'Bundle only the required modules'
})
.option('slimPath', {
default: 'build.js'
})
.help('Deploy a script to Tessel and run it with Node');

makeCommand('push')
Expand All @@ -119,6 +126,13 @@ makeCommand('push')
abbr: 'v',
help: 'Choose to view more debugging information'
})
.option('slim', {
flag: true,
help: 'Bundle only the required modules'
})
.option('slimPath', {
default: 'build.js'
})
.help('Pushes the file/dir to Flash memory to be run anytime the Tessel is powered, runs the file immediately once the file is copied over');

makeCommand('erase')
Expand Down
185 changes: 147 additions & 38 deletions lib/tessel/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ var fs = require('fs');
var path = require('path');
var tar = require('tar');
var Ignore = require('fstream-ignore');
var browserify = require('browserify');
var uglify = require('uglify-js');
var glob = require('glob');

var PUSH_START_SCRIPT_NAME = 'start';
var NODE_PUSH_SCRIPT = __dirname + '/../../resources/start_node_script.sh';
Expand Down Expand Up @@ -133,10 +136,10 @@ Tessel.prototype.deployScript = function(opts) {
.then(function(script) {
if (isPush) {
// Push the script into flash
return actions.pushScript(self, script).then(resolve);
return actions.pushScript(self, script, opts).then(resolve);
} else {
// Push the code into ram
return actions.runScript(self, filepath, script).then(resolve);
return actions.runScript(self, filepath, script, opts).then(resolve);
}
});
})
Expand All @@ -158,7 +161,7 @@ Tessel.prototype.restartScript = function(opts) {
.then(resolve).catch(reject);
} else {
// Start the script in RAM
return actions.runScript(self, filepath, opts.entryPoint)
return actions.runScript(self, filepath, opts.entryPoint, opts)
.then(resolve).catch(reject);
}
})
Expand Down Expand Up @@ -276,7 +279,11 @@ actions.sendBundle = function(tessel, filepath, opts) {

tessel.receive(remoteProcess).then(function() {
logs.info('Deployed.');
resolve(project.entryPoint);
if (opts.slim) {
resolve(opts.slimPath);
} else {
resolve(project.entryPoint);
}
}).catch(reject);

// Write the code bundle to the hardware
Expand All @@ -289,49 +296,132 @@ actions.sendBundle = function(tessel, filepath, opts) {

actions.tarBundle = function(opts) {
var target = opts.target || process.cwd();
var pack = tar.Pack();
var buffers = [];

if (opts.slim) {
logs.info('Generating slim build.');
return new Promise(function(resolve, reject) {
actions.glob(target + '/**/*.tesselignore', {
dot: true
}, function(error, ignoreFiles) {
if (error) {
return reject(error);
}

return new Promise(function(resolve, reject) {
var buffers = [];
var pack = tar.Pack();
var fstream = new Ignore({
path: target,
ignoreFiles: ['.tesselignore']
});
var rules = ignoreFiles.reduce(function(rules, ignoreFile) {
var dirname = path.dirname(ignoreFile);
var patterns = fs.readFileSync(ignoreFile, 'utf8').trim().split('\n').map(function(pattern) {
return path.join(dirname, pattern).replace(process.cwd() + path.sep, '');
});

if (opts.single) {
fstream.addIgnoreRules(['*', '!' + opts.resolvedEntryPoint]);
}
return rules.concat(patterns);
}, []).map(function(rule) {

if (rule[rule.length - 1] === '/') {
rule += '**/*.*';
}

if (rule[rule.length - 1] !== '*' && rule.indexOf('.') === -1) {
rule += '/**/*.*';
}

fstream.basename = '';
pack._noProprietary = true;
return rule;
});

var exclusions = '{' + rules.join(',') + '}';

// This ensures that the remote root directory
// is the same level as the directory containing
// our program entry-point files.
fstream.on('entry', function(entry) {
entry.root = {
path: entry.path
};
var b = actions.browserify(opts.resolvedEntryPoint, {
builtins: false,
commondir: false,
browserField: false,
detectGlobals: false,
ignoreMissing: true
});

actions.glob.sync(exclusions).forEach(function(file) {
b.exclude(file);
});

b.bundle(function(error, results) {
if (error) {
return reject(error);
} else {
fs.writeFileSync(opts.slimPath, actions.compress(results));

var fstream = new Ignore({
path: target,
});

fstream.addIgnoreRules(['*', '!' + opts.slimPath]);

fstream.basename = '';
pack._noProprietary = true;

fstream.on('entry', function(entry) {
entry.root = {
path: entry.path
};
});

fstream.pipe(pack)
.on('data', function(chunk) {
buffers.push(chunk);
})
.on('error', function(data) {
reject(data);
})
.on('end', function() {
fs.unlinkSync(opts.slimPath);
resolve(Buffer.concat(buffers));
});
}
});
});
});
} else {

// Send the ignore-filtered file stream into the tar packer
fstream.pipe(pack)
.on('data', function(chunk) {
buffers.push(chunk);
})
.on('error', function(data) {
reject(data);
})
.on('end', function() {
resolve(Buffer.concat(buffers));
return new Promise(function(resolve, reject) {
var fstream = new Ignore({
path: target,
ignoreFiles: ['.tesselignore']
});
});

if (opts.single) {
fstream.addIgnoreRules(['*', '!' + opts.resolvedEntryPoint]);
}

fstream.basename = '';
pack._noProprietary = true;

// This ensures that the remote root directory
// is the same level as the directory containing
// our program entry-point files.
fstream.on('entry', function(entry) {
entry.root = {
path: entry.path
};
});

// Send the ignore-filtered file stream into the tar packer
fstream.pipe(pack)
.on('data', function(chunk) {
buffers.push(chunk);
})
.on('error', function(data) {
reject(data);
})
.on('end', function() {
resolve(Buffer.concat(buffers));
});
});
}
};

actions.runScript = function(t, filepath, entryPoint) {
actions.runScript = function(t, filepath, entryPoint, opts) {
logs.info('Running %s...', entryPoint);
return new Promise(function(resolve) {
return t.connection.exec(commands.runScript(filepath, entryPoint))
return t.connection.exec(commands.runScript(filepath, opts.slim ? opts.slimPath : entryPoint))
.then(function(remoteProcess) {

// When the stream closes
Expand All @@ -344,12 +434,12 @@ actions.runScript = function(t, filepath, entryPoint) {
});
};

actions.pushScript = function(t, entryPoint) {
actions.pushScript = function(t, entryPoint, opts) {
// Write the node start file
return actions.writeToFile(t)
.then(function start() {
// Then start the script
return actions.startPushedScript(t, entryPoint);
return actions.startPushedScript(t, opts.slim ? opts.slimPath : entryPoint);
});
};

Expand Down Expand Up @@ -400,6 +490,25 @@ actions.startPushedScript = function(tessel, entryPoint) {
});
};

// To make these operations testable, we must wrap them
// in our own exported `actions`.
actions.glob = function(pattern, options, callback) {
glob(pattern, options, callback);
};

actions.glob.sync = function(pattern, options) {
return glob.sync(pattern, options);
};

actions.browserify = function(entry, options) {
return browserify(entry, options);
};

actions.compress = function(source) {
return uglify.minify(source.toString(), {
fromString: true
}).code;
};

if (global.IS_TEST_ENV) {
module.exports = actions;
Expand Down
6 changes: 4 additions & 2 deletions lib/usb_connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ util.inherits(USB.Scanner, EventEmitter);

USB.Scanner.prototype.start = function() {
var self = this;
if (usb) {
if (haveusb) {
usb.getDeviceList().forEach(deviceInspector);

usb.on('attach', deviceInspector);
Expand All @@ -337,7 +337,9 @@ USB.Scanner.prototype.start = function() {
};

USB.Scanner.prototype.stop = function() {
usb.removeAllListeners('attach');
if (haveusb) {
usb.removeAllListeners('attach');
}
};

module.exports.startScan = startScan;
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@
"dependencies": {
"async": "^1.4.2",
"bluebird": "^2.9.6",
"browserify": "^11.2.0",
"colors": "^1.1.0",
"debug": "^2.2.0",
"envfile": "^1.0.0",
"fs-extra": "^0.18.0",
"fstream-ignore": "^1.0.2",
"glob": "^5.0.15",
"inquirer": "^0.8.5",
"keypress": "^0.2.1",
"lodash": "^3.5.0",
Expand All @@ -66,6 +68,8 @@
"stream-to-buffer": "^0.1.0",
"tar": "^2.1.1",
"tar-stream": "^1.2.1",
"uglify-js": "^2.5.0",
"uglifyify": "^3.0.1",
"url-join": "0.0.1",
"usb": "^1.0.5",
"usb-daemon-parser": "0.0.1"
Expand Down
17 changes: 6 additions & 11 deletions resources/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// Import the interface to Tessel hardware
var tessel = require('tessel');

// Set the led pins as outputs
var led1 = tessel.led[2];
var led2 = tessel.led[3];

// Set initial LED states
led1.output(1);
led2.output(0);
// Turn one of the LEDs on to start.
tessel.led[2].on();

// Blink!
setInterval(function () {
console.log("I'm blinking! (Press CTRL + C to stop)");
// Toggle the led states
led1.toggle();
led2.toggle();
console.log("I'm blinking! (Press CTRL + C to stop)");
tessel.led[2].toggle();
tessel.led[3].toggle();
}, 100);
Loading

0 comments on commit 55552c8

Please sign in to comment.