diff --git a/app/directives/badges/badge-tooltip.spec.js b/app/directives/badges/badge-tooltip.spec.js
index bff215de8..afc066e09 100644
--- a/app/directives/badges/badge-tooltip.spec.js
+++ b/app/directives/badges/badge-tooltip.spec.js
@@ -1,5 +1,5 @@
/* jshint -W117, -W030 */
-describe('Badge Tooltiop Directive', function() {
+describe('Badge Tooltip Directive', function() {
var scope;
var element;
var badge = mockData.getMockBadge();
diff --git a/app/index.jade b/app/index.jade
index 65b8274b9..ed2cf125e 100644
--- a/app/index.jade
+++ b/app/index.jade
@@ -16,7 +16,6 @@ html
link(rel='stylesheet', href='../bower_components/angular-dropdowns/dist/angular-dropdowns.css')
link(rel='stylesheet', href='../bower_components/intro.js/introjs.css')
link(rel='stylesheet', href='../bower_components/angularjs-toaster/toaster.css')
- link(rel='stylesheet', href='../bower_components/devicon/devicon.min.css')
link(rel='stylesheet', href='../bower_components/fontawesome/css/font-awesome.css')
link(rel='stylesheet', href='../bower_components/ng-notifications-bar/dist/ngNotificationsBar.min.css')
link(rel='stylesheet', href='../bower_components/ngDialog/css/ngDialog.css')
diff --git a/app/specs.html b/app/specs.html
index d70c81ed1..e8b01d7cc 100644
--- a/app/specs.html
+++ b/app/specs.html
@@ -51,6 +51,7 @@
+
@@ -167,6 +168,7 @@
+
@@ -175,7 +177,6 @@
-
@@ -255,36 +256,35 @@
-
+
-
+
-
-
-
-
+
+
+
+
-
-
+
-
+
diff --git a/app/topcoder.constants.js b/app/topcoder.constants.js
old mode 100755
new mode 100644
diff --git a/assets/css/account/account.scss b/assets/css/account/account.scss
index fa5deea71..9f4333598 100644
--- a/assets/css/account/account.scss
+++ b/assets/css/account/account.scss
@@ -186,7 +186,7 @@
}
.github {
.ico {
- background-image: url(/images/svg/github.svg);
+ background-image: url(/images/github.svg);
background-repeat: no-repeat;
color: #404041;
}
@@ -194,7 +194,7 @@
.facebook {
margin-left: 41px;
.ico {
- background-image: url(/images/svg/facebook.svg);
+ background-image: url(/images/facebook.svg);
background-repeat: no-repeat;
color: #0d72b9;
}
@@ -202,7 +202,7 @@
.google-plus {
margin-left: 43px;
.ico {
- background-image: url(/images/svg/gplus.svg);
+ background-image: url(/images/gplus.svg);
background-position: center;
background-repeat: no-repeat;
border: 1px solid #d1d3d4;
@@ -213,7 +213,7 @@
.twitter {
margin-left: 40px;
.ico {
- background-image: url(/images/svg/twitter.svg);
+ background-image: url(/images/twitter.svg);
background-repeat: no-repeat;
color: #26a9e0;
}
diff --git a/assets/css/directives/external-web-link.scss b/assets/css/directives/external-web-link.scss
index 6c8811045..9a49fcc4e 100644
--- a/assets/css/directives/external-web-link.scss
+++ b/assets/css/directives/external-web-link.scss
@@ -1,4 +1,4 @@
-@import 'tc-includes';
+@import 'topcoder/tc-includes';
external-web-link {
.web-link {
@@ -23,7 +23,7 @@ external-web-link {
}
.form-field {
@include form-field;
- @include ui-form-placeholder;
+
&:disabled {
color: #B7B7B7;
}
@@ -31,7 +31,7 @@ external-web-link {
.form-field-focused {
@include form-field-focused;
}
-
+
.validation-bar.url {
flex: 1;
width: auto;
diff --git a/assets/fonts/devicon.eot b/assets/fonts/devicon.eot
deleted file mode 100755
index 8a40b765a..000000000
Binary files a/assets/fonts/devicon.eot and /dev/null differ
diff --git a/assets/fonts/devicon.svg b/assets/fonts/devicon.svg
deleted file mode 100755
index 68a19decf..000000000
--- a/assets/fonts/devicon.svg
+++ /dev/null
@@ -1,155 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/assets/fonts/devicon.ttf b/assets/fonts/devicon.ttf
deleted file mode 100755
index a7cd8f4dd..000000000
Binary files a/assets/fonts/devicon.ttf and /dev/null differ
diff --git a/assets/fonts/devicon.woff b/assets/fonts/devicon.woff
deleted file mode 100755
index e1e0d112d..000000000
Binary files a/assets/fonts/devicon.woff and /dev/null differ
diff --git a/assets/images/svg/facebook.svg b/assets/images/facebook.svg
similarity index 100%
rename from assets/images/svg/facebook.svg
rename to assets/images/facebook.svg
diff --git a/assets/images/svg/github.svg b/assets/images/github.svg
similarity index 100%
rename from assets/images/svg/github.svg
rename to assets/images/github.svg
diff --git a/assets/images/svg/gplus.svg b/assets/images/gplus.svg
similarity index 100%
rename from assets/images/svg/gplus.svg
rename to assets/images/gplus.svg
diff --git a/assets/images/svg/twitter.svg b/assets/images/twitter.svg
similarity index 100%
rename from assets/images/svg/twitter.svg
rename to assets/images/twitter.svg
diff --git a/bower.json b/bower.json
index a46e8baca..46f63e492 100644
--- a/bower.json
+++ b/bower.json
@@ -40,7 +40,6 @@
"angularjs-toaster": "~0.4.15",
"appirio-tech-ng-iso-constants": "git@github.com:appirio-tech/ng-iso-constants#~1.0.5",
"d3": "~3.5.6",
- "devicon": "*",
"fontawesome": "~4.3.0",
"jstzdetect": "~1.0.6",
"moment": "~2.10.3",
diff --git a/config.js b/config.js
index fe3cae590..f35fc241e 100644
--- a/config.js
+++ b/config.js
@@ -1,5 +1,5 @@
module.exports = function() {
- var constants = {
+ return {
'development': {
'CONSTANTS': {
API_URL: process.env.API_URL || 'https://api.topcoder-dev.com/v3',
@@ -231,6 +231,4 @@ module.exports = function() {
}
}
};
-
- return constants;
};
diff --git a/gulp-tasks/build.js b/gulp-tasks/build.js
new file mode 100644
index 000000000..f23492923
--- /dev/null
+++ b/gulp-tasks/build.js
@@ -0,0 +1,44 @@
+var runSequence = require('run-sequence');
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('build', function(done) {
+ utilities.log('Building everything');
+
+ runSequence(
+ 'clean',
+ ['optimize', 'fonts']
+ );
+
+ utilities.clean(config.temp, done);
+ });
+
+ gulp.task('build-specs', ['templatecache', 'ngConstants'], function() {
+ utilities.log('Building the spec runner');
+
+ var wiredep = require('wiredep').stream;
+ var options = config.getWiredepDefaultOptions();
+ options.devDependencies = true;
+
+ return gulp
+ .src(config.specRunner)
+ .pipe(wiredep(options))
+ .pipe($.inject(gulp.src(config.testlibraries),
+ {name: 'inject:testlibraries', read: false}))
+ .pipe($.inject(gulp.src(config.nonBowerScripts),
+ {name: 'inject:nonBowerScripts', read: false}))
+ .pipe($.inject(
+ gulp.src(config.js)
+ .pipe($.naturalSort())
+ .pipe($.angularFilesort())
+ ))
+ .pipe($.inject(gulp.src(config.specHelpers),
+ {name: 'inject:spechelpers', read: false}))
+ .pipe($.inject(gulp.src(config.specs),
+ {name: 'inject:specs', read: false}))
+ .pipe($.inject(gulp.src(config.temp + config.templateCache.file),
+ {name: 'inject:templates', read: false}))
+ .pipe(gulp.dest(config.app));
+ });
+};
diff --git a/gulp-tasks/clean.js b/gulp-tasks/clean.js
new file mode 100644
index 000000000..ca1df8777
--- /dev/null
+++ b/gulp-tasks/clean.js
@@ -0,0 +1,11 @@
+var del = require('del'); // rm -rf
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('clean', function(done) {
+ var delconfig = [].concat(config.build, config.temp);
+ utilities.log('Cleaning: ' + $.util.colors.blue(delconfig));
+ del(delconfig, done);
+ });
+};
diff --git a/gulp-tasks/copy-files.js b/gulp-tasks/copy-files.js
new file mode 100644
index 000000000..480ddf670
--- /dev/null
+++ b/gulp-tasks/copy-files.js
@@ -0,0 +1,11 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('copy-html', function() {
+ utilities.log('Moving app html files to .tmp');
+
+ return gulp
+ .src([config.app + '**/*.html', '!' + config.app + 'specs.html'])
+ .pipe(gulp.dest(config.temp));
+ });
+};
diff --git a/gulp-tasks/deploy.js b/gulp-tasks/deploy.js
new file mode 100644
index 000000000..4cfe8f455
--- /dev/null
+++ b/gulp-tasks/deploy.js
@@ -0,0 +1,54 @@
+var merge = require('merge-stream');
+var awspublishRouter = require('gulp-awspublish-router');
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('deploy', ['build'], function() {
+ var awsConfig = {
+ params: {
+ Bucket: config.aws.bucket
+ },
+ "accessKeyId": config.aws.key,
+ "secretAccessKey": config.aws.secret
+ };
+
+ // create a new publisher
+ var publisher = $.awspublish.create(awsConfig);
+
+ utilities.log('Deploying to S3');
+
+ var gzip = gulp.src(['build/**/*.js', 'build/**/*.css']).pipe($.awspublish.gzip())
+ .pipe(awspublishRouter({
+ cache: {
+ cacheTime: 94608000,
+ allowTransform: false,
+ public: true
+ },
+ routes: {
+ "^.+$": "$&"
+ }
+ }));
+
+ var plain = gulp.src(['build/**/*', '!build/**/*.js', '!build/**/*.css'])
+ .pipe(awspublishRouter({
+ cache: {
+ cacheTime: 94608000,
+ allowTransform: false,
+ public: true
+ },
+ routes: {
+ "^.+\\.html": {
+ cacheTime: 0
+ },
+ "^.+$": "$&"
+ }
+ }));
+
+ return merge(gzip, plain)
+ .pipe(publisher.cache())
+ .pipe(publisher.publish())
+ .pipe($.if(!config.production, publisher.sync()))
+ .pipe($.awspublish.reporter());
+ });
+};
diff --git a/gulp-tasks/e2e.js b/gulp-tasks/e2e.js
new file mode 100644
index 000000000..20a42af47
--- /dev/null
+++ b/gulp-tasks/e2e.js
@@ -0,0 +1,15 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('e2e', function() {
+ return gulp
+ .src(['./tests/e2e/app/*.js'])
+ .pipe($.angularProtractor({
+ 'configFile': 'tests/e2e/conf.js',
+ 'args': ['--baseUrl', 'http://127.0.0.1:8000'],
+ 'autoStartStopServer': true,
+ 'debug': true
+ }))
+ .on('error', function(e) { throw e });
+ });
+};
diff --git a/gulp-tasks/fonts.js b/gulp-tasks/fonts.js
new file mode 100644
index 000000000..f0900d064
--- /dev/null
+++ b/gulp-tasks/fonts.js
@@ -0,0 +1,11 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('fonts', function() {
+ utilities.log('Copying fonts');
+
+ return gulp
+ .src([config.fonts, 'bower_components/fontawesome/fonts/fontawesome-webfont.*'])
+ .pipe(gulp.dest(config.build + 'fonts'));
+ });
+};
diff --git a/gulp-tasks/images.js b/gulp-tasks/images.js
new file mode 100644
index 000000000..0b396b1c3
--- /dev/null
+++ b/gulp-tasks/images.js
@@ -0,0 +1,20 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('images', ['images:move-skills'], function() {
+ utilities.log('Copying and compressing the images');
+
+ return gulp
+ .src([config.images, '!' + config.assets + 'images/skills/**.*'])
+ .pipe($.imagemin({optimizationLevel: 4}))
+ .pipe(gulp.dest(config.temp + 'images'));
+ });
+
+ gulp.task('images:move-skills', function() {
+ utilities.log('Copying original skill icons to build folder');
+
+ return gulp
+ .src(config.assets + 'images/skills/**.*')
+ .pipe(gulp.dest(config.build + 'images/skills'));
+ });
+};
diff --git a/gulp-tasks/inject.js b/gulp-tasks/inject.js
new file mode 100644
index 000000000..5d81ccbb1
--- /dev/null
+++ b/gulp-tasks/inject.js
@@ -0,0 +1,36 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('wiredep', ['jade'], function() {
+ utilities.log('Injecting bower css/js and app js files into index.jade');
+ var options = config.getWiredepDefaultOptions();
+ var wiredep = require('wiredep').stream;
+
+ return gulp
+ .src(config.index)
+ .pipe(wiredep(options))
+ .pipe($.inject(
+ gulp.src(config.js)
+ .pipe($.naturalSort('desc'))
+ .pipe($.angularFilesort()),
+ {relative: true}))
+ .pipe($.inject(gulp.src(config.nonBowerScripts, {read: false}), {
+ starttag: '//- inject:nonBowerScripts',
+ endtag: '//- endinject',
+ ignorePath: 'assets/'
+ }))
+ .pipe(gulp.dest(config.app));
+ });
+
+ gulp.task('inject', ['wiredep', 'styles', 'templatecache'], function() {
+ utilities.log('Injecting app css into index.jade');
+
+ return gulp
+ .src(config.index)
+ .pipe($.inject( // Sort the css (topcoder.css, then everything else)
+ gulp.src(config.css, {read: false})
+ .pipe($.naturalSort('desc')),
+ {ignorePath: '.tmp', addRootSlash: false}))
+ .pipe(gulp.dest(config.app));
+ });
+};
diff --git a/gulp-tasks/jade.js b/gulp-tasks/jade.js
new file mode 100644
index 000000000..1aee4b4e0
--- /dev/null
+++ b/gulp-tasks/jade.js
@@ -0,0 +1,20 @@
+var envFile = require('../config.js')();
+var envConfig = envFile[process.env.ENVIRONMENT || 'development'];
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('jade', function() {
+ utilities.log('Compiling Jade --> HTML');
+
+ return gulp
+ .src(config.jade)
+ .pipe($.plumber())
+ .pipe($.data(function(file) {
+ return envConfig;
+ }))
+ .pipe($.jade({pretty: true}))
+ .pipe($.replace(/-->/g, ' -->'))
+ .pipe(gulp.dest(config.temp));
+ });
+};
diff --git a/gulp-tasks/linters.js b/gulp-tasks/linters.js
new file mode 100644
index 000000000..a83c765d6
--- /dev/null
+++ b/gulp-tasks/linters.js
@@ -0,0 +1,17 @@
+var args = require('yargs').argv;
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('vet', function() {
+ utilities.log('Analyzing source with JSHint and JSCS');
+
+ return gulp
+ .src(config.alljs)
+ .pipe($.if(args.verbose, $.print())) // gulp vet --verbose to trigger this line
+ .pipe($.jscs())
+ .pipe($.jshint())
+ .pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
+ .pipe($.jshint.reporter('fail'));
+ });
+};
diff --git a/gulp-tasks/ng-constants.js b/gulp-tasks/ng-constants.js
new file mode 100644
index 000000000..8d623190e
--- /dev/null
+++ b/gulp-tasks/ng-constants.js
@@ -0,0 +1,18 @@
+var envFile = require('../config.js')();
+var envConfig = envFile[process.env.ENVIRONMENT || 'development'];
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('ngConstants', function() {
+ utilities.log('Creating ng-constants file')
+
+ return $.ngConstant({
+ name: 'CONSTANTS',
+ constants: envConfig,
+ stream: true
+ })
+ .pipe($.rename('topcoder.constants.js'))
+ .pipe(gulp.dest(config.app));
+ });
+};
diff --git a/gulp-tasks/optimize.js b/gulp-tasks/optimize.js
new file mode 100644
index 000000000..d1b90da22
--- /dev/null
+++ b/gulp-tasks/optimize.js
@@ -0,0 +1,56 @@
+var envFile = require('../config.js')();
+var envConfig = envFile[process.env.ENVIRONMENT || 'development'];
+var RevAll = require('gulp-rev-all');
+var merge = require('merge-stream');
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('optimize', ['inject', 'test', 'ngConstants', 'images'], function() {
+ utilities.log('Optimizing the JavaScript, CSS, and HTML');
+
+ var assets = $.useref.assets({searchPath: ['.tmp', 'app', 'assets']});
+ var templateCache = config.temp + config.templateCache.file;
+ var cssFilter = $.filter('**/*.css');
+ var jsLibFilter = $.filter('**/' + config.optimized.vendor);
+ var jsAppFilter = $.filter('**/' + config.optimized.app);
+
+ var imageStream = gulp.src(config.temp + '/**/*.{svg,png,jpg,jpeg,gif}');
+ var userefStream = gulp
+ .src(config.indexHtml)
+ .pipe($.plumber())
+ .pipe($.inject(gulp.src(templateCache, {read: false}), {
+ starttag: '',
+ endtag: '',
+ relative: true
+ }))
+ .pipe(assets)
+ .pipe(cssFilter)
+ .pipe($.csso())
+ .pipe(cssFilter.restore())
+ .pipe(jsLibFilter)
+ .pipe($.uglify())
+ .pipe(jsLibFilter.restore())
+ .pipe(jsAppFilter)
+ .pipe($.if(!config.production && !config.qa, $.sourcemaps.init()))
+ .pipe($.ngAnnotate())
+ .pipe($.uglify())
+ .pipe(jsAppFilter.restore())
+ .pipe(assets.restore())
+ .pipe($.useref())
+
+ var revAll = new RevAll({
+ prefix: envConfig.CONSTANTS.ASSET_PREFIX,
+ dontRenameFile: [/^\/index.html/g]
+ });
+
+ return merge(userefStream, imageStream)
+ .pipe(revAll.revision())
+ .pipe($.if(!config.production && !config.qa, $.sourcemaps.write()))
+ // Uncomment if you want to see the JSON file containing
+ // the file mapping (e.g., "{"js/app.js": "js/app-a9bae026bc.js"}")
+ // .pipe(gulp.dest(config.build))
+ // .pipe(revAll.manifestFile())
+ .pipe(gulp.dest(config.build));
+ });
+};
diff --git a/gulp-tasks/scss.js b/gulp-tasks/scss.js
new file mode 100644
index 000000000..3da29f550
--- /dev/null
+++ b/gulp-tasks/scss.js
@@ -0,0 +1,24 @@
+var envFile = require('../config.js')();
+var envConfig = envFile[process.env.ENVIRONMENT || 'development'];
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('styles', function() {
+ utilities.log('Compiling Sass --> CSS');
+
+ var assetPrefix = envConfig.CONSTANTS.ASSET_PREFIX.length ? envConfig.CONSTANTS.ASSET_PREFIX : '/';
+
+ return gulp
+ .src(config.sass, {base: './'})
+ .pipe($.plumber())
+ .pipe($.sass({includePaths: require('appirio-styles').includePaths}))
+ .pipe($.autoprefixer({browsers: ['last 2 version']}))
+ .pipe($.replace(/\/fonts/g, assetPrefix + 'fonts'))
+ .pipe(gulp.dest(config.temp));
+ });
+
+ gulp.task('sass-watcher', function() {
+ gulp.watch([config.sass], ['styles']);
+ });
+};
diff --git a/gulp-tasks/serve.js b/gulp-tasks/serve.js
new file mode 100644
index 000000000..1e36e31f3
--- /dev/null
+++ b/gulp-tasks/serve.js
@@ -0,0 +1,101 @@
+var browserSync = require('browser-sync');
+var histFallback = require('connect-history-api-fallback');
+
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('serve', ['inject', 'ngConstants'], function() {
+ gulp.watch(config.sass, ['styles'])
+ .on('change', function(event) { utilities.changeEvent(event); });
+
+ gulp.watch(config.jade, ['templatecache'])
+ .on('change', function(event) { utilities.changeEvent(event); });
+
+ var options = {
+ server: {
+ baseDir: [config.temp, config.app, config.assets],
+ // Enables serving index.html for Angular HTML5 mode
+ middleware: [histFallback()],
+ routes: {
+ '/bower_components': 'bower_components'
+ }
+ },
+ files: config.watchFiles,
+ ghostMode: {
+ clicks: true,
+ location: false,
+ forms: true,
+ scroll: true
+ },
+ logPrefix: 'Topcoder-Account',
+ notify: false,
+ port: 3000,
+ reloadDelay: 1000
+ };
+
+ browserSync(options);
+
+ });
+
+ gulp.task('serve-specs', ['build-specs'], function() {
+ utilities.log('Run the spec runner');
+
+ gulp.watch(config.sass, ['styles'])
+ .on('change', function(event) { utilities.changeEvent(event); });
+
+ gulp.watch(config.jade, ['templatecache'])
+ .on('change', function(event) { utilities.changeEvent(event); });
+
+ var options = {
+ server: {
+ baseDir: ['./'],
+ // Enables serving index.html for Angular HTML5 mode
+ middleware: [histFallback()],
+ routes: {
+ '/bower_components': 'bower_components'
+ }
+ },
+ files: config.watchFiles,
+ ghostMode: {
+ clicks: true,
+ location: false,
+ forms: true,
+ scroll: true
+ },
+ logPrefix: 'Topcoder-Account',
+ notify: false,
+ reloadDelay: 1000,
+ startPath: config.app + config.specRunnerFile
+ };
+
+ browserSync(options);
+ });
+
+ gulp.task('serve-build', ['build'], function() {
+ // TODO: Figure out why watch doesn't work. Jade running before wiredep?
+
+ gulp.watch([config.sass, config.js, config.jade], ['optimize', browserSync.reload])
+ .on('change', function(event) { utilities.changeEvent(event); });
+
+ var options = {
+ server: {
+ baseDir: config.build,
+ // Enables serving index.html for Angular HTML5 mode
+ middleware: [histFallback()]
+ },
+ files: [],
+ ghostMode: {
+ clicks: true,
+ location: false,
+ forms: true,
+ scroll: true
+ },
+ logPrefix: 'Topcoder-Account',
+ notify: false,
+ reloadDelay: 1000
+ };
+
+ browserSync(options);
+
+ });
+};
diff --git a/gulp-tasks/template-cache.js b/gulp-tasks/template-cache.js
new file mode 100644
index 000000000..b2135367b
--- /dev/null
+++ b/gulp-tasks/template-cache.js
@@ -0,0 +1,16 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ gulp.task('templatecache', ['jade'], function() {
+ utilities.log('Creating AngularJS $templateCache');
+
+ return gulp
+ .src(config.htmltemplates)
+ .pipe($.minifyHtml({empty: true}))
+ .pipe($.angularTemplatecache(
+ config.templateCache.file,
+ config.templateCache.options
+ ))
+ .pipe(gulp.dest(config.temp));
+ });
+};
diff --git a/gulp-tasks/tests.js b/gulp-tasks/tests.js
new file mode 100644
index 000000000..6eca779fa
--- /dev/null
+++ b/gulp-tasks/tests.js
@@ -0,0 +1,12 @@
+module.exports = function(gulp, $, config, utilities) {
+ 'use strict';
+
+ // vet should be run before tests
+ gulp.task('test', ['templatecache', 'ngConstants'], function(done) {
+ utilities.startTests(true /* singleRun */, done);
+ });
+
+ gulp.task('autotest', ['vet', 'templatecache', 'ngConstants'], function(done) {
+ utilities.startTests(false, done);
+ });
+};
diff --git a/gulp-tasks/utilities.js b/gulp-tasks/utilities.js
new file mode 100644
index 000000000..267641f12
--- /dev/null
+++ b/gulp-tasks/utilities.js
@@ -0,0 +1,51 @@
+var config = require('../gulp.config')();
+var util = require('gulp-util');
+var del = require('del'); // rm -rf
+var path = require('path');
+
+exports.changeEvent = function(event) {
+ var srcPattern = new RegExp('/.*(?=/' + config.source + ')/');
+ this.log('File ' + event.path.replace(srcPattern, '') + ' ' + event.type);
+}
+
+exports.clean = function(path, done) {
+ this.log('Cleaning: ' + util.colors.blue(path));
+ del(path, done);
+}
+
+exports.log = function(msg) {
+ if (typeof(msg) === 'object') {
+ for (var item in msg) {
+ if (msg.hasOwnProperty(item)) {
+ util.log(util.colors.blue(msg[item]));
+ }
+ }
+ } else {
+ util.log(util.colors.blue(msg));
+ }
+}
+
+exports.startTests = function(singleRun, done) {
+ var karma = require('karma').server;
+ var excludeFiles = [];
+ var serverSpecs = config.serverIntegrationSpecs;
+
+ excludeFiles = serverSpecs;
+
+ karma.start({
+ configFile: path.join(__dirname,'../karma.conf.js'),
+ exclude: excludeFiles,
+ singleRun: !!singleRun
+ }, karmaCompleted.bind(this));
+
+ function karmaCompleted(karmaResult) {
+ this.log('Karma completed!');
+ if (karmaResult === 1) {
+ done('karma: tests failed with code ' + karmaResult);
+ } else {
+ done();
+ }
+ }
+}
+
+return module.exports;
diff --git a/gulpfile.js b/gulpfile.js
index 29761e9e5..7e5ffe30c 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,494 +1,19 @@
-var gulp = require('gulp');
-var args = require('yargs').argv;
-var config = require('./gulp.config')();
-var del = require('del'); // rm -rf
-var fs = require('fs');
-var $ = require('gulp-load-plugins')({lazy: true});
-var browserSync = require('browser-sync');
-var histFallback = require('connect-history-api-fallback');
-var merge = require('merge-stream');
-var RevAll = require('gulp-rev-all');
-var styleguide = require('sc5-styleguide');
-var awspublishRouter = require('gulp-awspublish-router');
+'use strict';
-var envFile = require('./config.js')();
-var envConfig = envFile[process.env.ENVIRONMENT || 'development'];
+var gulp = require('gulp');
+var plugins = require('gulp-load-plugins')({lazy: true});
-gulp.task('help', $.taskListing);
-gulp.task('default', ['help']);
-
-gulp.task('vet', function() {
- log('Analyzing source with JSHint and JSCS');
-
- return gulp
- .src(config.alljs)
- .pipe($.if(args.verbose, $.print())) // gulp vet --verbose to trigger this line
- .pipe($.jscs())
- .pipe($.jshint())
- .pipe($.jshint.reporter('jshint-stylish', {verbose: true}))
- .pipe($.jshint.reporter('fail'));
-});
-
-gulp.task('jade', ['clean-html'], function() {
- log('Compiling Jade --> HTML');
-
- return gulp
- .src(config.jade)
- .pipe($.plumber())
- .pipe($.data(function(file) {
- return envConfig;
- }))
- .pipe($.jade({pretty: true}))
- .pipe($.replace(/-->/g, ' -->'))
- .pipe(gulp.dest(config.temp));
-});
-
-gulp.task('styles', ['clean-styles'], function() {
- log('Compiling Sass --> CSS');
-
- var assetPrefix = envConfig.CONSTANTS.ASSET_PREFIX.length ? envConfig.CONSTANTS.ASSET_PREFIX : '/';
-
- return gulp
- .src(config.sass, {base: './'})
- .pipe($.plumber())
- .pipe($.sass({includePaths: require('appirio-styles').includePaths}))
- .pipe($.autoprefixer({browsers: ['last 2 version']}))
- .pipe($.replace(/\/fonts/g, assetPrefix + 'fonts'))
- .pipe(gulp.dest(config.temp));
-});
-
-gulp.task('sass-watcher', function() {
- gulp.watch([config.sass], ['styles']);
-});
+var config = require('./gulp.config')();
+var taskPath = './gulp-tasks/';
+var taskList = require('fs').readdirSync(taskPath);
-gulp.task('fonts', ['clean-fonts'], function() {
- log('Copying fonts');
+var utilities = require(taskPath + 'utilities');
- return gulp
- .src([config.fonts, 'bower_components/fontawesome/fonts/fontawesome-webfont.*'])
- .pipe(gulp.dest(config.build + 'fonts'));
-});
-
-gulp.task('dev-fonts', ['fonts'], function() {
- log('Copying devicon fonts');
-
- return gulp
- .src('bower_components/devicon/fonts/**.*')
- .pipe(gulp.dest(config.build + 'styles/fonts'));
-})
-
-gulp.task('images', ['clean-images'], function() {
- log('Copying and compressing the images');
-
- return gulp
- .src(config.images)
- .pipe($.imagemin({optimizationLevel: 4}))
- .pipe(gulp.dest(config.temp + 'images'));
-});
-
-
-gulp.task('images-orig-nav', ['build1'], function() {
- log('Copying original images');
- return gulp
- .src(config.assets + 'images/nav/**.*')
- .pipe(gulp.dest(config.build + 'images/nav'));
-});
-
-gulp.task('images-orig', ['images-orig-nav'], function() {
- log('Copying original images');
- return gulp
- .src(config.assets + 'images/skills/**.*')
- .pipe(gulp.dest(config.build + 'images/skills'));
-});
-
-gulp.task('clean', function(done) {
- var delconfig = [].concat(config.build, config.temp);
- log('Cleaning: ' + $.util.colors.blue(delconfig));
- del(delconfig, done);
-});
-gulp.task('clean-fonts', function(done) {
- clean(config.build + 'fonts/**/*.*', done);
-});
-gulp.task('clean-images', function(done) {
- clean(config.build + 'images/**/*.*', done);
-});
-gulp.task('clean-styles', function(done) {
- clean(config.temp + '**/*.css', done);
-});
-gulp.task('clean-html', function(done) {
- clean(config.temp + '**/*.html', done);
-});
-gulp.task('clean-code', function(done) {
- var files = [].concat(
- config.temp + '**/*.js',
- config.build + '**/*.html',
- config.build + 'js/**/*.js',
- config.build + 'styles/**/*.css'
- );
- clean(files, done);
-});
-
-gulp.task('copy-html', function() {
- log('Moving app html files to .tmp');
-
- return gulp
- .src([config.app + '**/*.html', '!' + config.app + 'specs.html'])
- .pipe(gulp.dest(config.temp));
-});
-
-gulp.task('templatecache', ['clean-code', 'jade', 'copy-html'], function() {
- log('Creating AngularJS $templateCache');
-
- return gulp
- .src(config.htmltemplates)
- .pipe($.minifyHtml({empty: true}))
- .pipe($.angularTemplatecache(
- config.templateCache.file,
- config.templateCache.options
- ))
- .pipe(gulp.dest(config.temp));
-});
-
-gulp.task('ngConstants', function() {
- return $.ngConstant({
- name: 'CONSTANTS',
- dest: 'topcoder.constants.js',
- constants: envConfig,
- stream: true
- })
- .pipe(gulp.dest(config.app));
-});
-
-gulp.task('wiredep', ['jade'], function() {
- log('Injecting bower css/js and app js files into index.jade');
- var options = config.getWiredepDefaultOptions();
- var wiredep = require('wiredep').stream;
-
- return gulp
- .src(config.index)
- .pipe(wiredep(options))
- .pipe($.inject(
- gulp.src(config.js)
- .pipe($.naturalSort('desc'))
- .pipe($.angularFilesort()),
- {relative: true}))
- .pipe($.inject(gulp.src(config.nonBowerScripts, {read: false}), {
- starttag: '//- inject:nonBowerScripts',
- endtag: '//- endinject',
- ignorePath: 'assets/'
- }))
- .pipe(gulp.dest(config.app));
-});
-
-gulp.task('inject', ['wiredep', 'styles', 'templatecache'], function() {
- log('Injecting app css into index.jade');
-
- return gulp
- .src(config.index)
- .pipe($.inject( // Sort the css (reset.css, then topcoder.css, then everything else)
- gulp.src([config.temp + 'assets/css/reset.css', config.css], {read: false})
- .pipe($.naturalSort('desc')),
- {ignorePath: '.tmp', addRootSlash: false}))
- .pipe(gulp.dest(config.app));
-});
-
-gulp.task('optimize', ['inject', 'test', 'ngConstants', 'images'], function() {
- log('Optimizing the JavaScript, CSS, and HTML');
-
- var assets = $.useref.assets({searchPath: ['.tmp', 'app', 'assets']});
- var templateCache = config.temp + config.templateCache.file;
- var cssFilter = $.filter('**/*.css');
- var jsLibFilter = $.filter('**/' + config.optimized.vendor);
- var jsAppFilter = $.filter('**/' + config.optimized.app);
-
- var imageStream = gulp.src(config.temp + '/**/*.{svg,png,jpg,jpeg,gif}');
- var userefStream = gulp
- .src(config.indexHtml)
- .pipe($.plumber())
- .pipe($.inject(gulp.src(templateCache, {read: false}), {
- starttag: '',
- endtag: '',
- relative: true
- }))
- .pipe(assets)
- .pipe(cssFilter)
- .pipe($.csso())
- .pipe(cssFilter.restore())
- .pipe(jsLibFilter)
- .pipe($.uglify())
- .pipe(jsLibFilter.restore())
- .pipe(jsAppFilter)
- .pipe($.if(!config.production && !config.qa, $.sourcemaps.init()))
- .pipe($.ngAnnotate())
- .pipe($.uglify())
- .pipe(jsAppFilter.restore())
- .pipe(assets.restore())
- .pipe($.useref())
-
- var revAll = new RevAll({
- prefix: envConfig.CONSTANTS.ASSET_PREFIX,
- dontRenameFile: [/^\/index.html/g]
- });
-
- return merge(userefStream, imageStream)
- .pipe(revAll.revision())
- .pipe($.if(!config.production && !config.qa, $.sourcemaps.write()))
- // Uncomment if you want to see the JSON file containing
- // the file mapping (e.g., "{"js/app.js": "js/app-a9bae026bc.js"}")
- // .pipe(gulp.dest(config.build))
- // .pipe(revAll.manifestFile())
- .pipe(gulp.dest(config.build));
-});
-
-gulp.task('build1', ['optimize', 'dev-fonts'], function() {
- log('Building everything');
-
- var msg = {
- title: 'gulp build',
- subtitle: 'Deployed to the build folder',
- message: 'Running `gulp serve-build`'
- };
- del(config.temp);
- log(msg);
-});
-
-gulp.task('build', ['images-orig']);
-
-gulp.task('build-specs', ['templatecache', 'ngConstants'], function() {
- log('Building the spec runner');
-
- var wiredep = require('wiredep').stream;
- var options = config.getWiredepDefaultOptions();
- options.devDependencies = true;
-
- return gulp
- .src(config.specRunner)
- .pipe(wiredep(options))
- .pipe($.inject(gulp.src(config.testlibraries),
- {name: 'inject:testlibraries', read: false}))
- .pipe($.inject(gulp.src(config.nonBowerScripts),
- {name: 'inject:nonBowerScripts', read: false}))
- .pipe($.inject(
- gulp.src(config.js)
- .pipe($.naturalSort())
- .pipe($.angularFilesort())
- ))
- .pipe($.inject(gulp.src(config.specHelpers),
- {name: 'inject:spechelpers', read: false}))
- .pipe($.inject(gulp.src(config.specs),
- {name: 'inject:specs', read: false}))
- .pipe($.inject(gulp.src(config.temp + config.templateCache.file),
- {name: 'inject:templates', read: false}))
- .pipe(gulp.dest(config.app));
-});
-
-gulp.task('serve', ['inject', 'ngConstants'], function() {
-
- gulp.watch(config.sass, ['styles'])
- .on('change', function(event) { changeEvent(event); });
-
- gulp.watch(config.jade, ['jade'])
- .on('change', function(event) { changeEvent(event); });
-
- var options = {
- server: {
- baseDir: [config.temp, config.app, config.assets],
- // Enables serving index.html for Angular HTML5 mode
- middleware: [histFallback()],
- routes: {
- '/bower_components': 'bower_components'
- }
- },
- files: config.watchFiles,
- ghostMode: {
- clicks: true,
- location: false,
- forms: true,
- scroll: true
- },
- logPrefix: 'Topcoder-Account',
- notify: false,
- port: 3000,
- reloadDelay: 1000
- };
-
- browserSync(options);
-
-});
-
-gulp.task('serve-specs', ['build-specs'], function() {
- log('Run the spec runner');
-
- gulp.watch(config.sass, ['styles'])
- .on('change', function(event) { changeEvent(event); });
-
- gulp.watch(config.jade, ['jade'])
- .on('change', function(event) { changeEvent(event); });
-
- var options = {
- server: {
- baseDir: ['./'],
- // Enables serving index.html for Angular HTML5 mode
- middleware: [histFallback()],
- routes: {
- '/bower_components': 'bower_components'
- }
- },
- files: config.watchFiles,
- ghostMode: {
- clicks: true,
- location: false,
- forms: true,
- scroll: true
- },
- logPrefix: 'Topcoder-Account',
- notify: false,
- reloadDelay: 1000,
- startPath: config.app + config.specRunnerFile
- };
-
- browserSync(options);
-});
-
-gulp.task('serve-build', ['build'], function() {
- // TODO: Figure out why watch doesn't work. Jade running before wiredep?
-
- gulp.watch([config.sass, config.js, config.jade], ['optimize', browserSync.reload])
- .on('change', function(event) { changeEvent(event); });
-
- var options = {
- server: {
- baseDir: config.build,
- // Enables serving index.html for Angular HTML5 mode
- middleware: [histFallback()]
- },
- files: [],
- ghostMode: {
- clicks: true,
- location: false,
- forms: true,
- scroll: true
- },
- logPrefix: 'Topcoder-Account',
- notify: false,
- reloadDelay: 1000
- };
-
- browserSync(options);
-
-});
-
-gulp.task('e2e', [], function(done) {
- gulp.src(['./tests/e2e/app/*.js'])
- .pipe($.angularProtractor({
- 'configFile': 'tests/e2e/conf.js',
- 'args': ['--baseUrl', 'http://127.0.0.1:8000'],
- 'autoStartStopServer': true,
- 'debug': true
- }))
- .on('error', function(e) { throw e });
-});
-
-// gulp.task('test', ['vet', 'templatecache'], function(done) {
-gulp.task('test', ['templatecache', 'ngConstants'], function(done) {
- startTests(true /* singleRun */, done);
-});
-
-gulp.task('autotest', ['vet', 'templatecache'], function(done) {
- startTests(false /* singleRun */, done);
-});
-
-gulp.task('deploy', ['build'], function() {
- var awsConfig = {
- params: {
- Bucket: config.aws.bucket
- },
- "accessKeyId": config.aws.key,
- "secretAccessKey": config.aws.secret
- };
-
- // create a new publisher
- var publisher = $.awspublish.create(awsConfig);
-
- log('Deploying to S3');
-
- var gzip = gulp.src(['build/**/*.js', 'build/**/*.css']).pipe($.awspublish.gzip())
- .pipe(awspublishRouter({
- cache: {
- cacheTime: 94608000,
- allowTransform: false,
- public: true
- },
- routes: {
- "^.+$": "$&"
- }
- }));
-
- var plain = gulp.src(['build/**/*', '!build/**/*.js', '!build/**/*.css'])
- .pipe(awspublishRouter({
- cache: {
- cacheTime: 94608000,
- allowTransform: false,
- public: true
- },
- routes: {
- "^.+\\.html": {
- cacheTime: 0
- },
- "^.+$": "$&"
- }
- }));
-
- return merge(gzip, plain)
- .pipe(publisher.cache())
- .pipe(publisher.publish())
- .pipe($.if(!config.production, publisher.sync()))
- .pipe($.awspublish.reporter());
-});
-
-/////////////////////////////////////
-
-function changeEvent(event) {
- var srcPattern = new RegExp('/.*(?=/' + config.source + ')/');
- log('File ' + event.path.replace(srcPattern, '') + ' ' + event.type);
-}
-
-function clean(path, done) {
- log('Cleaning: ' + $.util.colors.blue(path));
- del(path, done);
-}
-
-function log(msg) {
- if (typeof(msg) === 'object') {
- for (var item in msg) {
- if (msg.hasOwnProperty(item)) {
- $.util.log($.util.colors.blue(msg[item]));
- }
- }
- } else {
- $.util.log($.util.colors.blue(msg));
+taskList.forEach(function(taskFile) {
+ if (taskFile !== 'utilities.js') {
+ require(taskPath + taskFile)(gulp, plugins, config, utilities);
}
-}
-
-function startTests(singleRun, done) {
- var karma = require('karma').server;
- var excludeFiles = [];
- var serverSpecs = config.serverIntegrationSpecs;
-
- excludeFiles = serverSpecs;
-
- karma.start({
- configFile: __dirname + '/karma.conf.js',
- exclude: excludeFiles,
- singleRun: !!singleRun
- }, karmaCompleted);
+});
- function karmaCompleted(karmaResult) {
- log('Karma completed!');
- if (karmaResult === 1) {
- done('karma: tests failed with code ' + karmaResult);
- } else {
- done();
- }
- }
-}
+gulp.task('help', plugins.taskListing);
+gulp.task('default', ['help']);
diff --git a/package.json b/package.json
index 8e5bd18e7..b363a8595 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"gulp-ng-constant": "^0.3.0",
"gulp-plumber": "^1.0.1",
"gulp-print": "^1.1.0",
+ "gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.3",
"gulp-replace-task": "^0.11.0",
"gulp-rev": "^5.0.1",
@@ -80,7 +81,7 @@
"phantomjs": "^1.9.17",
"protractor-html-screenshot-reporter": "0.0.21",
"protractor-linkuisref-locator": "^1.1.2",
- "sc5-styleguide": "^0.3.39",
+ "run-sequence": "^1.1.5",
"sinon": "^1.15.3",
"sinon-chai": "^2.8.0",
"wiredep": "^2.2.2",