Skip to content

Commit

Permalink
Initial working version
Browse files Browse the repository at this point in the history
  • Loading branch information
bergie committed Apr 30, 2014
1 parent dee0f92 commit 3d42b0e
Show file tree
Hide file tree
Showing 14 changed files with 14,427 additions and 20 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
/node_modules/
npm-debug.log
/tmp/
/test/fixtures/components/*/
13 changes: 13 additions & 0 deletions .jshintrc
@@ -0,0 +1,13 @@
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"boss": true,
"eqnull": true,
"node": true
}
8 changes: 8 additions & 0 deletions .travis.yml
@@ -0,0 +1,8 @@
language: node_js
node_js:
- "0.10"

before_script:
- npm install -g grunt-cli

script: grunt test
32 changes: 15 additions & 17 deletions Gruntfile.js
Expand Up @@ -25,27 +25,24 @@ module.exports = function(grunt) {

// Before generating any new files, remove any previously-created files.
clean: {
tests: ['tmp'],
tests: ['tmp', 'test/fixtures/components/*/'],
},

noflo_manifest: {
update: {
files: {
'test/fixtures/component.json': ['test/fixtures/components/*', 'test/fixtures/graphs/*']
}
}
},

// Configuration to be run (and then tested).
noflo_browser: {
default_options: {
options: {
},
build: {
files: {
'tmp/default_options': ['test/fixtures/testing', 'test/fixtures/123'],
},
},
custom_options: {
options: {
separator: ': ',
punctuation: ' !!!',
},
files: {
'tmp/custom_options': ['test/fixtures/testing', 'test/fixtures/123'],
},
},
'tmp/noflo.js': ['test/fixtures/component.json']
}
}
},

// Unit tests.
Expand All @@ -59,13 +56,14 @@ module.exports = function(grunt) {
grunt.loadTasks('tasks');

// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-noflo-manifest');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-nodeunit');

// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.registerTask('test', ['clean', 'noflo_browser', 'nodeunit']);
grunt.registerTask('test', ['clean', 'noflo_manifest', 'noflo_browser', 'nodeunit']);

// By default, lint and run all tests.
grunt.registerTask('default', ['jshint', 'test']);
Expand Down
10 changes: 7 additions & 3 deletions package.json
Expand Up @@ -31,7 +31,8 @@
"grunt-contrib-jshint": "^0.9.2",
"grunt-contrib-clean": "^0.5.0",
"grunt-contrib-nodeunit": "^0.3.3",
"grunt": "~0.4.1"
"grunt": "~0.4.1",
"grunt-noflo-manifest": "^0.1.4"
},
"peerDependencies": {
"grunt": "~0.4.1"
Expand All @@ -40,7 +41,10 @@
"gruntplugin"
],
"dependencies": {
"component-builder": "^1.1.5",
"builder-coffee-script": "^0.1.1"
"component-builder": "0.10.x",
"component-installer": "0.0.8",
"component-json": "git://github.com/bergie/component-json.git",
"component-coffee": "^0.1.4",
"component-fbp": "^0.1.0"
}
}
164 changes: 164 additions & 0 deletions tasks/noflo_browser.js
@@ -0,0 +1,164 @@
/*
* grunt-noflo-browser
* https://github.com/noflo/grunt-noflo-browser
*
* Copyright (c) 2014 Henri Bergius
* Licensed under the MIT license.
*/

'use strict';

var Installer = require('component-installer');
var Builder = require('component-builder');
var path = require('path');

