Adding livereload, react-router base

This commit is contained in:
Jeffrey Morgan 2014-12-30 18:01:27 -05:00
parent 01e3521f92
commit be51f26065
10 changed files with 324 additions and 88 deletions

View File

@ -1,55 +0,0 @@
/** @jsx React.DOM */
var React = require('react');
var Store = require('./Store.js');
var actions = require('./actions.js');
var App = React.createClass({
getInitialState: function () {
return {
messages: Store.getMessages(),
newMessage: ''
};
},
componentWillMount: function () {
Store.addChangeListener(this.changeState);
},
componentWillUnmount: function () {
Store.removeChangeListener(this.changeState);
},
changeState: function () {
this.setState({
messages: Store.getMessages()
});
},
addMessage: function (event) {
event.preventDefault();
var input = this.refs.newMessage.getDOMNode();
actions.addMessage(input.value);
this.setState({
newMessage: ''
});
},
updateNewMessage: function (event) {
this.setState({
newMessage: event.target.value
});
},
renderMessages: function (message) {
return (
<div>{message}</div>
);
},
render: function() {
return (
<div>
{this.state.messages.map(this.renderMessages)}
<form onSubmit={this.addMessage}>
<input ref="newMessage" type="text" value={this.state.newMessage} onChange={this.updateNewMessage}/>
</form>
</div>
);
}
});
module.exports = App;

View File

@ -1,8 +0,0 @@
jest.dontMock('../sum');
describe('sum', function() {
it('adds 1 + 2 to equal 3', function() {
var sum = require('../sum');
expect(sum(1, 2)).toBe(3);
});
});

217
app/boot2docker.js Normal file
View File

