diff --git a/.eslintrc b/.eslintrc index 435e9d7..992f220 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,7 @@ { "extends": "kellyirc", "parser": "babel-eslint", + "cache": true, "env": { "node": true, "es6": true, diff --git a/gulp/_common.js b/gulp/_common.js new file mode 100644 index 0000000..63122a4 --- /dev/null +++ b/gulp/_common.js @@ -0,0 +1,6 @@ + +const fs = require('fs'); +const execSync = require('child_process').execSync; + +export const getPaths = () => JSON.parse(fs.readFileSync('./package.json')).gulp; +export const currentTag = () => execSync('git describe --abbrev=0').toString().trim(); \ No newline at end of file diff --git a/gulp/browser.js b/gulp/browser.js new file mode 100644 index 0000000..27fddf1 --- /dev/null +++ b/gulp/browser.js @@ -0,0 +1,32 @@ + +const _ = require('lodash'); + +const gulp = require('gulp'); +const filter = require('gulp-filter'); +const ghPages = require('gulp-gh-pages'); + +const browserSync = require('browser-sync').create(); + +const getPaths = require('./_common').getPaths; + +gulp.task('deploy', () => { + const paths = getPaths(); + return gulp.src(`${paths.dist}/**/*`, { base: paths.dist }) + .pipe(filter((file) => { + return !_.contains(file.path, 'node_modules') && !_.contains(file.path, 'nw') && !_.contains(file.path, 'package'); + })) + .pipe(ghPages()); +}); + +gulp.task('reload', () => { + browserSync.reload(); +}); + +gulp.task('connect', ['build:all'], () => { + browserSync.init({ + port: 8000, + server: { + baseDir: './dist' + } + }); +}); \ No newline at end of file diff --git a/gulp/clean.js b/gulp/clean.js new file mode 100644 index 0000000..0d4a9db --- /dev/null +++ b/gulp/clean.js @@ -0,0 +1,16 @@ + +const gulp = require('gulp'); +const del = require('del'); +const vinylPaths = require('vinyl-paths'); + +const getPaths = require('./_common').getPaths; + +gulp.task('clean:libcss', () => gulp.src(getPaths().dist+'/css/lib.min.css').pipe(vinylPaths(del))); + +gulp.task('clean:libjs', () => gulp.src(getPaths().dist+'/js/lib.min.js').pipe(vinylPaths(del))); + +gulp.task('clean:css', () => gulp.src(getPaths().dist+'/css/main.min.css').pipe(vinylPaths(del))); + +gulp.task('clean:js', () => gulp.src(getPaths().dist+'/js/main.min.js').pipe(vinylPaths(del))); + +gulp.task('clean:all', ['clean:libcss', 'clean:libjs', 'clean:css', 'clean:js']); \ No newline at end of file diff --git a/gulp/compile.js b/gulp/compile.js new file mode 100644 index 0000000..5d01f14 --- /dev/null +++ b/gulp/compile.js @@ -0,0 +1,104 @@ + +const gulp = require('gulp'); +const util = require('gulp-util'); +const concat = require('gulp-concat'); +const minifyCss = require('gulp-minify-css'); +const ngAnnotate = require('gulp-ng-annotate'); +const sourcemaps = require('gulp-sourcemaps'); +const sass = require('gulp-sass'); +const autoprefixer = require('gulp-autoprefixer'); +const gulpif = require('gulp-if'); +const rename = require('gulp-rename'); +const jade = require('gulp-jade'); + +const source = require('vinyl-source-stream'); + +const browserify = require('browserify'); +const babelify = require('babelify'); +const errorify = require('errorify'); +const watchify = require('watchify'); + +const getPaths = require('./_common').getPaths; + +gulp.task('compile:libcss', ['clean:libcss'], () => { + return gulp.src(getPaths().libcss) + .pipe(concat('lib.min.css')) + .pipe(minifyCss({ + keepSpecialComments: false, + removeEmpty: true + })) + .pipe(gulp.dest(getPaths().dist + 'css')) + .on('error', util.log); +}); + +gulp.task('compile:libjs', ['clean:libjs'], () => { + return gulp.src(getPaths().libjs) + .pipe(concat('lib.min.js')) + .pipe(gulp.dest(getPaths().dist + 'js')) + .on('error', util.log); +}); + +let bundler = null; + +gulp.task('compile:js', ['eslint', 'clean:js'], () => { + + const bundlee = function() { + return bundler + .bundle() + .pipe(source('js/main.min.js')) + .pipe(ngAnnotate()) + .pipe(gulp.dest(getPaths().dist)) + .on('error', util.log); + }; + + if(global.watching && bundler) return bundlee(); + + bundler = browserify({ + cache: {}, packageCache: {}, fullPaths: true, + entries: [getPaths().entry], + debug: global.watching + }) + .transform(babelify); + + if(global.watching) { + bundler.plugin(errorify); + } + + if (global.watching) { + bundler = watchify(bundler); + bundler.on('update', bundlee); + } + + return bundlee(); +}); + +gulp.task('compile:sass', ['clean:css'], () => { + return gulp.src(getPaths().sass) + .pipe(sourcemaps.init()) + .pipe(sass().on('error', sass.logError)) + .pipe(concat('css/main.css')) + .pipe(autoprefixer({ + browsers: ['last 2 versions'], + cascade: false + })) + .pipe(gulpif(!global.watching, minifyCss({ + keepSpecialComments: false, + removeEmpty: true + }))) + .pipe(rename({ suffix: '.min' })) + .pipe(sourcemaps.write()) + .pipe(gulp.dest(getPaths().dist)) + .on('error', util.log); +}); + +gulp.task('compile:jade', () => { + return gulp.src(getPaths().jade) + .pipe(concat('index.html')) + .pipe(jade({ + pretty: global.watching + })) + .pipe(gulp.dest(getPaths().dist)) + .on('error', util.log); +}); + +gulp.task('build:lib', ['compile:libjs', 'compile:libcss']); \ No newline at end of file diff --git a/gulp/copy.js b/gulp/copy.js new file mode 100644 index 0000000..43a1c05 --- /dev/null +++ b/gulp/copy.js @@ -0,0 +1,17 @@ + +const gulp = require('gulp'); +const util = require('gulp-util'); + +const getPaths = require('./_common').getPaths; + +gulp.task('copy:dist', () => { + return gulp.src(getPaths().favicon) + .pipe(gulp.dest(getPaths().dist)) + .on('error', util.log); +}); + +gulp.task('copy:nw', () => { + return gulp.src(['./package.json', 'nw-setup/**/*']) + .pipe(gulp.dest(getPaths().dist)) + .on('error', util.log); +}); \ No newline at end of file diff --git a/gulp/lint.js b/gulp/lint.js new file mode 100644 index 0000000..9f429bd --- /dev/null +++ b/gulp/lint.js @@ -0,0 +1,12 @@ + +const gulp = require('gulp'); +const eslint = require('gulp-eslint'); + +const getPaths = require('./_common').getPaths; + +gulp.task('eslint', () => { + return gulp.src(getPaths().js) + .pipe(eslint({ useEslintrc: true, cache: true })) + .pipe(eslint.format()) + .pipe(eslint.failOnError()); +}); \ No newline at end of file diff --git a/gulp/test.js b/gulp/test.js new file mode 100644 index 0000000..87e9442 --- /dev/null +++ b/gulp/test.js @@ -0,0 +1,12 @@ + +const gulp = require('gulp'); +const mocha = require('gulp-mocha'); + +const getPaths = require('./_common').getPaths; + +gulp.task('test', function() { + const paths = getPaths(); + + gulp.src(paths.testjs) + .pipe(mocha()); +}); \ No newline at end of file diff --git a/gulp/version.js b/gulp/version.js new file mode 100644 index 0000000..51916ea --- /dev/null +++ b/gulp/version.js @@ -0,0 +1,52 @@ + +const gulp = require('gulp'); +const fs = require('fs'); +const git = require('gulp-git'); +const bump = require('gulp-bump'); +const filter = require('gulp-filter'); +const tagVersion = require('gulp-tag-version'); + +const runSequence = require('run-sequence'); +const changelog = require('conventional-changelog'); + +const currentTag = require('./_common').currentTag; + +const versionSources = ['./bower.json', './package.json']; + +const versionStream = (type) => { + return gulp.src(versionSources) + .pipe(bump({ type: type })) + .pipe(gulp.dest('./')) + .pipe(filter('package.json')) + .pipe(tagVersion({ prefix: '' })); +}; + +const commitStream = (type) => { + const tag = currentTag(); + return gulp.src(versionSources.concat('CHANGELOG.md')) + .pipe(git.commit(`chore(version): release ${type} version ${tag}`, function() { + git.push(); + git.push('origin', 'master', { args: '--tags' }); + })); +}; + +const pushStream = () => { + git.push(); + git.push('origin', 'master', { args: '--tags' }); +}; + +gulp.task('generate:changelog', () => { + return changelog({ + releaseCount: 0, + preset: 'angular' + }) + .pipe(fs.createWriteStream('CHANGELOG.md')); +}); + +gulp.task('bump:patch:tag', () => versionStream('patch')); +gulp.task('bump:minor:tag', () => versionStream('minor')); +gulp.task('bump:major:tag', () => versionStream('major')); + +gulp.task('bump:patch:commit', () => runSequence('bump:patch:tag', 'generate:changelog', () => commitStream('patch') && pushStream())); +gulp.task('bump:minor:commit', () => runSequence('bump:minor:tag', 'generate:changelog', () => commitStream('minor') && pushStream())); +gulp.task('bump:major:commit', () => runSequence('bump:major:tag', 'generate:changelog', () => commitStream('major') && pushStream())); \ No newline at end of file diff --git a/gulp/watch.js b/gulp/watch.js new file mode 100644 index 0000000..16aab89 --- /dev/null +++ b/gulp/watch.js @@ -0,0 +1,27 @@ + +const gulp = require('gulp'); +const runSequence = require('run-sequence'); + +const getPaths = require('./_common').getPaths; + +gulp.task('watch:sass', () => { + global.watching = true; + return gulp.watch(getPaths().sass, () => { runSequence('compile:sass', 'reload'); }); +}); + +gulp.task('watch:jade', () => { + global.watching = true; + return gulp.watch(getPaths().jade, () => { runSequence('compile:jade', 'reload'); }); +}); + +gulp.task('watch:js', () => { + global.watching = true; + return gulp.watch(getPaths().js, () => { runSequence('compile:js', 'reload'); }); +}); + +gulp.task('watch:package', () => { + global.watching = true; + return gulp.watch('package.json', () => { runSequence('compile:libjs', 'compile:libcss', 'reload'); }); +}); + +gulp.task('watch:all', ['watch:package', 'watch:sass', 'watch:jade', 'watch:js']); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 46af0ed..b9606bb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,266 +2,26 @@ require('babel/register'); var gulp = require('gulp'); -var del = require('del'); -var source = require('vinyl-source-stream'); -var vinylPaths = require('vinyl-paths'); -var browserify = require('browserify'); -var babelify = require('babelify'); -var errorify = require('errorify'); -var watchify = require('watchify'); -var fs = require('fs'); -var git = require('gulp-git'); -var util = require('gulp-util'); -var open = require('gulp-open'); -var concat = require('gulp-concat'); -var rename = require('gulp-rename'); -var minifyCss = require('gulp-minify-css'); -var streamify = require('gulp-streamify'); -var uglify = require('gulp-uglify'); -var sass = require('gulp-sass'); -var jade = require('gulp-jade'); -var sourcemaps = require('gulp-sourcemaps'); -var connect = require('gulp-connect'); -var gulpif = require('gulp-if'); -var ghPages = require('gulp-gh-pages'); -var bump = require('gulp-bump'); -var tagVersion = require('gulp-tag-version'); -var filter = require('gulp-filter'); -var ngAnnotate = require('gulp-ng-annotate'); -var uncss = require('gulp-uncss'); -var eslint = require('gulp-eslint'); -var autoprefixer = require('gulp-autoprefixer'); -var changed = require('gulp-changed'); -var mocha = require('gulp-mocha'); +require('./gulp/browser'); +require('./gulp/clean'); +require('./gulp/compile'); +require('./gulp/copy'); +require('./gulp/lint'); +require('./gulp/test'); +require('./gulp/version'); +require('./gulp/watch'); -var watching = false; +gulp.task('bump:patch', ['bump:patch:tag', 'bump:patch:commit']); +gulp.task('bump:minor', ['bump:minor:tag', 'bump:minor:commit']); +gulp.task('bump:major', ['bump:major:tag', 'bump:major:commit']); -var getPaths = function() { - return JSON.parse(fs.readFileSync('./package.json')).gulp; -}; +gulp.task('release:patch', ['bump:patch', 'deploy']); +gulp.task('release:minor', ['bump:minor', 'deploy']); +gulp.task('release:major', ['bump:major', 'deploy']); -gulp.task('deploy', function() { - var paths = getPaths(); +gulp.task('build:all', ['copy:dist', 'build:lib', 'compile:all']); +gulp.task('compile:all', ['compile:js', 'compile:sass', 'compile:jade']); +gulp.task('check', ['test', 'build:all']); - return gulp.src(paths.dist + '**/*') - .pipe(ghPages()); -}); - -gulp.task('clean', function() { - var paths = getPaths(); - - return gulp.src(paths.dist) - .pipe(vinylPaths(del)) - .on('error', util.log); -}); - -gulp.task('copy:favicon', ['clean'], function() { - var paths = getPaths(); - - return gulp.src(paths.favicon) - .pipe(gulp.dest(paths.dist)) - .on('error', util.log); -}); - -gulp.task('copy:fonts', ['clean'], function() { - var paths = getPaths(); - - return gulp.src(paths.font) - .pipe(gulp.dest(paths.dist+'/fonts')) - .on('error', util.log); -}); - -gulp.task('build:libcss', ['clean', 'compile:jade', 'compile:sass'], function() { - var paths = getPaths(); - - return gulp.src(paths.libcss) - .pipe(changed(paths.dist)) - .pipe(concat('lib.min.css')) - /* .pipe(uncss({ - html: paths.dist + 'index.html' - })) */ - .pipe(minifyCss({ - keepSpecialComments: false, - removeEmpty: true - })) - .pipe(gulp.dest(paths.dist + 'css')) - .on('error', util.log); -}); - -gulp.task('build:libjs', ['clean'], function() { - var paths = getPaths(); - - return gulp.src(paths.libjs) - .pipe(changed(paths.dist)) - .pipe(gulpif(!watching, uglify({ outSourceMaps: false }))) - .pipe(concat('lib.min.js')) - .pipe(gulp.dest(paths.dist + 'js')) - .on('error', util.log); -}); - -gulp.task('compile:js', ['eslint', 'clean'], function() { - var paths = getPaths(); - - var bundler = browserify({ - cache: {}, packageCache: {}, fullPaths: watching, - entries: [paths.entry], - debug: watching - }) - .transform(babelify); - - if(watching) { - bundler.plugin(errorify); - } - - var bundlee = function() { - return bundler - .bundle() - .pipe(source('js/main.min.js')) - .pipe(gulpif(!watching, streamify(uglify({ outSourceMaps: false })))) - .pipe(ngAnnotate()) - .pipe(gulp.dest(paths.dist)) - .on('error', util.log); - }; - - if (watching) { - bundler = watchify(bundler); - bundler.on('update', bundlee); - } - - return bundlee(); -}); - -gulp.task('eslint', function() { - var paths = getPaths(); - - return gulp.src(paths.js) - .pipe(changed(paths.dist)) - .pipe(eslint({ useEslintrc: true })) - .pipe(eslint.format()) - .pipe(eslint.failOnError()); -}); - -gulp.task('compile:sass', ['clean', 'compile:jade'], function() { - var paths = getPaths(); - - return gulp.src(paths.sass) - .pipe(sourcemaps.init()) - .pipe(sass().on('error', sass.logError)) - .pipe(concat('css/main.css')) - /* .pipe(uncss({ - html: paths.dist + 'index.html' - })) */ - .pipe(autoprefixer({ - browsers: ['last 2 versions'], - cascade: false - })) - .pipe(gulpif(!watching, minifyCss({ - keepSpecialComments: false, - removeEmpty: true - }))) - .pipe(rename({ suffix: '.min' })) - .pipe(sourcemaps.write()) - .pipe(gulp.dest(paths.dist)) - .on('error', util.log); -}); - -gulp.task('compile:jade', ['clean'], function() { - var paths = getPaths(); - - return gulp.src(paths.jade) - .pipe(concat('index.html')) - .pipe(jade({ - pretty: watching - })) - .pipe(gulp.dest(paths.dist)) - .on('error', util.log); -}); - -gulp.task('reload', ['build'], function() { - return gulp.src('dist/*.html') - .pipe(connect.reload()) - .on('error', util.log); -}); - -gulp.task('connect', function() { - connect.server({ - root: ['./dist'], - port: 8000, - livereload: true - }); -}); - -gulp.task('open', ['build'], function() { - gulp.src('./dist/index.html') - .pipe(open({ - uri: 'http://127.0.0.1:8000' - })); -}); - -gulp.task('watch', function() { - var paths = getPaths(); - - watching = true; - return gulp.watch([paths.sass, paths.jade, paths.js, 'package.json'], ['reload']); -}); - - -var versionSources = ['./bower.json', './package.json']; - -var versionStream = function(type) { - return gulp.src(versionSources) - .pipe(bump({ type: type })) - .pipe(gulp.dest('./')) - .pipe(filter('package.json')) - .pipe(tagVersion({ prefix: '' })); -}; - -var commitStream = function(type) { - return gulp.src(versionSources) - .pipe(git.commit(type + ' version bump', function() { - git.push(); - git.push('origin', 'master', { args: '--tags' }); - })); -}; - -var pushStream = function() { - git.push(); - git.push('origin', 'master', { args: '--tags' }); -}; - -gulp.task('bump:patch:tag', function() { - return versionStream('patch'); -}); - -gulp.task('bump:minor:tag', function() { - return versionStream('minor'); -}); - -gulp.task('bump:major:tag', function() { - return versionStream('major'); -}); - -gulp.task('bump:patch:commit', ['bump:patch:tag'], function() { - return commitStream('patch') && pushStream(); -}); - -gulp.task('bump:minor:commit', ['bump:minor:tag'],function() { - return commitStream('minor') && pushStream(); -}); - -gulp.task('bump:major:commit', ['bump:major:tag'],function() { - return commitStream('major') && pushStream(); -}); - -gulp.task('test', function() { - var paths = getPaths(); - - gulp.src(paths.testjs) - .pipe(mocha()); -}); - -gulp.task('default', ['build', 'connect', 'open', 'watch']); -gulp.task('build', ['clean', 'copy:favicon', 'copy:fonts', 'build:libjs', 'build:libcss', 'compile']); -gulp.task('compile', ['compile:js', 'compile:sass', 'compile:jade']); -gulp.task('check', ['test', 'build']); +gulp.task('default', ['clean:all', 'build:all', 'connect', 'watch:all']); \ No newline at end of file diff --git a/package.json b/package.json index d860748..4d26192 100644 --- a/package.json +++ b/package.json @@ -12,41 +12,34 @@ "babel": "^5.8.23", "babel-eslint": "^4.1.0", "babelify": "^6.2.0", - "bower": "~1.5.2", - "browserify": "~11.0.1", - "chai": "^3.2.0", - "del": "~1.2.1", + "bower": "~1.6.3", + "browser-sync": "^2.9.11", + "browserify": "~11.2.0", + "conventional-changelog": "^0.5.0", + "del": "~2.0.2", "errorify": "^0.3.1", - "eslint-config-kellyirc": "^2.0.0", + "eslint-config-kellyirc": "^3.1.0", "gulp": "~3.9.0", - "gulp-autoprefixer": "^2.3.1", - "gulp-bump": "~0.3.1", - "gulp-changed": "^1.3.0", + "gulp-autoprefixer": "^3.0.2", + "gulp-bump": "^1.0.0", "gulp-concat": "~2.6.0", - "gulp-connect": "~2.2.0", "gulp-eslint": "^1.0.0", "gulp-filter": "~3.0.1", + "gulp-folders": "^1.1.0", "gulp-gh-pages": "~0.5.2", - "gulp-git": "^1.5.0", - "gulp-if": "~1.2.5", + "gulp-if": "^2.0.0", "gulp-jade": "~1.1.0", - "gulp-load-plugins": "^0.10.0", "gulp-minify-css": "~1.2.1", "gulp-mocha": "^2.1.3", "gulp-ng-annotate": "^1.1.0", - "gulp-open": "~1.0.0", "gulp-rename": "~1.2.2", "gulp-sass": "^2.0.4", "gulp-sourcemaps": "^1.5.2", - "gulp-streamify": "~1.0.0", "gulp-tag-version": "~1.3.0", - "gulp-uglify": "~1.3.0", - "gulp-uncss": "^1.0.3", "gulp-util": "~3.0.6", - "gulp-watch": "~4.3.5", - "mocha": "^2.3.0", - "tiny-lr": "~0.1.6", - "vinyl-paths": "~1.0.0", + "gulp-zip": "^3.0.2", + "run-sequence": "^1.1.4", + "vinyl-paths": "^2.0.0", "vinyl-source-stream": "~1.1.0", "watchify": "~3.4.0" },