module.exports = function(grunt) {

grunt.registerMultiTask('noflo_browser', 'Grunt plugin for building NoFlo projects for the browser', function() {
var options = this.options({
require: true,
development: false,
plugins: [
'component-json',
'component-coffee',
'component-fbp'
],
remotes: [
'https://raw.githubusercontent.com'
]
});

// Force task to async mode
var done = this.async();
var todo = 0;

var graphFileTemplate = grunt.file.read(path.resolve(__dirname, '../templates/graph.html'));
var writeGraphFiles = function (manifest, srcDir, destDir, destPath) {
if (!manifest.noflo || !manifest.noflo.graphs) {
return;
}
Object.keys(manifest.noflo.graphs).forEach(function (graphName) {
var graph = grunt.file.readJSON(path.resolve(srcDir, manifest.noflo.graphs[graphName]));
if (!graph.properties.environment || !graph.properties.environment.type || graph.properties.environment.type !== 'noflo-browser') {
return;
}

if (!graph.properties.environment.content) {
return;
}
var templated = grunt.template.process(graphFileTemplate, {
data: {
name: graphName,
lib: manifest.name,
noflo: destPath,
graphPath: manifest.name + '/' + manifest.noflo.graphs[graphName],
content: graph.properties.environment.content
}
});
var demoFile = path.resolve(destDir, graphName + '.html');
grunt.file.write(demoFile, templated);
grunt.log.writeln('Demo file "' + demoFile + '" built');
});
};

// Iterate over all specified file groups.
this.files.forEach(function(f) {
var src = f.src.filter(function(filepath) {
// Warn on and remove invalid source files (if nonull was set).
if (!grunt.file.exists(filepath)) {
grunt.log.warn('Source file "' + filepath + '" not found.');
return false;
} else {
return true;
}
}).forEach(function (manifestPath) {
todo++;
var manifestDir = path.resolve(process.cwd(), path.dirname(manifestPath));

var installer = new Installer(manifestDir);
installer.destination(path.resolve(manifestDir, 'components/'));

options.remotes.forEach(function (remote) {
installer.remote(remote);
});

if (options.development) {
installer.development();
}

installer.on('package', function (pkg) {
if (pkg.inFlight) {
return;
}
grunt.log.writeln('install ' + pkg.slug);

pkg.on('error', function (err){
if (err.fatal) {
grunt.fail.warn(err);
return;
}
grunt.log.error(err);
});

pkg.on('exists', function (dep){
grunt.verbose.writeln('exists ' + dep.slug);
});

pkg.on('end', function() {
grunt.log.writeln(pkg.name + ' complete');
});
});

installer.install(function (err) {
if (err) {
grunt.fail.warn(err);
return;
}

var builder = new Builder(manifestDir);

// Load plugins
options.plugins.forEach(function (plugin) {
builder.use(require(plugin));
});

if (options.development) {
builder.development();
builder.addSourceURLs();
}

builder.build(function (err, obj) {
if (err) {
grunt.fail.warn(err);
return;
}

var js = '';

if (options.require) {
js += obj.require;
}

js += obj.js;

// Cleanup
js = js.replace(/\.coffee(\'|\")/g, '.js$1');

// Write the destination file.
grunt.file.write(f.dest, js);

// Print a success message.
grunt.log.writeln('File "' + f.dest + '" built.');

writeGraphFiles(grunt.file.readJSON(manifestPath), manifestDir, path.resolve(process.cwd(), path.dirname(f.dest)), path.basename(f.dest));

todo--;
if (todo === 0) {
done();
}
});
});
});
});
});
};
20 changes: 20 additions & 0 deletions templates/graph.html
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= name %></title>
<script src="<%= noflo %>"></script>
</head>
<body>
<%= content %>
<script>
var noflo = require('noflo');
noflo.graph.loadJSON(require('<%= graphPath %>'), function (graph) {
graph.baseDir = '/<%= lib %>';
noflo.createNetwork(graph, function (network) {
console.log('<%= name %> is running!');
});
});
</script>
</body>
</html>
20 changes: 20 additions & 0 deletions test/expected/Clock.html
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Clock</title>
<script src="noflo.js"></script>
</head>
<body>
<div class='area' title='.area'><img id='clock' src='http://i.meemoo.me/v1/in/GJPUFPc8ThuRp9itdXC9_clock-face.png' style='position:absolute; width:300px; height:300px;' /><img id='hours' src='http://i.meemoo.me/v1/in/fRL213GT1uCRltIqXkK2_clock-hours.png' style='position:absolute; top:50px; left:130px; height:200px;' /><img id='minutes' src='http://i.meemoo.me/v1/in/23DZFKYoRTOIAjPA7sed_clock-minutes.png' style='position:absolute; top:0; left:140px; height:300px;' /><img id='seconds' src='http://i.meemoo.me/v1/in/VU2HqPmuTqucRpnUGGBj_clock-seconds.png' style='position:absolute; top:0; left:145px; height:300px;' /></div>
<script>
var noflo = require('noflo');
noflo.graph.loadJSON(require('bar/graphs/Clock.json'), function (graph) {
graph.baseDir = '/bar';
noflo.createNetwork(graph, function (network) {
console.log('Clock is running!');
});
});
</script>
</body>
</html>

0 comments on commit 3d42b0e

Please sign in to comment.