From cda3cfc641d0ab66f4b4f86acc8cfc5747341824 Mon Sep 17 00:00:00 2001 From: Vivian Guillen Date: Fri, 3 Jun 2016 17:31:36 -0700 Subject: [PATCH] merge in @@viviangb #585 --- cookiecutter.json | 5 +- hooks/post_gen_project.py | 38 +++++-- {{cookiecutter.project_slug}}/gulpfile.js | 107 ++++++++++++++++++ {{cookiecutter.project_slug}}/package.json | 37 ++++-- .../static/sass/project.scss | 21 ++++ 5 files changed, 188 insertions(+), 20 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/gulpfile.js diff --git a/cookiecutter.json b/cookiecutter.json index 65879a69..fb01784a 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -20,7 +20,6 @@ "use_python2": "n", "use_docker": "y", "use_heroku": "n", - "use_grunt": "n", - "open_source_license": ["MIT", "BSD", "Apache Software License 2.0", "Not open source"], - "_cookiecutter_version": "Minimum cookiecutter version" + "js_task_runner": ["Gulp", "Grunt", "None"], + "open_source_license": ["MIT", "BSD", "Apache Software License 2.0", "Not open source"] } diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index cffb052e..72abbfca 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -134,7 +134,25 @@ def remove_grunt_files(): """ Removes files needed for grunt if it isn't going to be used """ - for filename in ["Gruntfile.js", "package.json"]: + for filename in ["Gruntfile.js"]: + os.remove(os.path.join( + PROJECT_DIRECTORY, filename + )) + +def remove_gulp_files(): + """ + Removes files needed for grunt if it isn't going to be used + """ + for filename in ["gulpfile.js"]: + os.remove(os.path.join( + PROJECT_DIRECTORY, filename + )) + +def remove_packageJSON_file(): + """ + Removes files needed for grunt if it isn't going to be used + """ + for filename in ["package.json"]: os.remove(os.path.join( PROJECT_DIRECTORY, filename )) @@ -176,18 +194,24 @@ if '{{ cookiecutter.use_heroku }}'.lower() != 'y': if '{{ cookiecutter.use_docker }}'.lower() != 'y': remove_docker_files() -# 6. Removes all grunt files if it isn't going to be used -if '{{ cookiecutter.use_grunt }}'.lower() != 'y': +# 6. Removes all JS task manager files if it isn't going to be used +if '{{ cookiecutter.js_task_runner}}'.lower() == 'gulp': remove_grunt_files() +elif '{{ cookiecutter.js_task_runner}}'.lower() == 'grunt': + remove_gulp_files() +else: + remove_gulp_files() + remove_grunt_files() + remove_packageJSON_file() -# 7. Display a warning if use_docker and use_grunt are selected. Grunt isn't supported by our +# 7. Display a warning if use_docker and js task runner are selected. Grunt isn't supported by our # docker config atm. -if '{{ cookiecutter.use_grunt }}'.lower() == 'y' and '{{ cookiecutter.use_docker }}'.lower() == 'y': +if '{{ cookiecutter.js_task_runner }}'.lower() in ['grunt', 'gulp'] and '{{ cookiecutter.use_docker }}'.lower() == 'y': print( - "You selected to use docker and grunt. This is NOT supported out of the box for now. You " + "You selected to use docker and a JS task runner. This is NOT supported out of the box for now. You " "can continue to use the project like you normally would, but you will need to add a " - " grunt service to your docker configuration manually." + "js task runner service to your docker configuration manually." ) # 7. Display a warning if use_docker and use_mailhog are selected. Mailhog isn't supported by our diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js new file mode 100644 index 00000000..e5b0df9d --- /dev/null +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -0,0 +1,107 @@ + +//////////////////////////////// + //Setup// +//////////////////////////////// + +// Plugins +var gulp = require('gulp'), + pjson = require('./package.json'), + gutil = require('gulp-util'), + sass = require('gulp-sass'), + autoprefixer = require('gulp-autoprefixer'), + cssnano = require('gulp-cssnano'), + rename = require('gulp-rename'), + del = require('del'), + plumber = require('gulp-plumber'), + pixrem = require('gulp-pixrem'), + uglify = require('gulp-uglify'), + imagemin = require('gulp-imagemin'), + exec = require('gulp-exec'), + runSequence = require('run-sequence'), + browserSync = require('browser-sync'); + + +// Relative paths function +var pathsConfig = function (appName) { + this.app = "./" + (appName || pjson.name); + + return { + app: this.app, + templates: this.app + '/templates', + css: this.app + '/static/css', + sass: this.app + '/static/sass', + fonts: this.app + '/static/fonts', + images: this.app + '/static/images', + js: this.app + '/static/js', + } +}; + +var paths = pathsConfig(); + +//////////////////////////////// + //Tasks// +//////////////////////////////// + +// Styles autoprefixing and minification +gulp.task('styles', function() { + return gulp.src(paths.sass + '/project.scss') + .pipe(sass().on('error', sass.logError)) + .pipe(plumber()) // Checks for errors + .pipe(autoprefixer({browsers: ['last 2 version']})) // Adds vendor prefixes + .pipe(pixrem()) // add fallbacks for rem units + .pipe(gulp.dest(paths.css)) + .pipe(rename({ suffix: '.min' })) + .pipe(cssnano()) // Minifies the result + .pipe(gulp.dest(paths.css)); +}); + +// Javascript minification +gulp.task('scripts', function() { + return gulp.src(paths.js + '/project.js') + .pipe(plumber()) // Checks for errors + .pipe(uglify()) // Minifies the js + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest(paths.js)); +}); + +// Image compression +gulp.task('imgCompression', function(){ + return gulp.src(paths.images + '/*') + .pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images + .pipe(gulp.dest(paths.images)) +}); + +// Run django server +gulp.task('runServer', function() { + exec('python manage.py runserver', function (err, stdout, stderr) { + console.log(stdout); + console.log(stderr); + }); +}); + +// Browser sync server for live reload +gulp.task('browserSync', function() { + browserSync.init( + [paths.css + "/*.css", paths.js + "*.js", paths.templates + '*.html'], { + proxy: "localhost:8000" + }); +}); + +// Default task +gulp.task('default', function() { + runSequence(['styles', 'scripts', 'imgCompression'], 'runServer', 'browserSync'); +}); + +//////////////////////////////// + //Watch// +//////////////////////////////// + +// Watch +gulp.task('watch', ['default'], function() { + + gulp.watch(paths.sass + '/*.scss', ['styles']); + gulp.watch(paths.js + '/*.js', ['scripts']); + gulp.watch(paths.images + '/*', ['imgCompression']); + gulp.watch('templates/*.html'); + +}); diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json index 47cf6944..2be4b50c 100644 --- a/{{cookiecutter.project_slug}}/package.json +++ b/{{cookiecutter.project_slug}}/package.json @@ -3,17 +3,34 @@ "version": "{{ cookiecutter.version }}", "dependencies": {}, "devDependencies": { - "grunt": "~0.4.5", - "grunt-contrib-watch": "~0.6.1", - "grunt-bg-shell": "~2.3.1", - "connect-livereload": "~0.3.2", - "time-grunt": "~1.2.1", - "load-grunt-tasks": "~3.2.0", - "grunt-sass": "~1.0.0", - "grunt-postcss": "~0.5.5", - "cssnano": "~2.1.0", + {% if cookiecutter.js_task_runner == 'Grunt' %} "autoprefixer-core": "~5.2.1", - "pixrem": "~1.3.1" + "connect-livereload": "~0.3.2", + "cssnano": "~2.1.0", + "grunt": "~0.4.5", + "grunt-bg-shell": "~2.3.1", + "grunt-contrib-watch": "~0.6.1", + "grunt-postcss": "~0.5.5", + "grunt-sass": "~1.0.0", + "load-grunt-tasks": "~3.2.0", + "pixrem": "~1.3.1", + "time-grunt": "~1.2.1" + {% elif cookiecutter.js_task_runner == 'Gulp' %} + "browser-sync": "^2.12.10", + "del": "^2.2.0", + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.0", + "gulp-cssnano": "^2.1.2", + "gulp-exec": "^2.1.2", + "gulp-imagemin": "^3.0.1", + "gulp-pixrem": "^1.0.0", + "gulp-plumber": "^1.1.0", + "gulp-rename": "^1.2.2", + "gulp-sass": "^2.3.1", + "gulp-uglify": "^1.5.3", + "gulp-util": "^3.0.7", + "run-sequence": "^1.2.1" + {% endif %} }, "engines": { "node": ">=0.8.0" diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss index e737d593..54632b2d 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss @@ -1,5 +1,10 @@ + // project specific CSS goes here +//////////////////////////////// + //Variables// +//////////////////////////////// + // Alert colors $white: #fff; @@ -9,6 +14,10 @@ $pink: #f2dede; $dark-pink: #eed3d7; $red: #b94a48; +//////////////////////////////// + //Alerts// +//////////////////////////////// + // bootstrap alert CSS, translated to the django-standard levels of // debug, info, success, warning, error @@ -24,8 +33,16 @@ $red: #b94a48; color: $red; } +//////////////////////////////// + //Navbar// +//////////////////////////////// + // This is a fix for the bootstrap4 alpha release +.navbar { + border-radius: 0px; +} + @media (max-width: 47.9em) { .navbar-nav .nav-item { display: inline-block; @@ -42,6 +59,10 @@ $red: #b94a48; } } +//////////////////////////////// + //Django Toolbar// +//////////////////////////////// + // Display django-debug-toolbar. // See https://github.com/django-debug-toolbar/django-debug-toolbar/issues/742 // and https://github.com/pydanny/cookiecutter-django/issues/317