diff --git a/gulpfile.js/config.js b/gulpfile.js/config.js new file mode 100644 index 0000000000..e06f69239c --- /dev/null +++ b/gulpfile.js/config.js @@ -0,0 +1,64 @@ +var path = require('path'); + +var srcDir = 'static_src'; +var destDir = 'static'; + +var App = function(dir, options) { + this.dir = dir; + this.options = options || {}; + this.appName = this.options.appName || path.basename(dir); + this.sourceFiles = path.join('.', this.dir, srcDir); +}; +App.prototype = Object.create(null); +App.prototype.scssIncludePaths = function() { + return [this.sourceFiles]; +}; +App.prototype.scssSources = function() { + if (!this.options.scss) return []; + + return this.options.scss.map(function(file) { + return path.join(this.sourceFiles, file); + }, this); +}; + +// All the Wagtail apps that contain static files +var apps = [ + new App('wagtail/wagtailadmin', { + 'scss': [ + 'wagtailadmin/scss/core.scss', + 'wagtailadmin/scss/layouts/login.scss', + 'wagtailadmin/scss/layouts/home.scss', + 'wagtailadmin/scss/layouts/page-editor.scss', + 'wagtailadmin/scss/layouts/preview.scss', + 'wagtailadmin/scss/panels/rich-text.scss', + 'wagtailadmin/scss/userbar.scss', + 'wagtailadmin/scss/userbar_embed.scss', + ], + }), + new App('wagtail/wagtaildocs'), + new App('wagtail/wagtailembeds'), + new App('wagtail/wagtailforms'), + new App('wagtail/wagtailimages', { + 'scss': [ + 'wagtailimages/scss/add-multiple.scss', + 'wagtailimages/scss/focal-point-chooser.scss', + ], + }), + new App('wagtail/wagtailsnippets'), + new App('wagtail/wagtailusers', { + 'scss': [ + 'wagtailusers/scss/groups_edit.scss', + ], + }), + new App('wagtail/contrib/wagtailstyleguide', { + 'scss': [ + 'wagtailstyleguide/scss/styleguide.scss' + ], + }), +]; + +module.exports = { + apps: apps, + srcDir: srcDir, + destDir: destDir +} \ No newline at end of file diff --git a/gulpfile.js/index.js b/gulpfile.js/index.js new file mode 100644 index 0000000000..c198225bf1 --- /dev/null +++ b/gulpfile.js/index.js @@ -0,0 +1,2 @@ +var requireDir = require('require-dir'); +requireDir('./tasks', { recurse: true }); \ No newline at end of file diff --git a/gulpfile.js/lib/simplyCopy.js b/gulpfile.js/lib/simplyCopy.js new file mode 100644 index 0000000000..30e253bbae --- /dev/null +++ b/gulpfile.js/lib/simplyCopy.js @@ -0,0 +1,35 @@ +var gulp = require('gulp'); +var rename = require('gulp-rename'); +var gutil = require('gulp-util'); +var path = require('path'); +var config = require('../config'); + +/* + * Simple copy task - just copoes files from the source to the destination, + * with no compilation, minification, or other intelligence + * + */ + +var renameSrcToDest = function() { + return rename(function(filePath) { + filePath.dirname = filePath.dirname.replace( + '/' + config.srcDir + '/', + '/' + config.destDir + '/'); + }); +}; + + +var simpleCopyTask = function(glob) { + return function() { + var sources = config.apps.map(function(app) { + return path.join(app.sourceFiles, app.appName, glob); + }); + + return gulp.src(sources, {base: '.'}) + .pipe(renameSrcToDest()) + .pipe(gulp.dest('.')) + .on('error', gutil.log); + }; +}; + +module.exports = simpleCopyTask; \ No newline at end of file diff --git a/gulpfile.js/tasks/build.js b/gulpfile.js/tasks/build.js new file mode 100644 index 0000000000..ce105de0cd --- /dev/null +++ b/gulpfile.js/tasks/build.js @@ -0,0 +1,3 @@ +var gulp = require('gulp'); + +gulp.task('build', ['styles', 'scripts', 'images', 'fonts']); \ No newline at end of file diff --git a/gulpfile.js/tasks/default.js b/gulpfile.js/tasks/default.js new file mode 100644 index 0000000000..57f2678a9f --- /dev/null +++ b/gulpfile.js/tasks/default.js @@ -0,0 +1,3 @@ +var gulp = require('gulp'); + +gulp.task('default', ['build', 'watch']); \ No newline at end of file diff --git a/gulpfile.js/tasks/fonts.js b/gulpfile.js/tasks/fonts.js new file mode 100644 index 0000000000..9b8813a61d --- /dev/null +++ b/gulpfile.js/tasks/fonts.js @@ -0,0 +1,4 @@ +var gulp = require('gulp'); +var simpleCopyTask = require('../lib/simplyCopy'); + +gulp.task('fonts', simpleCopyTask('fonts/**/*')); \ No newline at end of file diff --git a/gulpfile.js/tasks/images.js b/gulpfile.js/tasks/images.js new file mode 100644 index 0000000000..f02632c2b6 --- /dev/null +++ b/gulpfile.js/tasks/images.js @@ -0,0 +1,4 @@ +var gulp = require('gulp'); +var simpleCopyTask = require('../lib/simplyCopy'); + +gulp.task('images', simpleCopyTask('images/**/*')); \ No newline at end of file diff --git a/gulpfile.js/tasks/scripts.js b/gulpfile.js/tasks/scripts.js new file mode 100644 index 0000000000..a34e58f1b9 --- /dev/null +++ b/gulpfile.js/tasks/scripts.js @@ -0,0 +1,4 @@ +var gulp = require('gulp'); +var simpleCopyTask = require('../lib/simplyCopy'); + +gulp.task('scripts', simpleCopyTask('js/**/*')); \ No newline at end of file diff --git a/gulpfile.js/tasks/styles.js b/gulpfile.js/tasks/styles.js new file mode 100644 index 0000000000..6ea893d26f --- /dev/null +++ b/gulpfile.js/tasks/styles.js @@ -0,0 +1,49 @@ +var gulp = require('gulp'); +var sass = require('gulp-sass'); +var config = require('../config'); +var autoprefixer = require('gulp-autoprefixer'); +var simpleCopyTask = require('../lib/simplyCopy'); +var gutil = require('gulp-util'); + +var flatten = function(arrOfArr) { + return arrOfArr.reduce(function(flat, more) { + return flat.concat(more); + }, []); +}; + +gulp.task('styles', ['styles:sass', 'styles:css']); + +gulp.task('styles:css', simpleCopyTask('css/**/*')); + +gulp.task('styles:sass', function () { + // Wagtail Sass files include each other across applications, + // e.g. wagtailimages Sass files will include wagtailadmin/sass/mixins.scss + // Thus, each app is used as an includePath. + var includePaths = flatten(config.apps.map(function(app) { return app.scssIncludePaths(); })); + + // Not all files in a directory need to be compiled, so each app defines + // its own Sass files that need to be compiled. + var sources = flatten(config.apps.map(function(app) { return app.scssSources(); })); + + return gulp.src(sources) + .pipe(sass({ + errLogToConsole: true, + includePaths: includePaths, + outputStyle: 'expanded' + })) + .pipe(autoprefixer({ + browsers: ['last 2 versions'], + cascade: false + })) + .pipe(gulp.dest(function(file) { + // e.g. wagtailadmin/scss/core.scss -> wagtailadmin/css/core.css + // Changing the suffix is done by Sass automatically + return file.base + .replace( + '/' + config.srcDir + '/', + '/' + config.destDir + '/' + ) + .replace('/scss/', '/css/'); + })) + .on('error', gutil.log); +}); diff --git a/gulpfile.js/tasks/watch.js b/gulpfile.js/tasks/watch.js new file mode 100644 index 0000000000..e19282248c --- /dev/null +++ b/gulpfile.js/tasks/watch.js @@ -0,0 +1,16 @@ +var gulp = require('gulp'); +var path = require('path'); +var config = require('../config'); + +/* + * Watch - Watch files, trigger tasks when they are modified + */ +gulp.task('watch', ['build'], function () { + config.apps.forEach(function(app) { + gulp.watch(path.join(app.sourceFiles, '*/scss/**'), ['styles:sass']); + gulp.watch(path.join(app.sourceFiles, '*/css/**'), ['styles:css']); + gulp.watch(path.join(app.sourceFiles, '*/js/**'), ['scripts']); + gulp.watch(path.join(app.sourceFiles, '*/images/**'), ['images']); + gulp.watch(path.join(app.sourceFiles, '*/fonts/**'), ['fonts']); + }); +}); diff --git a/package.json b/package.json index ba55628109..8ff35a0e20 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "gulp-sass": "~1.0.0", "gulp-sourcemaps": "~1.2.2", "gulp-util": "~2.2.14", - "jscs": "^1.12.0" + "jscs": "^1.12.0", + "require-dir": "^0.3.0" }, "dependencies": {}, "scripts": {