@domoinc/multiline
Version:
MultiLine - Domo Widget
474 lines (399 loc) • 14.5 kB
JavaScript
/*----------------------------------------------------------------------------------
Widget Grunt
© 2011 - 2015 DOMO, INC.
----------------------------------------------------------------------------------*/
var blue = '\x1B[0;36m';
var yellow = '\x1B[1;33m';
var noColor = '\x1B[0m';
var request = require('request');
var fs = require('fs');
var shell = require('shelljs');
var webpackConfig = require("./webpack.config.js");
module.exports = function(grunt) {
'use strict';
// Project configuration
grunt.initConfig({
// Metadata
bower: grunt.file.readJSON('bower.json'),
banner: '/*! <%= bower.name %> - v<%= bower.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> Domo */\n',
// Task configuration
portPick: {
livereload: {
options: {
port: 1337,
name: 'livereload'
},
targets: [
'watch.options.livereload',
'connect.options.livereload',
'connect.dist.options.livereload',
'connect.open.options.livereload'
]
},
server: {
options: {
port: 9000,
name: 'server'
},
targets: [
'connect.options.port',
'webpack-dev-server.options.port',
'port'
]
}
},
jshint: {
dev: {
options: {
force: true,
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
src: ['*.js', '!Gruntfile.js', '!Publish_Gruntfile.js']
},
dep: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
src: ['*.js', '!Gruntfile.js', '!Publish_Gruntfile.js']
}
},
watch: {
options: {
livereload: 0,
},
all: {
files: ['*.js'],
tasks: ['jshint:dev', 'webpack'],
options: {
spawn: true,
reload: true
}
},
},
connect: {
options: {
port: 0,
open: false,
// Change this to '0.0.0.0' to access the server from outside
hostname: '0.0.0.0'
},
dist: {
options: {
livereload: 0
}
},
open: {
options: {
livereload: 0,
open: true
}
}
},
init: {
dist: {
title: "<%= bower.name %>"
}
},
tmpChangeLogFileName: 'tmpCHANGELOG.md',
conventionalChangelog: {options:{}},
release: {
options: {
file: 'bower.json', //default: package.json
additionalFiles: ['package.json'],
beforeRelease: ['build', 'addBundle'],
npm: true, //default: true
npmtag: false, //default: no tag
tagName: 'v<%= version %>'
}
},
imageId:'widget',
port:9000,
clean: {
vendor: ['dist/vendor.bundle.js']
},
webpack: {
options: webpackConfig,
build: {}
},
'webpack-dev-server': {
options: {
webpack: webpackConfig,
publicPath: webpackConfig.output.publicPath,
port: 0,
open: true
},
start: {
keepAlive: true,
webpack: {
devtool: "eval",
debug: true
}
}
}
});
require('load-grunt-tasks')(grunt);
// Init
grunt.task.registerMultiTask('init', 'A task that creates a github repo.', function() {
shell.exec('git init');
grunt.log.write(blue + 'Ran init.\n' + noColor);
shell.exec('git add .');
grunt.log.write(blue + 'Added all files.\n' + noColor);
shell.exec('git commit -m "First Commit"');
grunt.log.write(blue + 'Local commit was run successfully.\n' + noColor);
grunt.log.write(blue + "Creating remote Repo: " + yellow + ('GITHUB_HOST=git.empdev.domo.com hub create DA/' + this.data.title) + noColor + "\n");
shell.exec('GITHUB_HOST=git.empdev.domo.com hub create DA/' + this.data.title);
grunt.log.write(blue + 'Created the repo!\n' + noColor);
shell.exec('git push origin master');
grunt.log.write(blue + 'Pushed to origin master\n' + noColor);
shell.exit(1);
grunt.log.write('Now run grunt deploy\n');
});
//Run Server
grunt.registerTask('default', ['jshint:dev', 'portPick:server', 'devWebpackConfig', 'webpack-dev-server']);
grunt.registerTask('server', ['jshint:dev', 'portPick:server', 'devWebpackConfig', 'webpack-dev-server']);
grunt.registerTask('build', ['jshint:dep', 'webpack']);
grunt.registerTask('addBundle', function() {
shell.exec('git add ' + webpackConfig.output.path + '/' + webpackConfig.output.filename);
});
grunt.registerTask('devWebpackConfig', function() {
webpackConfig.setDev();
});
/*----------------------------------------------------------------------------------
// RELEASE / GRUNT PUSH
----------------------------------------------------------------------------------*/
// Read the Change log into the release options
grunt.registerTask('readChangeLogIntoReleaseTask', function () {
var changeFile = grunt.file.read(grunt.config('tmpChangeLogFileName'));
grunt.config.set('release.options.changelogText', changeFile);
grunt.config.set('release.options.changelog', true);
shell.exec('rm ' + grunt.config('tmpChangeLogFileName'));
});
// Deploy to Github with tags
grunt.registerTask('push', function(release){
if (release) { release = release.toLowerCase(); }
var nextVersion = getConfigNextVersion(release);
grunt.config.set('conventionalChangelog.options.version', nextVersion);
grunt.config.set('conventionalChangelog.options.file', grunt.config('tmpChangeLogFileName'));
shell.exec('touch ' + grunt.config('tmpChangeLogFileName'));
shell.exec('touch CHANGELOG.md');
switch (release)
{
case 'patch':
grunt.task.run(['conventionalChangelog', 'readChangeLogIntoReleaseTask' , 'release:patch']);
break;
case 'minor':
grunt.task.run(['conventionalChangelog', 'readChangeLogIntoReleaseTask', 'release:minor']);
break;
case 'major':
grunt.task.run(['conventionalChangelog', 'readChangeLogIntoReleaseTask', 'release:major']);
break;
default :
console.log('Use one of the following commands to push');
console.log('grunt push:major');
console.log('grunt push:minor');
console.log('grunt push:patch');
break;
}
/*----------------------------------------------------------------------------------
// PUSH : Helper Functions
----------------------------------------------------------------------------------*/
/**
* Get the next bower version release string.
*/
function getConfigNextVersion (releaseType)
{
var versionObj = getBowerVersionInto();
return getNextVersionString(versionObj, releaseType);
}
/**
* Generate the next version string.
*/
function getNextVersionString (oldVersionObj, releaseType)
{
var nextVersionString = '';
switch (releaseType)
{
case 'patch':
nextVersionString = oldVersionObj[0] + '.' + oldVersionObj[1] + '.' + (oldVersionObj[2] + 1);
break;
case 'minor':
nextVersionString = oldVersionObj[0] + '.' + (oldVersionObj[1] + 1) + '.' + 0;
break;
case 'major':
nextVersionString = (oldVersionObj[0] + 1) + '.' + 0 + '.' + 0;
break;
}
return 'v' + nextVersionString;
}
/**
* returns the bower version number. [major, minor, patch]
*/
function getBowerVersionInto ()
{
var bower = grunt.config('bower');
var version = bower.version.split('.');
return version.map(function(d) {return Number(d);});
}
});
/*----------------------------------------------------------------------------------
// Doc Generation
----------------------------------------------------------------------------------*/
grunt.registerTask('writeDocFiles', function() {
var widgetName = grunt.config('bower').name;
var done = this.async();
shell.exec('phantomjs dev_scripts/getChartDefinitions.js '+grunt.config.get('port')+' '+widgetName, function(code, output) {
var obj = JSON.parse(output);
try {
fs.mkdirSync('docs');
} catch (err) {
//ignore
}
writeDescriptionDoc(widgetName);
writeConfigDoc(obj.config);
writeDataDefinitionDoc(obj.dataDefinition);
writeEventsDoc(widgetName);
writeExampleDoc();
done();
});
function writeConfigDoc(config) {
var fd = fs.openSync('docs/config.md', 'w');
var keys = Object.keys(config).sort();
fs.writeSync(fd, '## Configuration Options\n\n\n');
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
fs.writeSync(fd, '#### '+key+'\n');
fs.writeSync(fd, 'Type: `'+config[key].type+'` \n');
fs.writeSync(fd, 'Default: `'+JSON.stringify(config[key].value)+'` \n');
var units = config[key].units;
if (units) {
fs.writeSync(fd, 'Units: `'+units+'`\n\n');
} else {
fs.writeSync(fd, '\n');
}
fs.writeSync(fd, config[key].description+'\n\n');
}
fs.closeSync(fd);
}
function writeDataDefinitionDoc(dataDef) {
var fd = fs.openSync('docs/dataDef.md', 'w');
var keys = Object.keys(dataDef).sort();
fs.writeSync(fd, '## Data Definition\n\n\n');
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
fs.writeSync(fd, '#### '+key+'\n');
fs.writeSync(fd, 'Type: `'+dataDef[key].type+'`\n\n');
fs.writeSync(fd, 'Default validate: \n```js\n'+dataDef[key].validate+'\n```\n\n');
fs.writeSync(fd, 'Default accessor: \n```js\n'+dataDef[key].accessor+'\n```\n\n');
}
fs.closeSync(fd);
}
function writeEventsDoc(widgetName) {
var i =0;
var fd = fs.openSync('docs/events.md', 'w');
var code = fs.readFileSync('src/Widget.js', {encoding:'utf-8'});
var dispatch = code.match(/dispatch:[A-Za-z0-9]*/g);
var external = code.match(/external:[A-Za-z0-9]*/g);
fs.writeSync(fd, '## Events\n\n\n');
fs.writeSync(fd, '#### Dispatch Events\n\n');
if (dispatch) {
var dPrinted = [];
for (i=0; i<dispatch.length; i++) {
if (dPrinted.indexOf(dispatch[i]) ===-1) {
dPrinted.push(dispatch[i]);
fs.writeSync(fd, dispatch[i]+' \n');
}
}
}
fs.writeSync(fd, '#### External Events\n\n');
if (external) {
var ePrinted = [];
for (i=0; i<external.length; i++) {
if (ePrinted.indexOf(external[i]) ===-1) {
ePrinted.push(external[i]);
fs.writeSync(fd, external[i]+' \n');
}
}
}
fs.writeSync(fd, '\n');
fs.closeSync(fd);
}
function writeDescriptionDoc(widgetName) {
var images = grunt.file.expand('media/*.png');
var nImages = images.length;
var size = '500';
var configFile = 'publishConfig-'+widgetName+'.json';
var description = '';
if (grunt.file.exists(configFile)) {
description = grunt.file.readJSON(configFile).description
}
if (nImages == 2) {
size = '350';
} else if (nImages >= 3) {
size = '225'
}
var fd = fs.openSync('docs/description.md', 'w');
fs.writeSync(fd, '# '+widgetName+'\n\n');
fs.writeSync(fd, description+'\n\n');
for (var i = 0; i < images.length; i++) {
var img = images[i];
// fs.writeSync(fd, '<img src='+img+' height='+size+' width='+size+'> ');
}
fs.writeSync(fd, '\n\n');
fs.closeSync(fd);
}
function writeExampleDoc() {
var createWidget = fs.readFileSync('CreateWidget.js', {encoding:'utf-8'});
var fd = fs.openSync('docs/example.md', 'w');
fs.writeSync(fd, '## Example\n\n');
fs.writeSync(fd, '```js \n');
fs.writeSync(fd, createWidget);
fs.writeSync(fd, '\n```\n\n');
fs.closeSync(fd);
}
});
grunt.registerTask('compileReadMe', function(){
var desc = fs.readFileSync('docs/description.md', {encoding:'utf-8'});
var config = fs.readFileSync('docs/config.md', {encoding:'utf-8'});
var dataDef = fs.readFileSync('docs/dataDef.md', {encoding:'utf-8'});
var events = fs.readFileSync('docs/events.md', {encoding:'utf-8'});
var example = fs.readFileSync('docs/example.md', {encoding:'utf-8'});
var fd = fs.openSync('README.md', 'w');
fs.writeSync(fd, desc);
fs.writeSync(fd, config);
fs.writeSync(fd, dataDef);
fs.writeSync(fd, events);
fs.writeSync(fd, example);
fs.closeSync(fd);
});
grunt.registerTask('docGen', ['portPick:server', 'devWebpackConfig', 'webpack','connect:dist', 'writeDocFiles', 'compileReadMe', 'clean:vendor']);
/*----------------------------------------------------------------------------------
// Media Generation
----------------------------------------------------------------------------------*/
grunt.registerTask('writeMediaFiles', function() {
var done = this.async();
shell.exec('phantomjs dev_scripts/screencast.js '+grunt.config.get('port'), function(code, output) {
//Return code is the number of frames created
shell.cp('-f','media/widget_'+(code)+'.png', 'media/widget_0.png');
shell.cp('-f','media/widget_'+(code)+'.png', 'media/'+grunt.config.get('imageId')+'.png');
shell.exec('ffmpeg -y -framerate 25 -i media/widget_%d.png -c:v libx264 -vf "fps=25,format=yuv420p" media/'+grunt.config.get('imageId')+'.mp4');
shell.rm('-f', 'media/widget_*.png');
done();
});
});
grunt.registerTask('mediaGen',function(imageId) {
if (imageId) {
grunt.config.set('imageId', imageId);
}
grunt.task.run(['portPick:server', 'devWebpackConfig', 'webpack', 'connect:dist', 'writeMediaFiles', 'clean:vendor'])
});
/*----------------------------------------------------------------------------------
// Auto Widget Injection
----------------------------------------------------------------------------------*/
grunt.registerTask('autoInject', 'Injects AutoWidget.js dependency. Enables auto.html.', function () {
shell.exec('bower install DA/AutoWidgets#x');
});
};