@ -0,0 +1,217 @@
var exec = require('exec');
var path = require('path');
var fs = require('fs');
var path = require('path');
var async = require('async');
var cmdExec = function (cmd, callback) {
exec(cmd, function (stderr, stdout, code) {
console.log(stderr, stdout, code);
if (code) {
callback('Exit code ' + code + ': ' + stderr);
} else {
callback(null, stdout);
}
});
};
var homeDir = function () {
return process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
};
var Boot2Docker = {
version: function () {
var packagejson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
return packagejson['boot2docker-version'];
},
cliVersion: function (callback) {
cmdExec([Boot2Docker.command(), 'version'], function (err, out) {
console.log(err, out);
if (err) {
callback(err);
return;
}
var match = out.match(/version: v(\d+\.\d+\.\d+)/);
if (!match || match.length < 2) {
callback('Could not parse the boot2docker cli version.');
} else {
callback(null, match[1]);
}
});
},
isoVersion: function (callback) {
fs.readFile(path.join(homeDir(), '.boot2docker', 'boot2docker.iso'), 'utf8', function (err, data) {
if (err) {
callback(err);
return;
}
var match = data.match(/Boot2Docker-v(\d+\.\d+\.\d+)/);
if (!match) {
callback('Could not parse boot2docker iso version');
return;
}
callback (null, match[1]);
});
},
command: function () {
return path.join(process.cwd(), 'resources', 'boot2docker-' + this.version());
},
exists: function (callback) {
cmdExec([Boot2Docker.command(), 'info'], callback);
},
status: function (callback) {
cmdExec([Boot2Docker.command(), 'status'], function (err, out) {
console.log(err, out);
if (err) {
callback(err);
return;
}
callback(null, out.trim());
});
},
init: function (callback) {
cmdExec([Boot2Docker.command(), 'init'], callback);
},
start: function (callback) {
cmdExec([Boot2Docker.command(), 'start'], callback);
},
stop: function (callback) {
cmdExec([Boot2Docker.command(), 'stop'], callback);
},
upgrade: function (callback) {
cmdExec([Boot2Docker.command(), 'upgrade'], callback);
},
ip: function (callback) {
cmdExec([Boot2Docker.command(), 'ip'], callback);
},
erase: function (callback) {
var VMFileLocation = path.join(homeDir(), 'VirtualBox\\ VMs/boot2docker-vm');
cmdExec(['rm', '-rf', VMFileLocation], callback);
},
state: function (callback) {
cmdExec([Boot2Docker.command(), 'info'], function (err, out) {
if (err) {
callback(err);
return;
}
try {
var info = JSON.parse(out);
callback(null, info.State);
} catch (e) {
callback(e, null);
}
});
},
disk: function (callback) {
cmdExec([Boot2Docker.command(), 'ssh', 'df'], function (err, out) {
if (err) {
callback(err);
return;
}
try {
var lines = out.split('\n');
var dataline = _.find(lines, function (line) {
return line.indexOf('/dev/sda1') !== -1;
});
var tokens = dataline.split(' ');
tokens = tokens.filter(function (token) {
return token !== '';
});
var usedGb = parseInt(tokens[2], 10) / 1000000;
var totalGb = parseInt(tokens[3], 10) / 1000000;
var percent = parseInt(tokens[4].replace('%', ''), 10);
callback(null, {
used_gb: usedGb.toFixed(2),
total_gb: totalGb.toFixed(2),
percent: percent
});
} catch (error) {
callback(error, null);
}
});
},
memory: function (callback) {
cmdExec([Boot2Docker.command(), 'ssh', 'free -m'], function (err, out) {
if (err) {
callback(err);
return;
}
try {
var lines = out.split('\n');
var dataline = _.find(lines, function (line) {
return line.indexOf('-/+ buffers') !== -1;
});
var tokens = dataline.split(' ');
tokens = tokens.filter(function(token) {
return token !== '';
});
var usedGb = parseInt(tokens[2], 10) / 1000;
var freeGb = parseInt(tokens[3], 10) / 1000;
var totalGb = usedGb + freeGb;
var percent = Math.round(usedGb / totalGb * 100);
callback(null, {
used_gb: usedGb.toFixed(2),
total_gb: totalGb.toFixed(2),
free_gb: freeGb.toFixed(2),
percent: percent
});
} catch (error) {
callback(error);
}
});
},
stats: function (callback) {
var self = this;
self.state(function (err, state) {
if (err) {
callback(err);
return;
}
if (state === 'poweroff') {
callback(null, {state: state});
return;
}
self.memoryUsage(function (err, mem) {
if (err) {
callback(null, {state: state});
return;
}
self.diskUsage(function (err, disk) {
if (err) {
callback(null, {state: state, memory: mem});
return;
}
callback(null, {
state: state,
memory: mem,
disk: disk
});
});
});
});
},
sshKeyExists: function () {
return fs.existsSync(path.join(homeDir(), '.ssh', 'id_boot2docker'));
}
};
module.exports = Boot2Docker;
//TODO: move me to setup
Boot2Docker.waitWhileStatus = function (status, callback) {
var current = status;
async.whilst(function () {
return current === status;
}, function (callback) {
Boot2Docker.status(function (err, vmStatus) {
if (err) {
callback(err);
} else {
current = vmStatus.trim();
callback();
}
});
}, function (err) {
callback(err);
});
};

View File

