2016-11-24 19:49:25 +03:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2016 Kam Low
|
|
|
|
*
|
|
|
|
* @license MIT
|
|
|
|
**/
|
|
|
|
|
|
|
|
var fs = require('fs'),
|
|
|
|
path = require('path'),
|
2017-01-31 21:50:14 +03:00
|
|
|
Promise = require('bluebird'),
|
|
|
|
tmp = require('tmp'),
|
2016-11-24 19:49:25 +03:00
|
|
|
grunt = require('grunt'),
|
|
|
|
package = require('./package'),
|
2017-08-01 15:48:54 +03:00
|
|
|
_ = require('lodash')
|
2016-11-24 21:26:43 +03:00
|
|
|
|
|
|
|
|
2017-01-31 21:50:14 +03:00
|
|
|
// Ensures temporary files are cleaned up on program close, even if errors are encountered.
|
2017-08-01 15:48:54 +03:00
|
|
|
tmp.setGracefulCleanup()
|
2017-01-31 21:50:14 +03:00
|
|
|
|
|
|
|
var defaults = {
|
2018-03-15 17:11:21 +03:00
|
|
|
quiet: false,
|
2017-01-31 21:50:14 +03:00
|
|
|
port: 4400,
|
2018-03-23 14:16:19 +03:00
|
|
|
portLive: 4401,
|
2017-01-31 21:50:14 +03:00
|
|
|
targetDir: path.resolve(process.cwd(), 'public'),
|
|
|
|
targetFile: 'index.html',
|
|
|
|
appDir: path.resolve(__dirname, 'app'),
|
|
|
|
configFile: path.resolve(__dirname, 'app/lib/config.js'),
|
2018-04-12 21:40:50 +03:00
|
|
|
cacheDir: tmp.dirSync({ unsafeCleanup: true, prefix: 'spectacle-' }).name,
|
|
|
|
oneFile: false
|
2018-07-02 03:25:14 +03:00
|
|
|
}
|
|
|
|
|
2017-01-31 21:50:14 +03:00
|
|
|
function resolveOptions(options) {
|
2017-08-01 15:48:54 +03:00
|
|
|
var opts = _.extend({}, defaults, options)
|
2017-01-31 21:50:14 +03:00
|
|
|
|
|
|
|
// Replace some absolute paths
|
|
|
|
if (opts.specFile && opts.specFile.indexOf('test/fixtures') === 0)
|
2017-08-01 15:48:54 +03:00
|
|
|
opts.specFile = path.resolve(__dirname, opts.specFile)
|
2017-01-31 21:50:14 +03:00
|
|
|
if (opts.logoFile && opts.logoFile.indexOf('test/fixtures') === 0)
|
2017-08-01 15:48:54 +03:00
|
|
|
opts.logoFile = path.resolve(__dirname, opts.logoFile)
|
2018-10-19 07:35:59 +03:00
|
|
|
if (opts.appDir && opts.appDir.indexOf('/') !== 0)
|
|
|
|
opts.appDir = path.resolve(__dirname, opts.appDir)
|
|
|
|
|
2017-01-31 21:50:14 +03:00
|
|
|
|
2018-07-02 03:25:14 +03:00
|
|
|
return opts
|
2017-01-31 21:50:14 +03:00
|
|
|
}
|
|
|
|
|
2016-11-24 19:49:25 +03:00
|
|
|
/**
|
|
|
|
* Run Spectacle and configured tasks
|
|
|
|
**/
|
|
|
|
module.exports = function (options) {
|
2017-08-01 15:48:54 +03:00
|
|
|
var opts = resolveOptions(options)
|
2016-11-24 19:49:25 +03:00
|
|
|
|
|
|
|
//
|
2016-12-11 17:43:02 +03:00
|
|
|
//= Load the specification and init configuration
|
2016-11-24 19:49:25 +03:00
|
|
|
|
2016-12-11 17:43:02 +03:00
|
|
|
function loadData() {
|
2017-08-01 15:48:54 +03:00
|
|
|
var specPath = path.resolve(opts.specFile)
|
2018-07-02 03:25:14 +03:00
|
|
|
delete require.cache[specPath]
|
|
|
|
var specData = require(opts.appDir + '/lib/resolve-references.js').fetchReference(specPath)
|
|
|
|
return require(path.resolve(opts.appDir + '/lib/preprocessor'))(options, specData)
|
2016-12-11 17:43:02 +03:00
|
|
|
}
|
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
var config = require(path.resolve(opts.configFile))(grunt, opts, loadData())
|
2016-11-24 19:49:25 +03:00
|
|
|
|
|
|
|
//
|
|
|
|
//= Setup Grunt to do the heavy lifting
|
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.initConfig(_.merge({ pkg: package }, config))
|
2018-03-15 17:11:21 +03:00
|
|
|
if(opts.quiet) {
|
2017-01-31 21:50:14 +03:00
|
|
|
grunt.log.writeln = function() {}
|
|
|
|
grunt.log.write = function() {}
|
|
|
|
grunt.log.header = function() {}
|
|
|
|
grunt.log.ok = function() {}
|
|
|
|
}
|
2016-11-24 19:49:25 +03:00
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
var cwd = process.cwd() // change CWD for loadNpmTasks global install
|
2016-11-24 21:26:43 +03:00
|
|
|
var exists = grunt.file.exists(path.join(path.resolve('node_modules'),
|
|
|
|
'grunt-contrib-concat',
|
2017-08-01 15:48:54 +03:00
|
|
|
'package.json'))
|
2016-11-24 21:26:43 +03:00
|
|
|
if (!exists)
|
2017-08-01 15:48:54 +03:00
|
|
|
process.chdir(__dirname)
|
2016-11-24 21:26:43 +03:00
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.loadNpmTasks('grunt-contrib-concat')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-uglify')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-cssmin')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-watch')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-clean')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-copy')
|
|
|
|
grunt.loadNpmTasks('grunt-contrib-connect')
|
|
|
|
grunt.loadNpmTasks('grunt-compile-handlebars')
|
|
|
|
grunt.loadNpmTasks('grunt-prettify')
|
|
|
|
grunt.loadNpmTasks('grunt-sass')
|
2018-04-12 21:40:50 +03:00
|
|
|
grunt.loadNpmTasks('grunt-embed')
|
2016-11-24 21:26:43 +03:00
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
process.chdir(cwd)
|
2016-11-24 19:49:25 +03:00
|
|
|
|
|
|
|
grunt.registerTask('predentation', 'Remove indentation from generated <pre> tags.', function() {
|
2017-08-01 15:48:54 +03:00
|
|
|
var html = fs.readFileSync(opts.cacheDir + '/' + opts.targetFile, 'utf8')
|
2016-11-24 19:49:25 +03:00
|
|
|
html = html.replace(/<pre.*?><code.*?>([\s\S]*?)<\/code><\/pre>/gmi, function(x, y) {
|
|
|
|
var lines = x.split('\n'), level = null;
|
|
|
|
if (lines) {
|
|
|
|
|
|
|
|
// Determine the level of indentation
|
|
|
|
lines.forEach(function(line) {
|
|
|
|
if (line[0] === '<') return;
|
2017-08-01 15:48:54 +03:00
|
|
|
var wsp = line.search(/\S/)
|
2016-11-24 19:49:25 +03:00
|
|
|
level = (level === null || (wsp < line.length && wsp < level)) ? wsp : level;
|
2017-08-01 15:48:54 +03:00
|
|
|
})
|
2016-11-24 19:49:25 +03:00
|
|
|
|
|
|
|
// Remove indentation
|
2017-08-01 15:48:54 +03:00
|
|
|
var regex = new RegExp('^\\s{' + level + '}')
|
2016-11-24 19:49:25 +03:00
|
|
|
lines.forEach(function(line, index, lines) {
|
2017-08-01 15:48:54 +03:00
|
|
|
lines[index] = line.replace(regex, '')
|
|
|
|
})
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
2017-08-01 15:48:54 +03:00
|
|
|
return lines.join('\n')
|
|
|
|
})
|
|
|
|
fs.writeFileSync(opts.cacheDir + '/' + opts.targetFile, html)
|
|
|
|
})
|
|
|
|
|
|
|
|
grunt.registerTask('stylesheets', ['sass:scss', 'concat:css', 'cssmin'])
|
|
|
|
grunt.registerTask('javascripts', ['concat:js', 'uglify'])
|
|
|
|
grunt.registerTask('templates', ['clean:html', 'compile-handlebars', 'predentation', 'prettify'])
|
|
|
|
grunt.registerTask('foundation', ['sass:foundation_scss', 'concat:foundation_css']) // 'concat:foundation_js'
|
|
|
|
grunt.registerTask('default', ['stylesheets', 'javascripts', 'foundation', 'templates'])
|
|
|
|
grunt.registerTask('server', ['connect'])
|
|
|
|
grunt.registerTask('develop', ['server', 'watch'])
|
2016-11-24 19:49:25 +03:00
|
|
|
|
2016-12-11 17:43:02 +03:00
|
|
|
// Reload template data when watch files change
|
2018-03-23 17:04:54 +03:00
|
|
|
grunt.event.on('watch', function() {
|
|
|
|
try {
|
|
|
|
grunt.config.set('compile-handlebars.compile.templateData', loadData())
|
|
|
|
} catch (e) {
|
|
|
|
grunt.fatal(e);
|
|
|
|
}
|
2017-08-01 15:48:54 +03:00
|
|
|
})
|
2016-12-11 17:43:02 +03:00
|
|
|
|
2016-11-24 19:49:25 +03:00
|
|
|
// Report, etc when all tasks have completed.
|
2017-01-31 21:50:14 +03:00
|
|
|
var donePromise = new Promise(function(resolve, reject) {
|
|
|
|
grunt.task.options({
|
|
|
|
error: function(e) {
|
2018-03-15 17:11:21 +03:00
|
|
|
if(!opts.quiet) {
|
2017-08-01 15:48:54 +03:00
|
|
|
console.warn('Task error:', e)
|
2017-01-31 21:50:14 +03:00
|
|
|
}
|
|
|
|
// TODO: fail here or push on?
|
2017-08-01 15:48:54 +03:00
|
|
|
reject(e)
|
2017-01-31 21:50:14 +03:00
|
|
|
},
|
|
|
|
done: function() {
|
2018-03-15 17:11:21 +03:00
|
|
|
if(!opts.quiet) {
|
2017-08-01 15:48:54 +03:00
|
|
|
console.log('All tasks complete')
|
2017-01-31 21:50:14 +03:00
|
|
|
}
|
2017-08-01 15:48:54 +03:00
|
|
|
resolve()
|
2017-01-31 21:50:14 +03:00
|
|
|
}
|
2017-08-01 15:48:54 +03:00
|
|
|
})
|
|
|
|
})
|
2016-11-24 19:49:25 +03:00
|
|
|
|
2016-12-11 17:43:02 +03:00
|
|
|
|
2016-11-24 19:49:25 +03:00
|
|
|
//
|
|
|
|
//= Run the shiz
|
|
|
|
|
2017-01-31 21:50:14 +03:00
|
|
|
if (opts.startServer) {
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run('server')
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
|
|
|
else {
|
2017-01-31 21:50:14 +03:00
|
|
|
if (!opts.disableCss) {
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run(['foundation', 'stylesheets'])
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
2017-01-31 21:50:14 +03:00
|
|
|
if (!opts.disableJs) {
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run('javascripts')
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
2017-01-31 21:50:14 +03:00
|
|
|
if (opts.logoFile) {
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run('copy:logo')
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run('templates')
|
2018-03-23 14:16:19 +03:00
|
|
|
if (opts.developmentMode || opts.developmentModeLive) {
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.run('develop')
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
2018-04-12 21:40:50 +03:00
|
|
|
if (opts.oneFile) {
|
|
|
|
grunt.task.run('embed')
|
|
|
|
}
|
2016-11-24 19:49:25 +03:00
|
|
|
}
|
|
|
|
|
2017-08-01 15:48:54 +03:00
|
|
|
grunt.task.start()
|
2017-01-31 21:50:14 +03:00
|
|
|
|
|
|
|
return donePromise;
|
2016-11-24 19:49:25 +03:00
|
|
|
};
|