diff --git a/.travis.yml b/.travis.yml
index 4cddccc4cf..6fcff9f516 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,10 @@
language: node_js
node_js:
- 4.0
-before_install:
-- npm install -g grunt-cli
install:
- npm install
script:
-- "./node_modules/grunt-cli/bin/grunt test"
+- "./node_modules/gulp/bin/gulp test"
- npm test
after_success:
- "./create-release-tag.sh"
diff --git a/Gruntfile.js b/Gruntfile.js
deleted file mode 100644
index 587bb93973..0000000000
--- a/Gruntfile.js
+++ /dev/null
@@ -1,148 +0,0 @@
-module.exports = function (grunt) {
- grunt.initConfig({
- // Builds Sass
- sass: {
- dev: {
- options: {
- includePaths: [
- 'govuk_modules/govuk_template/assets/stylesheets',
- 'govuk_modules/govuk_frontend_toolkit/stylesheets',
- 'govuk_modules/govuk-elements-sass/'
- ],
- outputStyle: 'expanded',
- sourceComments: true,
- sourceMap: true
- },
- files: [{
- expand: true,
- cwd: 'app/assets/sass',
- src: ['*.scss'],
- dest: 'public/stylesheets/',
- ext: '.css'
- },
- {
- expand: true,
- cwd: 'docs/assets/sass',
- src: ['*.scss'],
- dest: 'public/stylesheets/',
- ext: '.css'
- }]
- }
- },
-
- // Copies templates and assets from external modules and dirs
- sync: {
- assets: {
- files: [{
- expand: true,
- cwd: 'app/assets/',
- src: ['**/*', '!sass/**'],
- dest: 'public/'
- }, {
- expand: true,
- cwd: 'docs/assets/',
- src: ['**/*', '!sass/**'],
- dest: 'public/'
- }],
- ignoreInDest: '**/stylesheets/**',
- updateAndDelete: true
- },
- govuk: {
- files: [{
- cwd: 'node_modules/govuk_frontend_toolkit/',
- src: '**',
- dest: 'govuk_modules/govuk_frontend_toolkit/'
- },
- {
- cwd: 'node_modules/govuk_template_jinja/assets/',
- src: '**',
- dest: 'govuk_modules/govuk_template/assets/'
- },
- {
- cwd: 'node_modules/govuk_template_jinja/views/layouts/',
- src: '**',
- dest: 'govuk_modules/govuk_template/views/layouts/'
- },
- {
- cwd: 'node_modules/govuk-elements-sass/public/sass/',
- src: ['**', '!node_modules', '!elements-page.scss', '!elements-page-ie6.scss', '!elements-page-ie7.scss', '!elements-page-ie8.scss', '!main.scss', '!main-ie6.scss', '!main-ie7.scss', '!main-ie8.scss', '!prism.scss'],
- dest: 'govuk_modules/govuk-elements-sass/'
- }]
- },
- govuk_template_jinja: {
- files: [{
- cwd: 'govuk_modules/govuk_template/views/layouts/',
- src: '**',
- dest: 'lib/'
- }]
- }
- },
-
- // Watches assets and sass for changes
- watch: {
- css: {
- files: ['app/assets/sass/**/*.scss'],
- tasks: ['sass'],
- options: {
- spawn: false
- }
- },
- assets: {
- files: ['app/assets/**/*', '!app/assets/sass/**'],
- tasks: ['sync:assets'],
- options: {
- spawn: false
- }
- }
- },
-
- // nodemon watches for changes and restarts app
- nodemon: {
- dev: {
- script: 'server.js',
- options: {
- ext: 'js, json',
- ignore: ['node_modules/**', 'app/assets/**', 'public/**'],
- args: grunt.option.flags()
- }
- }
- },
-
- concurrent: {
- target: {
- tasks: ['watch', 'nodemon'],
- options: {
- logConcurrentOutput: true
- }
- }
- }
- })
-
- ;[
- 'grunt-sync',
- 'grunt-contrib-watch',
- 'grunt-sass',
- 'grunt-nodemon',
- 'grunt-concurrent'
- ].forEach(function (task) {
- grunt.loadNpmTasks(task)
- })
-
- grunt.registerTask('generate-assets', [
- 'sync',
- 'sass'
- ])
-
- grunt.registerTask('default', [
- 'generate-assets',
- 'concurrent:target'
- ])
-
- grunt.registerTask(
- 'test',
- 'default',
- function () {
- grunt.log.writeln('Test that the app runs')
- }
- )
-}
diff --git a/Procfile b/Procfile
index d058ce9929..1b9f7acc84 100644
--- a/Procfile
+++ b/Procfile
@@ -1 +1 @@
-web: node ./node_modules/grunt-cli/bin/grunt --gruntfile Gruntfile.js generate-assets && node server.js
+web: node ./node_modules/gulp/bin/gulp generate-assets && node server.js
diff --git a/docs/documentation/install/install-the-kit.md b/docs/documentation/install/install-the-kit.md
index 1c179784ed..4af0603fd2 100644
--- a/docs/documentation/install/install-the-kit.md
+++ b/docs/documentation/install/install-the-kit.md
@@ -69,7 +69,7 @@ To check you’re in the right folder, you can run `ls` (list items):
```
ls
```
-You should see a list of files inside the prototype, starting with `CHANGELOG.md, CONTRIBUTING.md, Gruntfile.js etc`
+You should see a list of files inside the prototype, starting with `CHANGELOG.md, CONTRIBUTING.md, gulpfile.js etc`
> If you don’t see these files, check that you installed the kit into the right location and named it correctly.
@@ -87,4 +87,5 @@ npm install
```
The install may take up to a minute. Whilst installing it may `WARN` about some items - this is ok. As long as there are no `ERROR`s you can continue.
-Next (run the kit)
\ No newline at end of file
+
+Next (run the kit)
diff --git a/gulp/clear.js b/gulp/clear.js
new file mode 100644
index 0000000000..20578df275
--- /dev/null
+++ b/gulp/clear.js
@@ -0,0 +1,15 @@
+/*
+ clear.js
+ ===========
+ removes public folder/govuk_modules folder
+*/
+var config = require('./config.json')
+
+var gulp = require('gulp')
+var clean = require('gulp-clean')
+
+gulp.task('clear', function () {
+ return gulp.src([config.assets.output + '/*',
+ config.assets.govuk_modules + '/*'], {read: false})
+ .pipe(clean())
+})
diff --git a/gulp/config.json b/gulp/config.json
new file mode 100644
index 0000000000..99229b24bb
--- /dev/null
+++ b/gulp/config.json
@@ -0,0 +1,8 @@
+{
+ "assets": {
+ "output": "public/",
+ "base" : "app/assets/",
+ "govuk_modules": "govuk_modules/",
+ "lib": "lib/"
+ }
+}
diff --git a/gulp/copy-assets.js b/gulp/copy-assets.js
new file mode 100644
index 0000000000..61059bc396
--- /dev/null
+++ b/gulp/copy-assets.js
@@ -0,0 +1,13 @@
+/*
+ copy.js
+ ===========
+ copies images and javascript folders to public
+*/
+
+var gulp = require('gulp')
+var config = require('./config.json')
+
+gulp.task('copy-assets', function () {
+ return gulp.src(['!' + config.assets.base + 'sass{,/**/*}', config.assets.base + '/**'])
+ .pipe(gulp.dest(config.assets.output))
+})
diff --git a/gulp/copy-modules.js b/gulp/copy-modules.js
new file mode 100644
index 0000000000..d510050e28
--- /dev/null
+++ b/gulp/copy-modules.js
@@ -0,0 +1,29 @@
+/*
+ copy-gov-modules.js
+ ===========
+ copies files for node_modules into govuk_modules
+*/
+
+var gulp = require('gulp')
+var config = require('./config.json')
+
+gulp.task('copy-toolkit', function () {
+ return gulp.src(['node_modules/govuk_frontend_toolkit/**'])
+ .pipe(gulp.dest(config.assets.govuk_modules + '/govuk_frontend_toolkit/'))
+})
+
+gulp.task('copy-template', function () {
+ return gulp.src(['node_modules/govuk_template_jinja/views/layouts/**'])
+ .pipe(gulp.dest(config.assets.govuk_modules + '/govuk_template/layouts/'))
+ .pipe(gulp.dest(config.assets.lib))
+})
+
+gulp.task('copy-template-assets', function () {
+ return gulp.src(['node_modules/govuk_template_jinja/assets/**'])
+ .pipe(gulp.dest(config.assets.govuk_modules + '/govuk_template/assets/'))
+})
+
+gulp.task('copy-elements-sass', function () {
+ return gulp.src(['node_modules/govuk-elements-sass/public/sass/**'])
+ .pipe(gulp.dest(config.assets.govuk_modules + '/govuk-elements-sass/'))
+})
diff --git a/gulp/nodemon.js b/gulp/nodemon.js
new file mode 100644
index 0000000000..54ff48053b
--- /dev/null
+++ b/gulp/nodemon.js
@@ -0,0 +1,16 @@
+/*
+ nodemon.js
+ ===========
+ uses nodemon to run a server, watches for javascript and json changes
+*/
+
+var gulp = require('gulp')
+var nodemon = require('gulp-nodemon')
+var config = require('./config.json')
+
+gulp.task('server', function () {
+ nodemon({ignore: [config.assets.output + '*', config.assets.output + '*'],
+ script: 'server.js',
+ ext: 'js, json',
+ env: {NODE_ENV: 'development'}})
+})
diff --git a/gulp/sass.js b/gulp/sass.js
new file mode 100644
index 0000000000..e622b46d50
--- /dev/null
+++ b/gulp/sass.js
@@ -0,0 +1,23 @@
+/*
+ sass.js
+ ===========
+ compiles sass from assets folder with the govuk_modules
+ also includes sourcemaps
+*/
+
+var gulp = require('gulp')
+var sass = require('gulp-sass')
+var sourcemaps = require('gulp-sourcemaps')
+
+var config = require('./config.json')
+
+gulp.task('sass', function () {
+ return gulp.src(config.assets.base + '/sass/*.scss')
+ .pipe(sass({outputStyle: 'expanded',
+ includePaths: ['govuk_modules/govuk_frontend_toolkit/stylesheets',
+ 'govuk_modules/govuk_template/assets/stylesheets',
+ 'govuk_modules/govuk-elements-sass/']}).on('error', sass.logError))
+ .pipe(sourcemaps.init())
+ .pipe(sourcemaps.write())
+ .pipe(gulp.dest(config.assets.output + '/stylesheets/'))
+})
diff --git a/gulp/tasks.js b/gulp/tasks.js
new file mode 100644
index 0000000000..aec855e7c3
--- /dev/null
+++ b/gulp/tasks.js
@@ -0,0 +1,39 @@
+/*
+ tasks.js
+ ===========
+ defaults wraps generate-assets, watch and server
+*/
+
+var gulp = require('gulp')
+var gutil = require('gulp-util')
+var runSequence = require('run-sequence')
+
+gulp.task('default', function (done) {
+ runSequence('generate-assets',
+ 'watch',
+ 'server', done)
+})
+
+gulp.task('generate-assets', function (done) {
+ runSequence('clear',
+ 'copy-govuk-modules',
+ 'sass',
+ 'copy-assets', done)
+})
+
+gulp.task('copy-govuk-modules', function (done) {
+ runSequence(['copy-toolkit',
+ 'copy-template-assets',
+ 'copy-elements-sass',
+ 'copy-template'], done)
+})
+
+gulp.task('watch', function (done) {
+ runSequence('watch-sass',
+ 'watch-assets', done)
+})
+
+gulp.task('test', function (done) {
+ gutil.log('Test that the app runs')
+ done()
+})
diff --git a/gulp/watch.js b/gulp/watch.js
new file mode 100644
index 0000000000..63faa23a72
--- /dev/null
+++ b/gulp/watch.js
@@ -0,0 +1,17 @@
+/*
+ watch.js
+ ===========
+ watches sass/js/images
+*/
+
+var gulp = require('gulp')
+var config = require('./config.json')
+
+gulp.task('watch-sass', function () {
+ return gulp.watch(config.assets.base + 'sass/**', {cwd: './'}, ['sass'])
+})
+
+gulp.task('watch-assets', function () {
+ return gulp.watch([config.assets.base + 'images/**',
+ config.assets.base + 'javascripts/**'], {cwd: './'}, ['copy'])
+})
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000000..9f3b6143a0
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,16 @@
+/*
+ gulpfile.js
+ ===========
+ Rather than manage one giant configuration file responsible
+ for creating multiple tasks, each task has been broken out into
+ its own file in `/gulp`. Any files in that directory
+ get automatically required below.
+ To add a new task, simply add a new task file that directory.
+ `/gulp/tasks.js` specifies the default set of
+ tasks to run when you run `gulp`.
+*/
+
+var requireDir = require('require-dir')
+
+// Require all tasks in gulp/tasks, including subfolders
+requireDir('./gulp', {recurse: true})
diff --git a/package.json b/package.json
index 765c5624ee..ecae58b49f 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"node": ">=4.0 <6.7"
},
"scripts": {
- "start": "node start.js",
+ "start": "node start.js && gulp",
"lint": "standard",
"test": "npm run lint"
},
@@ -23,13 +23,12 @@
"govuk-elements-sass": "2.0.0",
"govuk_frontend_toolkit": "^4.18.3",
"govuk_template_jinja": "0.18.3",
- "grunt": "0.4.5",
- "grunt-cli": "0.1.13",
- "grunt-concurrent": "0.4.3",
- "grunt-contrib-watch": "0.5.3",
- "grunt-nodemon": "0.4.0",
- "grunt-sass": "^1.1.0",
- "grunt-sync": "^0.5.1",
+ "gulp": "^3.9.1",
+ "gulp-clean": "^0.3.2",
+ "gulp-nodemon": "^2.1.0",
+ "gulp-sass": "^2.3.2",
+ "gulp-sourcemaps": "^1.6.0",
+ "gulp-util": "^3.0.7",
"hogan.js": "3.0.2",
"marked": "^0.3.6",
"minimist": "0.0.8",
@@ -37,6 +36,8 @@
"portscanner": "^1.0.0",
"prompt": "^0.2.14",
"readdir": "0.0.6",
+ "require-dir": "^0.3.0",
+ "run-sequence": "^1.2.2",
"serve-favicon": "2.3.0",
"standard": "^7.1.2",
"sync-request": "^3.0.1"
diff --git a/start.js b/start.js
index 134f416ed0..ea093d5168 100644
--- a/start.js
+++ b/start.js
@@ -1,5 +1,4 @@
var path = require('path')
-
// Check for `node_modules` folder and warn if missing
var fs = require('fs')
@@ -13,12 +12,6 @@ try {
fs.unlinkSync(path.join(__dirname, '/.port.tmp'))
} catch (e) {}
-var gruntfile = path.join(__dirname, '/Gruntfile.js')
-
-require('./node_modules/grunt/lib/grunt.js').cli({
- 'gruntfile': gruntfile
-})
-
process.on('SIGINT', function () {
// remove .port.tmp if it exists
try {