@ -4,8 +4,9 @@
<link rel="stylesheet" href="main.css"/> <link rel="stylesheet" href="main.css"/>
</head> </head>
<body> <body>
<script src="main.js"></script>
<script src="https://cdn.ravenjs.com/1.1.15/jquery,native/raven.min.js"></script> <script src="https://cdn.ravenjs.com/1.1.15/jquery,native/raven.min.js"></script>
<script src="http://localhost:35729/livereload.js"></script>
<script> <script>
Raven.config('https://0a5f032d745d4acaae94ce46f762c586@app.getsentry.com/35057', { Raven.config('https://0a5f032d745d4acaae94ce46f762c586@app.getsentry.com/35057', {
// we highly recommend restricting exceptions to a domain in order to filter out clutter // we highly recommend restricting exceptions to a domain in order to filter out clutter

View File

@ -1,7 +1,82 @@
/** @jsx React.DOM */
var App = require('./App.js');
var React = require('react'); var React = require('react');
window.React = React; // export for dev tools var Router = require('react-router');
var Route = Router.Route;
var NotFoundRoute = Router.NotFoundRoute;
var DefaultRoute = Router.DefaultRoute;
var Link = Router.Link;
var RouteHandler = Router.RouteHandler;
React.render(<App/>, document.body); var boot2docker = require('./boot2docker.js');
var App = React.createClass({
render: function () {
return (
<RouteHandler/>
);
}
});
var Setup = React.createClass({
render: function () {
return (
<p>Hello!</p>
);
},
componentWillMount: function () {
},
setup: function () {
},
steps: [
]
});
var Containers = React.createClass({
render: function () {
return (
<div>
<ContainerList/>
<RouteHandler/>
</div>
);
}
});
var ContainerList = React.createClass({
render: function () {
return (
<ul>
<li>Container 1</li>
<li>Container 2</li>
<li>Container 3</li>
<li>Container 4</li>
<li>Container 5</li>
</ul>
);
}
});
var NoContainers = React.createClass({
render: function () {
return (
<p>No containers</p>
);
}
});
var routes = (
<Route name="app" path="/" handler={App}>
<DefaultRoute handler={Setup}/>
<Route name="containers" handler={Containers}>
<DefaultRoute handler={NoContainers}/>
</Route>
<Route name="setup" handler={Setup}>
</Route>
</Route>
);
Router.run(routes, function (Handler) {
React.render(<Handler/>, document.body);
});

View File

@ -1,5 +0,0 @@
// sum.js
function sum(value1, value2) {
return value1 + value2;
}
module.exports = sum;

View File

@ -22,8 +22,8 @@ app.on('activate-with-no-open-windows', function () {
app.on('ready', function() { app.on('ready', function() {
// Create the browser window. // Create the browser window.
var windowOptions = { var windowOptions = {
width: 800, width: 960,
height: 578, height: 640,
resizable: true, resizable: true,
frame: false, frame: false,
'web-preferences': { 'web-preferences': {

View File

@ -9,6 +9,7 @@ var streamify = require('gulp-streamify');
var notify = require('gulp-notify'); var notify = require('gulp-notify');
var concat = require('gulp-concat'); var concat = require('gulp-concat');
var less = require('gulp-less'); var less = require('gulp-less');
var livereload = require('gulp-livereload');
var cssmin = require('gulp-cssmin'); var cssmin = require('gulp-cssmin');
var imagemin = require('gulp-imagemin'); var imagemin = require('gulp-imagemin');
var gutil = require('gulp-util'); var gutil = require('gulp-util');
@ -35,6 +36,7 @@ gulp.task('js', function () {
entries: ['./app/main.js'], // Only need initial file, browserify finds the rest entries: ['./app/main.js'], // Only need initial file, browserify finds the rest
transform: [reactify], // We want to convert JSX to normal javascript transform: [reactify], // We want to convert JSX to normal javascript
debug: options.dev, // Gives us sourcemapping debug: options.dev, // Gives us sourcemapping
ignoreMissing: true,
cache: {}, packageCache: {}, fullPaths: options.dev // Requirement of watchify cache: {}, packageCache: {}, fullPaths: options.dev // Requirement of watchify
}); });
@ -43,12 +45,15 @@ gulp.task('js', function () {
bundler.external(dep); bundler.external(dep);
}); });
bundler.external('./app');
var bundle = function () { var bundle = function () {
return bundler.bundle() return bundler.bundle()
.on('error', gutil.log) .on('error', gutil.log)
.pipe(source('main.js')) .pipe(source('main.js'))
.pipe(gulpif(!options.dev, streamify(uglify()))) .pipe(gulpif(!options.dev, streamify(uglify())))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build')); .pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
}; };
if (options.dev) { if (options.dev) {
@ -88,7 +93,8 @@ gulp.task('images', function() {
interlaced: true, interlaced: true,
svgoPlugins: [{removeViewBox: false}] svgoPlugins: [{removeViewBox: false}]
})) }))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build')); .pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
}); });
gulp.task('styles', function () { gulp.task('styles', function () {
@ -99,7 +105,8 @@ gulp.task('styles', function () {
.pipe(gulpif(options.dev, sourcemaps.write())) .pipe(gulpif(options.dev, sourcemaps.write()))
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build')) .pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulpif(!options.dev, cssmin())) .pipe(gulpif(!options.dev, cssmin()))
.pipe(concat('main.css')); .pipe(concat('main.css'))
.pipe(gulpif(options.dev, livereload()));
}); });
gulp.task('download', function (cb) { gulp.task('download', function (cb) {
@ -111,7 +118,8 @@ gulp.task('download', function (cb) {
gulp.task('copy', function () { gulp.task('copy', function () {
gulp.src('./app/index.html') gulp.src('./app/index.html')
.pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build')); .pipe(gulp.dest(options.dev ? './build' : './dist/osx/' + options.filename + '/Contents/Resources/app/build'))
.pipe(gulpif(options.dev, livereload()));
}); });
gulp.task('dist', function (cb) { gulp.task('dist', function (cb) {
@ -178,10 +186,12 @@ gulp.task('default', ['download', 'copy', 'js', 'images', 'styles'], function ()
gulp.watch('./app/images/**', ['images']); gulp.watch('./app/images/**', ['images']);
gulp.watch('./app/styles/**/*.less', ['styles']); gulp.watch('./app/styles/**/*.less', ['styles']);
livereload.listen();
var env = process.env;
env.NODE_ENV = 'development';
gulp.src('').pipe(shell(['./cache/Atom.app/Contents/MacOS/Atom .'], { gulp.src('').pipe(shell(['./cache/Atom.app/Contents/MacOS/Atom .'], {
env: { env: env
NODE_ENV: 'development'
}
})); }));
}); });

View File

@ -20,12 +20,12 @@
} }
], ],
"boot2docker-version": "1.3.2", "boot2docker-version": "1.3.2",
"atom-shell-version": "0.19.1", "atom-shell-version": "0.20.3",
"dependencies": { "dependencies": {
"ansi-to-html": "0.2.0", "ansi-to-html": "0.2.0",
"async": "^0.9.0", "async": "^0.9.0",
"dockerode": "2.0.4", "dockerode": "2.0.4",
"exec": "^0.1.2", "exec": "0.1.2",
"flux-react": "^2.6.1", "flux-react": "^2.6.1",
"leveldown": "^1.0.0", "leveldown": "^1.0.0",
"levelup": "git+https://github.com/kitematic/node-levelup.git", "levelup": "git+https://github.com/kitematic/node-levelup.git",

View File

@ -8,14 +8,15 @@ export NODE="$BASE/cache/node-v$NODE_VERSION/bin/node"
export PATH="$BASE/cache/node-v$NODE_VERSION/bin/:$BASE/node_modules/.bin:$PATH" export PATH="$BASE/cache/node-v$NODE_VERSION/bin/:$BASE/node_modules/.bin:$PATH"
export NODE_PATH="$BASE/node_modules" export NODE_PATH="$BASE/node_modules"
pushd $BASE > /dev/null mkdir -p $BASE/cache
mkdir -p cache
cd cache pushd $BASE/cache > /dev/null
if [ ! -f "$NODE" ]; then if [ ! -f "$NODE" ]; then
curl -L -o node-v$NODE_VERSION-darwin-x64.tar.gz http://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz curl -L -o node-v$NODE_VERSION-darwin-x64.tar.gz http://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-darwin-x64.tar.gz
mkdir -p node-v$NODE_VERSION mkdir -p node-v$NODE_VERSION
tar -xzf node-v$NODE_VERSION-darwin-x64.tar.gz --strip-components 1 -C node-v$NODE_VERSION tar -xzf node-v$NODE_VERSION-darwin-x64.tar.gz --strip-components 1 -C node-v$NODE_VERSION
rm -rf node-v$NODE_VERSION-darwin-x64.tar.gz
fi fi
popd > /dev/null popd > /dev/null