Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| // enable debug for gulp | |
| process.env.DEBUG = process.env.DEBUG || 'freecc:*'; | |
| require('babel-core/register'); | |
| var Rx = require('rx'), | |
| gulp = require('gulp'), | |
| path = require('path'), | |
| // utils | |
| plumber = require('gulp-plumber'), | |
| notify = require('gulp-notify'), | |
| gutil = require('gulp-util'), | |
| reduce = require('gulp-reduce-file'), | |
| sortKeys = require('sort-keys'), | |
| debug = require('debug')('freecc:gulp'), | |
| yargs = require('yargs'), | |
| concat = require('gulp-concat'), | |
| uglify = require('gulp-uglify'), | |
| merge = require('merge-stream'), | |
| babel = require('gulp-babel'), | |
| sourcemaps = require('gulp-sourcemaps'), | |
| // react app | |
| webpack = require('webpack-stream'), | |
| webpackConfig = require('./webpack.config.js'), | |
| webpackConfigNode = require('./webpack.config.node.js'), | |
| // server process | |
| nodemon = require('gulp-nodemon'), | |
| sync = require('browser-sync'), | |
| // css | |
| less = require('gulp-less'), | |
| // rev | |
| rev = require('gulp-rev'), | |
| revReplace = require('gulp-rev-replace'), | |
| revDel = require('rev-del'), | |
| // lint | |
| jsonlint = require('gulp-jsonlint'), | |
| eslint = require('gulp-eslint'), | |
| // unit-tests | |
| tape = require('gulp-tape'), | |
| tapSpec = require('tap-spec'); | |
| Rx.config.longStackSupport = true; | |
| var __DEV__ = !yargs.argv.p; | |
| var reloadDelay = 1000; | |
| var reload = sync.reload; | |
| var paths = { | |
| server: './server/server.js', | |
| serverIgnore: [ | |
| 'gulpfile.js', | |
| 'public/', | |
| '!public/js/bundle*', | |
| 'node_modules/', | |
| 'client/', | |
| 'seed', | |
| 'server/manifests/*.json', | |
| 'server/rev-manifest.json' | |
| ], | |
| publicJs: './public/js', | |
| css: 'public/css', | |
| loopback: { | |
| client: './client/loopbackClient', | |
| root: path.join(__dirname, 'client/'), | |
| clientName: 'lbApp' | |
| }, | |
| client: { | |
| src: './client', | |
| dest: 'public/js' | |
| }, | |
| vendorChallenges: [ | |
| 'public/bower_components/jshint/dist/jshint.js', | |
| 'public/bower_components/chai/chai.js', | |
| 'public/bower_components/CodeMirror/lib/codemirror.js', | |
| 'public/bower_components/CodeMirror/addon/edit/closebrackets.js', | |
| 'public/bower_components/CodeMirror/addon/edit/matchbrackets.js', | |
| 'public/bower_components/CodeMirror/addon/lint/lint.js', | |
| 'public/bower_components/CodeMirror/addon/lint/javascript-lint.js', | |
| 'public/bower_components/CodeMirror/mode/javascript/javascript.js', | |
| 'public/bower_components/CodeMirror/mode/xml/xml.js', | |
| 'public/bower_components/CodeMirror/mode/css/css.js', | |
| 'public/bower_components/CodeMirror/mode/htmlmixed/htmlmixed.js', | |
| 'node_modules/emmet-codemirror/dist/emmet.js', | |
| 'public/js/lib/loop-protect/loop-protect.js' | |
| ], | |
| vendorMain: [ | |
| 'public/bower_components/jquery/dist/jquery.min.js', | |
| 'public/bower_components/bootstrap/dist/js/bootstrap.min.js', | |
| 'public/bower_components/d3/d3.min.js', | |
| 'public/bower_components/moment/min/moment.min.js', | |
| 'public/bower_components/lightbox2/dist/js/lightbox.min.js', | |
| 'public/bower_components/rxjs/dist/rx.all.min.js' | |
| ], | |
| js: [ | |
| 'client/main.js', | |
| 'client/iFrameScripts.js', | |
| 'client/plugin.js' | |
| ], | |
| commonFramework: [ | |
| 'init', | |
| 'bindings', | |
| 'add-test-to-string', | |
| 'code-storage', | |
| 'code-uri', | |
| 'add-loop-protect', | |
| 'get-iframe', | |
| 'update-preview', | |
| 'create-editor', | |
| 'detect-unsafe-code-stream', | |
| 'display-test-results', | |
| 'execute-challenge-stream', | |
| 'output-display', | |
| 'phone-scroll-lock', | |
| 'report-issue', | |
| 'run-tests-stream', | |
| 'show-completion', | |
| 'step-challenge', | |
| 'end' | |
| ], | |
| less: './client/less/main.less', | |
| lessFiles: './client/less/*.less', | |
| manifest: 'server/manifests/', | |
| node: { | |
| src: './client', | |
| dest: 'common/app' | |
| }, | |
| syncWatch: [ | |
| 'public/**/*.*' | |
| ], | |
| challenges: [ | |
| 'seed/challenges/*/*.json' | |
| ] | |
| }; | |
| var webpackOptions = { | |
| devtool: 'inline-source-map' | |
| }; | |
| function formatCommonFrameworkPaths() { | |
| return this.map(function(script) { | |
| return 'client/commonFramework/' + script + '.js'; | |
| }); | |
| } | |
| function errorHandler() { | |
| var args = Array.prototype.slice.call(arguments); | |
| // Send error to notification center with gulp-notify | |
| notify.onError({ | |
| title: 'Compile Error', | |
| message: '<%= error %>' | |
| }).apply(this, args); | |
| // Keep gulp from hanging on this task | |
| this.emit('end'); | |
| } | |
| function delRev(dest, manifestName) { | |
| // in production do not delete old revisions | |
| if (!__DEV__) { | |
| return gutil.noop(); | |
| } | |
| return revDel({ | |
| oldManifest: path.join(paths.manifest, manifestName), | |
| dest: dest | |
| }); | |
| } | |
| gulp.task('serve', ['build-manifest'], function(cb) { | |
| var called = false; | |
| nodemon({ | |
| script: paths.server, | |
| ext: '.jsx .js .json', | |
| ignore: paths.serverIgnore, | |
| exec: path.join(__dirname, 'node_modules/.bin/babel-node'), | |
| env: { | |
| 'NODE_ENV': 'development', | |
| 'DEBUG': process.env.DEBUG || 'freecc:*' | |
| } | |
| }) | |
| .on('start', function() { | |
| if (!called) { | |
| called = true; | |
| setTimeout(function() { | |
| cb(); | |
| }, reloadDelay); | |
| } | |
| }) | |
| .on('restart', function(files) { | |
| if (files) { | |
| debug('Files that changes: ', files); | |
| } | |
| setTimeout(function() { | |
| debug('Restarting browsers'); | |
| reload(); | |
| }, reloadDelay); | |
| }); | |
| }); | |
| var syncDepenedents = [ | |
| 'serve', | |
| 'js', | |
| 'less', | |
| 'dependents', | |
| 'pack-watch', | |
| 'build-manifest' | |
| ]; | |
| gulp.task('sync', syncDepenedents, function() { | |
| sync.init(null, { | |
| proxy: 'http://localhost:3000', | |
| logLeval: 'debug', | |
| files: paths.syncWatch, | |
| port: 3001, | |
| open: false, | |
| reloadDelay: reloadDelay | |
| }); | |
| }); | |
| gulp.task('lint-js', function() { | |
| return gulp.src([ | |
| 'common/**/*.js', | |
| 'common/**/*.jsx', | |
| 'client/**/*.js', | |
| 'client/**/*.jsx', | |
| 'server/**/*.js', | |
| 'config/**/*.js' | |
| ]) | |
| .pipe(eslint()) | |
| .pipe(eslint.format()); | |
| }); | |
| gulp.task('lint-json', function() { | |
| return gulp.src(paths.challenges) | |
| .pipe(jsonlint()) | |
| .pipe(jsonlint.reporter()); | |
| }); | |
| gulp.task('test-challenges', ['lint-json']); | |
| gulp.task('pack-client', function() { | |
| if (!__DEV__) { console.log('\n\nbundling production\n\n'); } | |
| var manifestName = 'react-manifest.json'; | |
| var dest = webpackConfig.output.path; | |
| return gulp.src(webpackConfig.entry) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| .pipe(webpack(Object.assign( | |
| {}, | |
| webpackConfig, | |
| webpackOptions | |
| ))) | |
| .pipe(__DEV__ ? gutil.noop() : uglify()) | |
| .pipe(gulp.dest(dest)) | |
| .pipe(rev()) | |
| // copy files to public | |
| .pipe(gulp.dest(dest)) | |
| // create manifest | |
| .pipe(rev.manifest(manifestName)) | |
| // delete old rev | |
| .pipe(delRev( | |
| dest, | |
| manifestName | |
| )) | |
| .pipe(gulp.dest(paths.manifest)); | |
| }); | |
| var defaultStatsOptions = { | |
| colors: gutil.colors.supportsColor, | |
| hash: false, | |
| timings: false, | |
| chunks: false, | |
| chunkModules: false, | |
| modules: false, | |
| children: true, | |
| version: true, | |
| cached: false, | |
| cachedAssets: false, | |
| reasons: false, | |
| source: false, | |
| errorDetails: false | |
| }; | |
| var webpackCalled = false; | |
| gulp.task('pack-watch', function(cb) { | |
| if (webpackCalled) { | |
| console.log('webpack watching already runnning'); | |
| return cb(); | |
| } | |
| gulp.src(webpackConfig.entry) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| .pipe(webpack(Object.assign( | |
| {}, | |
| webpackConfig, | |
| webpackOptions, | |
| { watch: true } | |
| ), null, function(notUsed, stats) { | |
| if (stats) { | |
| gutil.log(stats.toString(defaultStatsOptions)); | |
| } | |
| if (!webpackCalled) { | |
| debug('webpack init completed'); | |
| webpackCalled = true; | |
| cb(); | |
| } | |
| })) | |
| .pipe(gulp.dest(webpackConfig.output.path)); | |
| }); | |
| gulp.task('pack-watch-manifest', ['pack-watch'], function() { | |
| var manifestName = 'react-manifest.json'; | |
| var dest = webpackConfig.output.path; | |
| return gulp.src(dest + '/bundle.js') | |
| .pipe(rev()) | |
| // copy files to public | |
| .pipe(gulp.dest(dest)) | |
| // create manifest | |
| .pipe(rev.manifest(manifestName)) | |
| .pipe(delRev( | |
| dest, | |
| manifestName | |
| )) | |
| .pipe(gulp.dest(paths.manifest)); | |
| }); | |
| gulp.task('pack-node', function() { | |
| return gulp.src(webpackConfigNode.entry) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| .pipe(webpack(webpackConfigNode)) | |
| .pipe(gulp.dest(webpackConfigNode.output.path)); | |
| }); | |
| gulp.task('pack', ['pack-client', 'pack-node']); | |
| gulp.task('less', function() { | |
| var manifestName = 'css-manifest.json'; | |
| var dest = paths.css; | |
| return gulp.src(paths.less) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| // compile | |
| .pipe(less({ | |
| paths: [ path.join(__dirname, 'less', 'includes') ] | |
| })) | |
| .pipe(gulp.dest(dest)) | |
| // add revision | |
| .pipe(rev()) | |
| // copy files to public | |
| .pipe(gulp.dest(dest)) | |
| // create and merge manifest | |
| .pipe(rev.manifest(manifestName)) | |
| .pipe(delRev( | |
| dest, | |
| manifestName | |
| )) | |
| .pipe(gulp.dest(paths.manifest)); | |
| }); | |
| function getFilesGlob(files) { | |
| if (!__DEV__) { | |
| return files; | |
| } | |
| return files.map(function(file) { | |
| return file | |
| .replace('.min.', '.') | |
| // moment breaks the pattern | |
| .replace('/min/', '/'); | |
| }); | |
| } | |
| gulp.task('js', function() { | |
| var manifestName = 'js-manifest.json'; | |
| var dest = paths.publicJs; | |
| var jsFiles = merge( | |
| gulp.src(getFilesGlob(paths.vendorMain)) | |
| .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) | |
| .pipe(concat('vendor-main.js')) | |
| .pipe( | |
| __DEV__ ? | |
| sourcemaps.write({ sourceRoot: '/vendor' }) : | |
| gutil.noop() | |
| ), | |
| gulp.src(paths.vendorChallenges) | |
| .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) | |
| .pipe(__DEV__ ? gutil.noop() : uglify()) | |
| .pipe(concat('vendor-challenges.js')) | |
| .pipe( | |
| __DEV__ ? | |
| sourcemaps.write({ sourceRoot: '/vendor' }) : | |
| gutil.noop() | |
| ), | |
| gulp.src(paths.js) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| .pipe(babel()) | |
| .pipe(__DEV__ ? gutil.noop() : uglify()) | |
| ); | |
| return jsFiles | |
| .pipe(gulp.dest(dest)) | |
| // create registry file | |
| .pipe(rev()) | |
| // copy revisioned assets to dest | |
| .pipe(gulp.dest(dest)) | |
| // create manifest file | |
| .pipe(rev.manifest(manifestName)) | |
| .pipe(delRev( | |
| dest, | |
| manifestName | |
| )) | |
| // copy manifest file to dest | |
| .pipe(gulp.dest(paths.manifest)); | |
| }); | |
| // commonFramework depend on iFrameScripts | |
| // and faux.js | |
| gulp.task('dependents', ['js'], function() { | |
| var manifestName = 'dependents-manifest.json'; | |
| var dest = paths.publicJs; | |
| var manifest = gulp.src( | |
| path.join(__dirname, paths.manifest, 'js-manifest.json') | |
| ); | |
| return gulp.src(formatCommonFrameworkPaths.call(paths.commonFramework)) | |
| .pipe(plumber({ errorHandler: errorHandler })) | |
| .pipe(babel()) | |
| .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) | |
| .pipe(concat('commonFramework.js')) | |
| .pipe( | |
| __DEV__ ? | |
| sourcemaps.write({ sourceRoot: '/commonFramework' }) : | |
| gutil.noop() | |
| ) | |
| .pipe(__DEV__ ? gutil.noop() : uglify()) | |
| .pipe(revReplace({ manifest: manifest })) | |
| .pipe(gulp.dest(dest)) | |
| .pipe(rev()) | |
| .pipe(gulp.dest(dest)) | |
| .pipe(rev.manifest(manifestName)) | |
| .pipe(delRev( | |
| dest, | |
| manifestName | |
| )) | |
| .pipe(gulp.dest(paths.manifest)); | |
| }); | |
| function collector(file, memo) { | |
| return Object.assign({}, JSON.parse(file.contents), memo); | |
| } | |
| function done(manifest) { | |
| return sortKeys(manifest); | |
| } | |
| function buildManifest() { | |
| return gulp.src(paths.manifest + '*.json') | |
| .pipe(reduce('rev-manifest.json', collector, done, {})) | |
| .pipe(gulp.dest('server/')); | |
| } | |
| var buildDependents = ['less', 'js', 'dependents']; | |
| if (__DEV__) { | |
| buildDependents.push('pack-watch-manifest'); | |
| } | |
| gulp.task('build-manifest', buildDependents, function() { | |
| return buildManifest(); | |
| }); | |
| gulp.task('build-manifest-watch', function() { | |
| return buildManifest(); | |
| }); | |
| gulp.task('build', [ | |
| 'less', | |
| 'js', | |
| 'dependents', | |
| 'pack-client', | |
| 'build-manifest' | |
| ]); | |
| var watchDependents = [ | |
| 'less', | |
| 'js', | |
| 'dependents', | |
| 'serve', | |
| 'sync', | |
| 'pack-watch', | |
| 'pack-watch-manifest', | |
| 'build-manifest' | |
| ]; | |
| gulp.task('reload', function() { | |
| notify({ message: 'test changed' }); | |
| reload(); | |
| }); | |
| gulp.task('watch', watchDependents, function() { | |
| gulp.watch(paths.lessFiles, ['less']); | |
| gulp.watch(paths.js.concat(paths.vendorChallenges), ['js']); | |
| gulp.watch(paths.challenges, ['test-challenges', 'reload']); | |
| gulp.watch(paths.js, ['js', 'dependents']); | |
| gulp.watch( | |
| formatCommonFrameworkPaths.call(paths.commonFramework), | |
| ['dependents'] | |
| ); | |
| gulp.watch(paths.manifest + '/*.json', ['build-manifest-watch']); | |
| gulp.watch(webpackConfig.output.path + '/bundle.js', ['pack-watch-manifest']); | |
| }); | |
| gulp.task('default', [ | |
| 'less', | |
| 'serve', | |
| 'pack-watch', | |
| 'pack-watch-manifest', | |
| 'build-manifest-watch', | |
| 'watch', | |
| 'sync' | |
| ]); | |
| gulp.task('test', function() { | |
| return gulp.src('test/**/*.js') | |
| .pipe(tape({ | |
| reporter: tapSpec() | |
| })); | |
| }); |