2013-12-06 05:24:25 -05:00
// # Gruntfile - Task automation for Ghost
// Run various tasks when developing for and working with Ghost
// Run `grunt --help` or visit https://github.com/TryGhost/Ghost/wiki/Grunt-Toolkit/ for usage instructions
2013-09-24 05:46:30 -05:00
var path = require ( 'path' ) ,
when = require ( 'when' ) ,
semver = require ( 'semver' ) ,
fs = require ( 'fs' ) ,
2014-02-05 03:40:30 -05:00
_ = require ( 'lodash' ) ,
2013-10-25 00:58:58 -05:00
spawn = require ( 'child_process' ) . spawn ,
2013-07-01 16:24:59 -05:00
buildDirectory = path . resolve ( process . cwd ( ) , '.build' ) ,
2013-09-24 05:46:30 -05:00
distDirectory = path . resolve ( process . cwd ( ) , '.dist' ) ,
2014-01-05 01:40:53 -05:00
bootstrap = require ( './core/bootstrap' ) ,
2013-09-13 02:24:28 -05:00
2013-12-06 05:24:25 -05:00
// ## Build File Patterns
// a list of files and paterns to process and exclude when running builds & releases
2014-02-21 22:16:07 -05:00
// It is taken from the .npmignore file and all patterns are inverted as the .npmignore
// file defines what to ignore, whereas we want to define what to include.
buildGlob = ( function ( ) {
/*jslint stupid:true */
return fs . readFileSync ( '.npmignore' , { encoding : 'utf8' } ) . split ( '\n' ) . map ( function ( pattern ) {
if ( pattern [ 0 ] === '!' ) {
return pattern . substr ( 1 ) ;
}
return '!' + pattern ;
} ) ;
} ( ) ) ,
2013-09-18 13:45:21 -05:00
2013-12-06 05:24:25 -05:00
// ## Grunt configuration
2013-06-25 06:43:15 -05:00
configureGrunt = function ( grunt ) {
2013-08-17 13:39:02 -05:00
// load all grunt tasks
2014-02-18 22:41:21 -05:00
require ( 'matchdep' ) . filterDev ( [ 'grunt-*' , '!grunt-cli' ] ) . forEach ( grunt . loadNpmTasks ) ;
2013-08-17 13:39:02 -05:00
2013-06-25 06:43:15 -05:00
var cfg = {
// Common paths to be used by tasks
paths : {
2014-02-26 18:15:31 -05:00
// adminAssets: './core/client/', ?? who knows...
adminOldAssets : './core/clientold/assets' ,
2013-06-25 06:43:15 -05:00
build : buildDirectory ,
2013-11-01 10:33:49 -05:00
releaseBuild : path . join ( buildDirectory , 'release' ) ,
2013-06-25 06:43:15 -05:00
dist : distDirectory ,
2013-10-11 10:31:47 -05:00
releaseDist : path . join ( distDirectory , 'release' )
2013-06-25 06:43:15 -05:00
} ,
2013-07-11 09:24:33 -05:00
buildType : 'Build' ,
2013-06-25 06:43:15 -05:00
pkg : grunt . file . readJSON ( 'package.json' ) ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-watch
2013-08-17 13:39:02 -05:00
// Watch files and livereload in the browser during development
watch : {
handlebars : {
2014-02-26 18:15:31 -05:00
files : [ 'core/clientold/tpl/**/*.hbs' ] ,
2013-08-17 13:39:02 -05:00
tasks : [ 'handlebars' ]
} ,
2014-02-25 23:58:00 -05:00
emberTemplates : {
files : 'core/client/templates/**/*.hbs' ,
tasks : [ 'emberTemplates' ]
} ,
2014-02-26 23:45:45 -05:00
ember : {
files : [
'core/client/**/*.js'
] ,
tasks : [ 'transpile' , 'concat_sourcemap' ]
} ,
2013-08-17 13:39:02 -05:00
sass : {
2014-02-26 18:15:31 -05:00
files : [ '<%= paths.adminOldAssets %>/sass/**/*' ] ,
2013-08-17 13:39:02 -05:00
tasks : [ 'sass:admin' ]
} ,
2013-09-13 21:15:30 -05:00
concat : {
files : [
2014-02-26 18:15:31 -05:00
'core/clientold/*.js' ,
'core/clientold/helpers/*.js' ,
'core/clientold/models/*.js' ,
'core/clientold/tpl/*.js' ,
'core/clientold/views/*.js'
2013-09-13 21:15:30 -05:00
] ,
tasks : [ 'concat' ]
} ,
2013-08-17 13:39:02 -05:00
livereload : {
files : [
// Theme CSS
'content/themes/casper/css/*.css' ,
// Theme JS
'content/themes/casper/js/*.js' ,
// Admin CSS
2014-02-26 18:15:31 -05:00
'<%= paths.adminOldAssets %>/css/*.css' ,
2013-08-17 13:39:02 -05:00
// Admin JS
2013-09-13 21:15:30 -05:00
'core/built/scripts/*.js'
2013-08-17 13:39:02 -05:00
] ,
options : {
livereload : true
}
} ,
express : {
2014-02-26 18:15:31 -05:00
// Restart any time clientold or server js files change
2013-10-23 15:58:28 -05:00
files : [ 'core/server.js' , 'core/server/**/*.js' ] ,
2013-08-17 13:39:02 -05:00
tasks : [ 'express:dev' ] ,
options : {
//Without this option specified express won't be reloaded
nospawn : true
}
}
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-express-server
2013-08-17 13:39:02 -05:00
// Start our server in development
express : {
options : {
2013-12-04 15:20:16 -05:00
script : 'index.js' ,
output : 'Ghost is running'
2013-08-17 13:39:02 -05:00
} ,
dev : {
options : {
2013-10-25 00:58:58 -05:00
//output: 'Express server listening on address:.*$'
2013-08-17 13:39:02 -05:00
}
2013-08-29 05:04:33 -05:00
} ,
test : {
options : {
node _env : 'testing'
}
2013-08-17 13:39:02 -05:00
}
} ,
2014-02-26 21:44:09 -05:00
// ### Config for grunt-contrib-jshint
// JSHint all the things!
jshint : {
2013-07-11 14:02:18 -05:00
server : {
2014-02-26 21:44:09 -05:00
options : {
2013-06-25 06:43:15 -05:00
// node environment
node : true ,
// browser environment
browser : false ,
// allow dangling underscores in var names
2014-02-26 21:44:09 -05:00
nomen : false ,
2013-06-25 06:43:15 -05:00
// don't require use strict pragma
2014-02-26 21:44:09 -05:00
strict : false ,
sub : true ,
eqeqeq : true ,
laxbreak : true ,
bitwise : true ,
curly : true ,
forin : true ,
immed : true ,
latedef : true ,
newcap : true ,
noarg : true ,
noempty : true ,
nonew : true ,
plusplus : true ,
regexp : true ,
undef : true ,
unused : true ,
trailing : true ,
indent : 4 ,
onevar : true ,
white : true
2013-06-25 06:43:15 -05:00
} ,
files : {
src : [
2013-09-24 05:46:30 -05:00
'*.js' ,
'core/*.js' ,
'core/server/**/*.js'
2013-06-25 07:38:41 -05:00
]
2013-07-11 14:02:18 -05:00
}
2013-06-25 06:43:15 -05:00
} ,
2013-07-11 14:02:18 -05:00
client : {
2014-02-26 21:44:09 -05:00
options : {
"predef" : {
"document" : true ,
"window" : true ,
"location" : true ,
"setTimeout" : true ,
"Ember" : true ,
"Em" : true ,
"DS" : true ,
"$" : true
} ,
2013-06-25 06:43:15 -05:00
// node environment
node : false ,
// browser environment
browser : true ,
// allow dangling underscores in var names
2014-02-26 21:44:09 -05:00
nomen : false ,
bitwise : true ,
curly : true ,
eqeqeq : true ,
forin : true ,
immed : true ,
latedef : true ,
newcap : true ,
noarg : true ,
noempty : true ,
nonew : true ,
plusplus : true ,
regexp : true ,
undef : true ,
unused : true ,
trailing : true ,
indent : 4 ,
esnext : true ,
onevar : true ,
white : true
2013-06-25 06:43:15 -05:00
} ,
files : {
2014-02-26 21:44:09 -05:00
src : [
'core/client/**/*.js' ,
// Ignore files
'!core/client/assets/vendor/**/*.js' ,
'!core/client/tpl/**/*.js'
]
}
2013-07-11 14:02:18 -05:00
} ,
shared : {
2014-02-26 21:44:09 -05:00
options : {
2013-07-11 14:02:18 -05:00
// node environment
node : true ,
// browser environment
browser : false ,
// don't require use strict pragma
2014-02-26 21:44:09 -05:00
strict : false ,
// allow dangling underscores in var names
nomen : false ,
bitwise : true ,
curly : true ,
eqeqeq : true ,
forin : true ,
immed : true ,
latedef : true ,
newcap : true ,
noarg : true ,
noempty : true ,
nonew : true ,
plusplus : true ,
regexp : true ,
undef : true ,
unused : true ,
trailing : true ,
indent : 4 ,
onevar : true ,
white : true
2013-07-11 14:02:18 -05:00
} ,
files : {
src : [
2014-02-26 21:44:09 -05:00
'core/shared/**/*.js' ,
// Ignore files
2014-03-03 16:41:34 -05:00
'!core/shared/vendor/**/*.js' ,
'!core/shared/lib/**/*.js'
2013-07-11 14:02:18 -05:00
]
2014-02-26 21:44:09 -05:00
}
2013-06-25 06:43:15 -05:00
}
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-mocha-cli
// Run mocha unit tests
2013-07-09 17:54:57 -05:00
mochacli : {
2013-06-25 06:43:15 -05:00
options : {
2013-09-24 05:46:30 -05:00
ui : 'bdd' ,
2013-10-16 17:57:52 -05:00
reporter : 'spec' ,
timeout : '15000'
2013-05-26 12:17:46 -05:00
} ,
2013-11-24 09:29:36 -05:00
unit : {
2013-07-31 02:33:28 -05:00
src : [ 'core/test/unit/**/*_spec.js' ]
2013-06-25 06:43:15 -05:00
} ,
2013-05-25 11:48:15 -05:00
2013-11-07 08:26:47 -05:00
model : {
src : [ 'core/test/integration/**/model*_spec.js' ]
2013-06-25 06:43:15 -05:00
} ,
2013-05-25 11:55:23 -05:00
2014-02-26 18:15:31 -05:00
clientold : {
src : [ 'core/test/unit/**/clientold*_spec.js' ]
2013-08-19 16:52:50 -05:00
} ,
server : {
src : [ 'core/test/unit/**/server*_spec.js' ]
} ,
shared : {
src : [ 'core/test/unit/**/shared*_spec.js' ]
2013-08-24 15:51:58 -05:00
} ,
2013-06-25 06:43:15 -05:00
perm : {
2013-07-31 02:33:28 -05:00
src : [ 'core/test/unit/**/permissions_spec.js' ]
2013-08-03 10:11:16 -05:00
} ,
migrate : {
src : [
'core/test/unit/**/export_spec.js' ,
'core/test/unit/**/import_spec.js'
]
2013-10-29 16:34:47 -05:00
} ,
2013-12-03 21:47:39 -05:00
storage : {
src : [ 'core/test/unit/**/storage*_spec.js' ]
} ,
2013-10-29 16:34:47 -05:00
integration : {
2014-02-26 12:51:01 -05:00
src : [
'core/test/integration/**/model*_spec.js' ,
'core/test/integration/**/api*_spec.js'
]
2013-11-24 09:29:36 -05:00
} ,
api : {
src : [ 'core/test/functional/api/*_test.js' ]
2013-12-31 12:09:49 -05:00
} ,
routes : {
src : [ 'core/test/functional/routes/*_test.js' ]
2013-06-25 06:43:15 -05:00
}
} ,
2013-06-14 17:12:04 -05:00
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-sass
2013-06-25 06:43:15 -05:00
// Compile all the SASS!
sass : {
admin : {
files : {
2014-02-26 18:15:31 -05:00
'<%= paths.adminOldAssets %>/css/screen.css' : '<%= paths.adminOldAssets %>/sass/screen.scss'
2013-06-10 08:52:04 -05:00
}
2013-09-27 10:02:35 -05:00
} ,
compress : {
options : {
style : 'compressed'
} ,
files : {
2014-02-26 18:15:31 -05:00
'<%= paths.adminOldAssets %>/css/screen.css' : '<%= paths.adminOldAssets %>/sass/screen.scss'
2013-09-27 10:02:35 -05:00
}
2013-06-25 06:43:15 -05:00
}
} ,
2013-12-06 05:24:25 -05:00
// ### config for grunt-shell
// command line tools
2013-06-25 06:43:15 -05:00
shell : {
2014-02-18 22:41:21 -05:00
// run bundle
bundle : {
command : 'bundle install'
} ,
2013-12-06 05:24:25 -05:00
// install bourbon
2013-06-25 06:43:15 -05:00
bourbon : {
2014-02-26 18:15:31 -05:00
command : 'bourbon install --path <%= paths.adminOldAssets %>/sass/modules/'
2013-11-02 18:40:43 -05:00
} ,
2014-03-04 16:35:06 -05:00
bower : {
command : path . resolve ( _ _dirname + '/node_modules/.bin/bower install' ) ,
options : {
stdout : true
}
} ,
2013-12-06 05:24:25 -05:00
// generate coverage report
2013-11-02 18:40:43 -05:00
coverage : {
2013-11-11 15:54:48 -05:00
command : function ( ) {
// will work on windows only if mocha is globally installed
var cmd = ! ! process . platform . match ( /^win/ ) ? 'mocha' : './node_modules/mocha/bin/mocha' ;
return cmd + ' --timeout 15000 --reporter html-cov > coverage.html ./core/test/blanket_coverage.js' ;
} ,
execOptions : {
env : 'NODE_ENV=' + process . env . NODE _ENV
}
2013-06-25 06:43:15 -05:00
}
} ,
2013-06-01 18:45:02 -05:00
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-handlebars
2014-02-26 18:15:31 -05:00
// Compile templates for admin clientold
2013-06-25 06:43:15 -05:00
handlebars : {
core : {
options : {
2013-09-24 05:46:30 -05:00
namespace : 'JST' ,
2013-06-25 06:43:15 -05:00
processName : function ( filename ) {
2014-02-26 18:15:31 -05:00
filename = filename . replace ( 'core/clientold/tpl/' , '' ) ;
2013-06-25 06:43:15 -05:00
return filename . replace ( '.hbs' , '' ) ;
}
2013-06-01 18:45:02 -05:00
} ,
2013-06-25 06:43:15 -05:00
files : {
2014-02-26 18:15:31 -05:00
'core/clientold/tpl/hbs-tpl.js' : 'core/clientold/tpl/**/*.hbs'
2013-06-01 18:45:02 -05:00
}
2013-06-25 06:43:15 -05:00
}
} ,
2014-02-25 23:58:00 -05:00
// ### Config for grunt-ember-templates
// Compiles handlebar templates for ember
emberTemplates : {
2014-02-26 23:45:45 -05:00
dev : {
2014-02-25 23:58:00 -05:00
options : {
2014-02-26 23:45:45 -05:00
templateBasePath : /core\/client\// ,
templateFileExtensions : /\.hbs/ ,
templateRegistration : function ( name , template ) {
return grunt . config . process ( "define('ghost/" ) + name + "', ['exports'], function(__exports__){ __exports__['default'] = " + template + "; });" ;
}
2014-02-25 23:58:00 -05:00
} ,
files : {
"core/built/scripts/templates-ember.js" : "core/client/templates/**/*.hbs"
}
}
} ,
2014-02-26 23:45:45 -05:00
// ### Config for grunt-es6-module-transpiler
// Compiles Ember es6 modules
transpile : {
client : {
type : 'amd' ,
moduleName : function ( path ) {
return 'ghost/' + path ;
} ,
files : [ {
expand : true ,
cwd : 'core/client/' ,
src : [ '**/*.js' ] ,
dest : '.tmp/ember-transpiled/'
} ]
}
} ,
// ### Config for grunt-es6-module-transpiler
// Compiles Ember es6 modules
concat _sourcemap : {
client : {
src : [ '.tmp/ember-transpiled/**/*.js' ] ,
dest : 'core/built/scripts/ghost-dev-ember.js' ,
options : {
sourcesContent : true
}
}
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-groc
// Generate documentation from code
2013-06-25 06:43:15 -05:00
groc : {
2013-06-25 13:10:33 -05:00
docs : {
options : {
2013-09-24 05:46:30 -05:00
'out' : './docs/' ,
'glob' : [
'README.md' ,
'config.example.js' ,
'index.js' ,
'core/*.js' ,
'core/server/**/*.js' ,
'core/shared/**/*.js' ,
2014-02-26 18:15:31 -05:00
'core/clientold/**/*.js'
2013-07-11 14:02:18 -05:00
] ,
2013-09-24 05:46:30 -05:00
'except' : [
'!core/**/vendor/**/*.js' ,
2014-02-26 18:15:31 -05:00
'!core/clientold/tpl/**/*.js'
2013-06-25 13:10:33 -05:00
]
}
2013-06-25 06:43:15 -05:00
}
} ,
2013-06-01 18:45:02 -05:00
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-clean
// Clean up files as part of other tasks
2013-09-18 13:56:39 -05:00
clean : {
2014-03-02 09:30:35 -05:00
built : {
src : [ 'core/built/**' ]
} ,
2013-11-01 10:33:49 -05:00
release : {
src : [ '<%= paths.releaseBuild %>/**' ]
2013-10-14 22:39:52 -05:00
} ,
test : {
src : [ 'content/data/ghost-test.db' ]
2013-09-18 13:56:39 -05:00
}
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-copy
// Prepare files for builds / releases
2013-06-25 06:43:15 -05:00
copy : {
2014-03-03 16:41:34 -05:00
dev : {
files : [ {
cwd : 'bower_components/jquery/dist/' ,
src : 'jquery.js' ,
dest : 'core/built/public/' ,
expand : true
} ]
} ,
prod : {
files : [ {
cwd : 'bower_components/jquery/dist/' ,
src : 'jquery.js' ,
dest : 'core/built/public/' ,
expand : true
} ]
} ,
2013-11-01 10:33:49 -05:00
release : {
2013-06-25 06:43:15 -05:00
files : [ {
2014-03-03 16:41:34 -05:00
cwd : 'bower_components/jquery/dist/' ,
src : 'jquery.js' ,
dest : 'core/built/public/' ,
expand : true
2014-03-04 16:35:06 -05:00
} , {
2013-06-25 06:43:15 -05:00
expand : true ,
2013-09-18 13:45:21 -05:00
src : buildGlob ,
2013-11-01 10:33:49 -05:00
dest : '<%= paths.releaseBuild %>/'
2013-06-25 06:43:15 -05:00
} ]
}
} ,
2013-05-19 23:22:00 -05:00
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-compress
// Zip up builds / releases
2013-06-25 06:43:15 -05:00
compress : {
2013-10-11 10:31:47 -05:00
release : {
options : {
archive : '<%= paths.releaseDist %>/Ghost-<%= pkg.version %>.zip'
} ,
expand : true ,
2013-11-01 10:33:49 -05:00
cwd : '<%= paths.releaseBuild %>/' ,
2013-10-11 10:31:47 -05:00
src : [ '**' ]
2013-06-10 08:52:04 -05:00
}
2013-07-01 15:58:47 -05:00
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-concat
// concatenate multiple JS files into a single file ready for use
2013-09-13 21:15:30 -05:00
concat : {
dev : {
files : {
2013-09-24 05:46:30 -05:00
'core/built/scripts/vendor.js' : [
2014-03-03 16:41:34 -05:00
'bower_components/jquery/dist/jquery.js' ,
'bower_components/jquery-ui/ui/jquery-ui.js' ,
2014-02-26 18:15:31 -05:00
'core/clientold/assets/lib/jquery-utils.js' ,
'core/clientold/assets/lib/uploader.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/lodash/dist/lodash.underscore.js' ,
'bower_components/backbone/backbone.js' ,
2014-03-02 09:30:35 -05:00
'bower_components/handlebars/handlebars.runtime.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/moment/moment.js' ,
'bower_components/jquery-file-upload/js/jquery.fileupload.js' ,
'bower_components/codemirror/lib/codemirror.js' ,
2014-03-05 14:46:43 -05:00
'bower_components/codemirror/addon/mode/overlay.js' ,
'bower_components/codemirror/mode/markdown/markdown.js' ,
'bower_components/codemirror/mode/gfm/gfm.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/showdown/src/showdown.js' ,
'bower_components/validator-js/validator.js' ,
2014-03-05 18:10:44 -05:00
'core/clientold/assets/lib/showdown/extensions/ghostdown.js' ,
2014-03-03 16:41:34 -05:00
'core/shared/lib/showdown/extensions/typography.js' ,
'core/shared/lib/showdown/extensions/github.js' ,
// ToDo: Remove or replace
2014-02-26 18:15:31 -05:00
'core/clientold/assets/vendor/shortcuts.js' ,
'core/clientold/assets/vendor/to-title-case.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/Countable/Countable.js' ,
'bower_components/fastclick/lib/fastclick.js' ,
'bower_components/nprogress/nprogress.js'
2013-09-13 21:15:30 -05:00
] ,
2013-09-24 05:46:30 -05:00
'core/built/scripts/helpers.js' : [
2014-02-26 18:15:31 -05:00
'core/clientold/init.js' ,
2013-09-13 21:15:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/mobile-interactions.js' ,
'core/clientold/toggle.js' ,
'core/clientold/markdown-actions.js' ,
'core/clientold/helpers/index.js'
2013-09-13 21:15:30 -05:00
] ,
2013-09-24 05:46:30 -05:00
'core/built/scripts/templates.js' : [
2014-02-26 18:15:31 -05:00
'core/clientold/tpl/hbs-tpl.js'
2013-09-13 21:15:30 -05:00
] ,
2013-09-24 05:46:30 -05:00
'core/built/scripts/models.js' : [
2014-02-26 18:15:31 -05:00
'core/clientold/models/**/*.js'
2013-09-13 21:15:30 -05:00
] ,
2013-09-24 05:46:30 -05:00
'core/built/scripts/views.js' : [
2014-02-26 18:15:31 -05:00
'core/clientold/views/**/*.js' ,
'core/clientold/router.js'
2013-09-13 21:15:30 -05:00
]
}
} ,
2014-02-25 23:58:00 -05:00
'dev-ember' : {
files : {
'core/built/scripts/vendor-ember.js' : [
2014-03-05 18:10:44 -05:00
'core/client/assets/vendor/loader.js' ,
'bower_components/jquery/dist/jquery.js' ,
2014-03-02 09:30:35 -05:00
'bower_components/handlebars/handlebars.js' ,
2014-03-05 18:10:44 -05:00
'bower_components/ember/ember.js' ,
2014-03-02 09:30:35 -05:00
'bower_components/ember-resolver/dist/ember-resolver.js' ,
'bower_components/ic-ajax/dist/globals/main.js' ,
'bower_components/codemirror/lib/codemirror.js' ,
'bower_components/codemirror/addon/mode/overlay.js' ,
'bower_components/codemirror/mode/markdown/markdown.js' ,
'bower_components/codemirror/mode/gfm/gfm.js' ,
'bower_components/showdown/src/showdown.js' ,
'core/clientold/assets/lib/showdown/extensions/ghostdown.js' ,
'core/shared/lib/showdown/extensions/typography.js' ,
'core/shared/lib/showdown/extensions/github.js' ,
'bower_components/moment/moment.js'
2014-02-25 23:58:00 -05:00
]
}
} ,
2013-09-13 21:15:30 -05:00
prod : {
files : {
2013-09-24 05:46:30 -05:00
'core/built/scripts/ghost.js' : [
2014-03-03 16:41:34 -05:00
'bower_components/jquery/dist/jquery.js' ,
'bower_components/jquery-ui/ui/jquery-ui.js' ,
2014-02-26 18:15:31 -05:00
'core/clientold/assets/lib/jquery-utils.js' ,
'core/clientold/assets/lib/uploader.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/lodash/dist/lodash.underscore.js' ,
'bower_components/backbone/backbone.js' ,
2014-03-02 09:30:35 -05:00
'bower_components/handlebars/handlebars.runtime.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/moment/moment.js' ,
'bower_components/jquery-file-upload/js/jquery.fileupload.js' ,
'bower_components/codemirror/lib/codemirror.js' ,
2014-03-05 14:46:43 -05:00
'bower_components/codemirror/addon/mode/overlay.js' ,
'bower_components/codemirror/mode/markdown/markdown.js' ,
'bower_components/codemirror/mode/gfm/gfm.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/showdown/src/showdown.js' ,
'bower_components/validator-js/validator.js' ,
2014-03-05 18:10:44 -05:00
'core/clientold/assets/lib/showdown/extensions/ghostdown.js' ,
2014-03-03 16:41:34 -05:00
'core/shared/lib/showdown/extensions/typography.js' ,
'core/shared/lib/showdown/extensions/github.js' ,
// ToDo: Remove or replace
2014-02-26 18:15:31 -05:00
'core/clientold/assets/vendor/shortcuts.js' ,
'core/clientold/assets/vendor/to-title-case.js' ,
2014-03-03 16:41:34 -05:00
'bower_components/Countable/Countable.js' ,
'bower_components/fastclick/lib/fastclick.js' ,
'bower_components/nprogress/nprogress.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/init.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/mobile-interactions.js' ,
'core/clientold/toggle.js' ,
'core/clientold/markdown-actions.js' ,
'core/clientold/helpers/index.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/tpl/hbs-tpl.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/models/**/*.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/views/**/*.js' ,
2013-09-24 05:46:30 -05:00
2014-02-26 18:15:31 -05:00
'core/clientold/router.js'
2013-09-13 21:15:30 -05:00
]
}
}
} ,
2013-12-06 05:24:25 -05:00
// ### Config for grunt-contrib-uglify
// minify javascript file for production
2013-09-13 21:15:30 -05:00
uglify : {
prod : {
files : {
2013-09-24 05:46:30 -05:00
'core/built/scripts/ghost.min.js' : 'core/built/scripts/ghost.js'
2013-09-13 21:15:30 -05:00
}
}
2013-06-25 06:43:15 -05:00
}
2013-06-10 08:52:04 -05:00
} ;
2013-05-13 14:18:20 -05:00
2013-06-25 06:43:15 -05:00
grunt . initConfig ( cfg ) ;
2013-12-06 05:24:25 -05:00
// ## Custom Tasks
2013-10-25 00:58:58 -05:00
grunt . registerTask ( 'setTestEnv' , 'Use "testing" Ghost config; unless we are running on travis (then show queries for debugging)' , function ( ) {
2013-10-29 15:54:37 -05:00
process . env . NODE _ENV = process . env . TRAVIS ? 'travis-' + process . env . DB : 'testing' ;
2013-11-03 09:12:09 -05:00
cfg . express . test . options . node _env = process . env . NODE _ENV ;
2013-09-13 09:12:38 -05:00
} ) ;
2013-09-13 02:24:28 -05:00
grunt . registerTask ( 'loadConfig' , function ( ) {
var done = this . async ( ) ;
2014-01-05 01:40:53 -05:00
bootstrap ( ) . then ( function ( ) {
2013-09-13 02:24:28 -05:00
done ( ) ;
} ) ;
} ) ;
2013-08-26 16:28:41 -05:00
grunt . registerTask ( 'spawn-casperjs' , function ( ) {
var done = this . async ( ) ,
options = [ 'host' , 'noPort' , 'port' , 'email' , 'password' ] ,
2013-10-18 19:13:07 -05:00
args = [ 'test' ]
. concat ( grunt . option ( 'target' ) || [ 'admin/' , 'frontend/' ] )
. concat ( [ '--includes=base.js' , '--verbose' , '--log-level=debug' , '--port=2369' ] ) ;
2013-08-26 16:28:41 -05:00
// Forward parameters from grunt to casperjs
_ . each ( options , function processOption ( option ) {
if ( grunt . option ( option ) ) {
args . push ( '--' + option + '=' + grunt . option ( option ) ) ;
}
} ) ;
grunt . util . spawn ( {
cmd : 'casperjs' ,
args : args ,
opts : {
cwd : path . resolve ( 'core/test/functional' ) ,
stdio : 'inherit'
}
} , function ( error , result , code ) {
2014-02-26 21:44:09 -05:00
/*jshint unused:false*/
2013-08-26 16:28:41 -05:00
if ( error ) {
grunt . fail . fatal ( result . stdout ) ;
}
grunt . log . writeln ( result . stdout ) ;
done ( ) ;
} ) ;
} ) ;
2013-08-01 02:12:59 -05:00
/ * G e n e r a t e C h a n g e l o g
* - Pulls changelog from git , excluding merges .
* - Uses first line of commit message . Includes committer name .
* /
2013-10-25 00:58:58 -05:00
grunt . registerTask ( 'changelog' , 'Generate changelog from Git' , function ( ) {
2013-08-01 02:12:59 -05:00
// TODO: Break the contents of this task out into a separate module,
// put on npm. (@cgiffard)
var done = this . async ( ) ;
function git ( args , callback , depth ) {
depth = depth || 0 ;
if ( ! depth ) {
2013-09-24 05:46:30 -05:00
grunt . log . writeln ( 'git ' + args . join ( ' ' ) ) ;
2013-08-01 02:12:59 -05:00
}
var buffer = [ ] ;
2013-09-24 05:46:30 -05:00
spawn ( 'git' , args , {
2013-08-01 02:12:59 -05:00
// We can reasonably assume the gruntfile will be in the root of the repo.
cwd : _ _dirname ,
2013-09-24 05:46:30 -05:00
stdio : [ 'ignore' , 'pipe' , process . stderr ]
2013-08-01 02:12:59 -05:00
2013-09-24 05:46:30 -05:00
} ) . on ( 'exit' , function ( code ) {
2013-08-01 02:12:59 -05:00
// Process exited correctly but we got no output.
// Spawn again, but make sure we don't spiral out of control.
// Hack to work around an apparent node bug.
//
// Frustratingly, it's impossible to distinguish this
// bug from a genuine empty log.
if ( ! buffer . length && code === 0 && depth < 20 ) {
return setImmediate ( function ( ) {
git ( args , callback , depth ? depth + 1 : 1 ) ;
} ) ;
}
if ( code === 0 ) {
2013-09-24 05:46:30 -05:00
return callback ( buffer . join ( '' ) ) ;
2013-08-01 02:12:59 -05:00
}
// We failed. Git returned a non-standard exit code.
grunt . log . error ( 'Git returned a non-zero exit code.' ) ;
done ( false ) ;
// Push returned data into the buffer
2013-09-24 05:46:30 -05:00
} ) . stdout . on ( 'data' , buffer . push . bind ( buffer ) ) ;
2013-08-01 02:12:59 -05:00
}
// Crazy function for getting around inconsistencies in tagging
function sortTags ( a , b ) {
a = a . tag ;
b = b . tag ;
// NOTE: Accounting for different tagging method for
// 0.2.1 and up.
// If we didn't have this issue I'd just pass rcompare
// into sort directly. Could be something to think about
// in future.
2013-09-24 05:46:30 -05:00
if ( semver . rcompare ( a , '0.2.0' ) < 0 ||
semver . rcompare ( b , '0.2.0' ) < 0 ) {
2013-08-01 02:12:59 -05:00
return semver . rcompare ( a , b ) ;
}
2013-09-24 05:46:30 -05:00
a = a . split ( '-' ) ;
b = b . split ( '-' ) ;
2013-08-01 02:12:59 -05:00
if ( semver . rcompare ( a [ 0 ] , b [ 0 ] ) !== 0 ) {
return semver . rcompare ( a [ 0 ] , b [ 0 ] ) ;
}
// Using this janky looking integerising-method
// because it's faster and doesn't result in NaN, which
// breaks sorting
2013-09-12 15:03:01 -05:00
/*jslint bitwise: true */
2013-08-01 02:12:59 -05:00
return ( + b [ 1 ] | 0 ) - ( + a [ 1 ] | 0 ) ;
}
// Gets tags in master branch, sorts them with semver,
function getTags ( callback ) {
2013-09-24 05:46:30 -05:00
git ( [ 'show-ref' , '--tags' ] , function ( results ) {
2013-08-01 02:12:59 -05:00
results = results
. split ( /\n+/ )
. filter ( function ( tag ) {
return tag . length && tag . match ( /\/\d+\.\d+/ ) ;
} )
. map ( function ( tag ) {
return {
2013-09-24 05:46:30 -05:00
'tag' : tag . split ( /tags\// ) . pop ( ) . trim ( ) ,
'ref' : tag . split ( /\s+/ ) . shift ( ) . trim ( )
2013-08-01 02:12:59 -05:00
} ;
} )
. sort ( sortTags ) ;
callback ( results ) ;
} ) ;
}
// Parses log to extract commit data.
function parseLog ( data ) {
var commits = [ ] ,
commitRegex =
new RegExp (
2013-09-24 05:46:30 -05:00
'\\n*[|\\*\\s]*commit\\s+([a-f0-9]+)' +
'\\n[|\\*\\s]*Author:\\s+([^<\\n]+)<([^>\\n]+)>' +
'\\n[|\\*\\s]*Date:\\s+([^\\n]+)' +
'\\n+[|\\*\\s]*[ ]{4}([^\\n]+)' ,
'ig'
2013-08-01 02:12:59 -05:00
) ;
// Using String.prototype.replace as a kind of poor-man's substitute
// for a streaming parser.
data . replace (
commitRegex ,
function ( wholeCommit , hash , author , email , date , message ) {
2014-02-26 21:44:09 -05:00
/*jshint unused:false*/
2013-08-01 02:12:59 -05:00
// The author name and commit message may have trailing space.
author = author . trim ( ) ;
message = message . trim ( ) ;
// Reformat date to make it parse-able by JS
date =
date . replace (
/^(\w+)\s(\w+)\s(\d+)\s([\d\:]+)\s(\d+)\s([\+\-\d]+)$/ ,
2013-09-24 05:46:30 -05:00
'$1, $2 $3 $5 $4 $6'
2013-08-01 02:12:59 -05:00
) ;
commits . push ( {
2013-09-24 05:46:30 -05:00
'hash' : hash ,
'author' : author ,
'email' : email ,
'date' : date ,
'parsedDate' : new Date ( Date . parse ( date ) ) ,
'message' : message
2013-08-01 02:12:59 -05:00
} ) ;
return null ;
}
) ;
return commits ;
}
// Gets git log for specified range.
function getLog ( to , from , callback ) {
2013-09-24 05:46:30 -05:00
var range = from && to ? from + '..' + to : '' ,
args = [ 'log' , 'master' , '--no-color' , '--no-merges' , '--graph' ] ;
2013-08-01 02:12:59 -05:00
if ( range ) {
args . push ( range ) ;
}
git ( args , function ( data ) {
callback ( parseLog ( data ) ) ;
} ) ;
}
// Run the job
getTags ( function ( tags ) {
2013-09-24 05:46:30 -05:00
var logPath = path . join ( _ _dirname , 'CHANGELOG.md' ) ,
2013-08-01 02:12:59 -05:00
log = fs . createWriteStream ( logPath ) ,
commitCache = { } ;
function processTag ( tag , callback ) {
2013-09-24 05:46:30 -05:00
var buffer = '' ,
2013-08-01 02:12:59 -05:00
peek = tag [ 1 ] ;
tag = tag [ 0 ] ;
getLog ( tag . tag , peek . tag , function ( commits ) {
// Use the comparison with HEAD to remove commits which
// haven't been included in a build/release yet.
2013-10-25 00:58:58 -05:00
if ( tag . tag === 'HEAD' ) {
2013-08-01 02:12:59 -05:00
commits . forEach ( function ( commit ) {
commitCache [ commit . hash ] = true ;
} ) ;
2013-10-25 00:58:58 -05:00
return callback ( '' ) ;
2013-08-01 02:12:59 -05:00
}
2013-09-24 05:46:30 -05:00
buffer += '## Release ' + tag . tag + '\n' ;
2013-08-01 02:12:59 -05:00
commits = commits
. filter ( function ( commit ) {
// Get rid of jenkins' release tagging commits
// Remove commits we've already spat out
return (
2013-09-24 05:46:30 -05:00
commit . author !== 'TryGhost-Jenkins' &&
2013-08-01 02:12:59 -05:00
! commitCache [ commit . hash ]
) ;
} )
. map ( function ( commit ) {
2013-09-24 05:46:30 -05:00
buffer += '\n* ' + commit . message + ' (_' + commit . author + '_)' ;
2013-08-01 02:12:59 -05:00
commitCache [ commit . hash ] = true ;
} ) ;
if ( ! commits . length ) {
2013-10-25 00:58:58 -05:00
buffer += '\nNo changes were made in this build.\n' ;
2013-08-01 02:12:59 -05:00
}
2013-09-24 05:46:30 -05:00
callback ( buffer + '\n' ) ;
2013-08-01 02:12:59 -05:00
} ) ;
}
// Get two weeks' worth of tags
2013-09-24 05:46:30 -05:00
tags . unshift ( { 'tag' : 'HEAD' } ) ;
2013-08-01 02:12:59 -05:00
tags =
tags
. slice ( 0 , 14 )
. map ( function ( tag , index ) {
return [
tag ,
tags [ index + 1 ] || tags [ index ]
] ;
} ) ;
2013-09-24 05:46:30 -05:00
log . write ( '# Ghost Changelog\n\n' ) ;
log . write ( '_Showing ' + tags . length + ' releases._\n' ) ;
2013-08-01 02:12:59 -05:00
when . reduce ( tags ,
function ( prev , tag , idx ) {
2014-02-26 21:44:09 -05:00
/*jshint unused:false*/
2013-08-01 02:12:59 -05:00
return when . promise ( function ( resolve ) {
processTag ( tag , function ( releaseData ) {
2013-09-24 05:46:30 -05:00
resolve ( prev + '\n' + releaseData ) ;
2013-08-01 02:12:59 -05:00
} ) ;
} ) ;
2013-09-24 05:46:30 -05:00
} , '' )
2013-08-01 02:12:59 -05:00
. then ( function ( reducedChangelog ) {
log . write ( reducedChangelog ) ;
log . close ( ) ;
done ( true ) ;
} ) ;
} ) ;
} ) ;
2013-11-01 10:33:49 -05:00
grunt . registerTask ( 'release' ,
'Release task - creates a final built zip\n' +
' - Do our standard build steps (sass, handlebars, etc)\n' +
' - Generate changelog for the past 14 releases\n' +
' - Copy files to release-folder/#/#{version} directory\n' +
' - Clean out unnecessary files (travis, .git*, .af*, .groc*)\n' +
' - Zip files in release-folder to dist-folder/#{version} directory' ,
[
'shell:bourbon' ,
2014-03-04 16:35:06 -05:00
'shell:bower' ,
2013-11-01 10:33:49 -05:00
'sass:compress' ,
'handlebars' ,
'concat' ,
'uglify' ,
'clean:release' ,
'copy:release' ,
'compress:release'
] ) ;
2013-10-11 10:31:47 -05:00
2013-10-25 00:58:58 -05:00
grunt . registerTask ( 'dev' ,
'Dev Mode; watch files and restart server on changes' ,
[
'sass:admin' ,
'handlebars' ,
'concat' ,
2014-02-26 23:45:45 -05:00
'emberBuild' ,
2014-03-03 16:41:34 -05:00
'copy:dev' ,
2013-10-25 00:58:58 -05:00
'express:dev' ,
'watch'
] ) ;
2013-08-17 13:39:02 -05:00
2013-12-06 05:24:25 -05:00
// ### Find out more about grunt task usage
grunt . registerTask ( 'help' ,
'Outputs help information if you type `grunt help` instead of `grunt --help`' ,
function ( ) {
console . log ( 'Type `grunt --help` to get the details of available grunt tasks, or alternatively visit https://github.com/TryGhost/Ghost/wiki/Grunt-Toolkit' ) ;
} ) ;
2013-11-01 10:33:49 -05:00
2013-12-06 05:24:25 -05:00
// ### Running the test suites
2013-09-13 09:12:38 -05:00
2013-12-06 05:24:25 -05:00
grunt . registerTask ( 'test-unit' , 'Run unit tests (mocha)' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'mochacli:unit' ] ) ;
2013-09-13 09:12:38 -05:00
2013-12-06 05:24:25 -05:00
grunt . registerTask ( 'test-integration' , 'Run integration tests (mocha + db access)' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'mochacli:integration' ] ) ;
2013-10-29 16:34:47 -05:00
2014-03-03 16:41:34 -05:00
grunt . registerTask ( 'test-functional' , 'Run functional interface tests (CasperJS)' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'copy:dev' , 'express:test' , 'spawn-casperjs' , 'express:test:stop' ] ) ;
2013-09-13 09:12:38 -05:00
2013-12-06 05:24:25 -05:00
grunt . registerTask ( 'test-api' , 'Run functional api tests (mocha)' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'express:test' , 'mochacli:api' , 'express:test:stop' ] ) ;
2013-11-24 09:29:36 -05:00
2013-12-31 12:09:49 -05:00
grunt . registerTask ( 'test-routes' , 'Run functional route tests (mocha)' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'express:test' , 'mochacli:routes' , 'express:test:stop' ] ) ;
2014-02-26 21:44:09 -05:00
grunt . registerTask ( 'validate' , 'Run tests and lint code' , [ 'jshint' , 'test-routes' , 'test-unit' , 'test-api' , 'test-integration' , 'test-functional' ] ) ;
2013-09-13 09:12:38 -05:00
2013-11-01 10:33:49 -05:00
2013-12-06 05:24:25 -05:00
// ### Coverage report for Unit and Integration Tests
2013-11-02 18:40:43 -05:00
2014-01-04 09:09:59 -05:00
grunt . registerTask ( 'test-coverage' , 'Generate unit and integration (mocha) tests coverage report' , [ 'clean:test' , 'setTestEnv' , 'loadConfig' , 'shell:coverage' ] ) ;
2013-11-02 18:40:43 -05:00
2013-12-06 05:24:25 -05:00
// ### Documentation
2013-11-01 10:33:49 -05:00
2013-10-25 00:58:58 -05:00
grunt . registerTask ( 'docs' , 'Generate Docs' , [ 'groc' ] ) ;
2013-09-13 09:12:38 -05:00
2013-11-01 10:33:49 -05:00
2013-12-06 05:24:25 -05:00
// ### Tools for building assets
2013-11-01 10:33:49 -05:00
2014-03-04 16:35:06 -05:00
grunt . registerTask ( 'init' , 'Prepare the project for development' , [ 'shell:bundle' , 'shell:bourbon' , 'shell:bower' , 'default' ] ) ;
2013-11-01 10:33:49 -05:00
// Before running in production mode
2014-03-03 16:41:34 -05:00
grunt . registerTask ( 'prod' , 'Build CSS, JS & templates for production' , [ 'sass:compress' , 'handlebars' , 'concat' , 'uglify' , 'copy:prod' ] ) ;
2013-09-13 21:15:30 -05:00
2014-02-26 23:45:45 -05:00
// All tasks related to building the Ember client code
grunt . registerTask ( 'emberBuild' , 'Build Ember JS & templates for development' , [ 'emberTemplates:dev' , 'transpile' , 'concat_sourcemap' ] ) ;
2013-10-25 00:58:58 -05:00
// When you just say 'grunt'
2014-03-05 18:10:44 -05:00
grunt . registerTask ( 'default' , 'Build CSS, JS & templates for development' , [ 'update_submodules' , 'sass:compress' , 'handlebars' , 'concat' , 'copy:dev' , 'emberBuild' ] ) ;
2013-06-25 06:43:15 -05:00
} ;
2014-03-05 18:10:44 -05:00
module . exports = configureGrunt ;