diff --git a/.eslintignore b/.eslintignore index b8349da881..b107de65a1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -16,5 +16,3 @@ migrations/* scripts/* website/common/browserify.js Gruntfile.js -gulpfile.js -gulp \ No newline at end of file diff --git a/gulp/.eslintrc b/gulp/.eslintrc deleted file mode 100644 index a802b21bde..0000000000 --- a/gulp/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "root": true, - "env": { - "node": true, - }, - "extends": [ - "habitrpg/server", - "habitrpg/babel" - ], -} diff --git a/gulp/gulp-apidoc.js b/gulp/gulp-apidoc.js index 51c3ae865a..cfbe3f0f56 100644 --- a/gulp/gulp-apidoc.js +++ b/gulp/gulp-apidoc.js @@ -22,5 +22,5 @@ gulp.task('apidoc', ['apidoc:clean'], (done) => { }); gulp.task('apidoc:watch', ['apidoc'], () => { - return gulp.watch(APIDOC_SRC_PATH + '/**/*.js', ['apidoc']); + return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, ['apidoc']); }); diff --git a/gulp/gulp-bootstrap.js b/gulp/gulp-bootstrap.js index 49e570aa4b..e0043d0cd8 100644 --- a/gulp/gulp-bootstrap.js +++ b/gulp/gulp-bootstrap.js @@ -8,10 +8,10 @@ const BOOSTRAP_NEW_CONFIG_PATH = 'website/client/assets/scss/bootstrap_config.sc const BOOTSTRAP_ORIGINAL_CONFIG_PATH = 'node_modules/bootstrap/scss/_custom.scss'; // https://stackoverflow.com/a/14387791/969528 -function copyFile(source, target, cb) { +function copyFile (source, target, cb) { let cbCalled = false; - function done(err) { + function done (err) { if (!cbCalled) { cb(err); cbCalled = true; @@ -33,4 +33,4 @@ gulp.task('bootstrap', (done) => { BOOTSTRAP_ORIGINAL_CONFIG_PATH, done, ); -}); \ No newline at end of file +}); diff --git a/gulp/gulp-build.js b/gulp/gulp-build.js index 891c2f0b7a..b79b1abcca 100644 --- a/gulp/gulp-build.js +++ b/gulp/gulp-build.js @@ -1,10 +1,9 @@ import gulp from 'gulp'; -import runSequence from 'run-sequence'; import babel from 'gulp-babel'; import webpackProductionBuild from '../webpack/build'; gulp.task('build', () => { - if (process.env.NODE_ENV === 'production') { + if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env gulp.start('build:prod'); } }); @@ -27,12 +26,12 @@ gulp.task('build:server', ['build:src', 'build:common']); gulp.task('build:client', ['bootstrap'], (done) => { webpackProductionBuild((err, output) => { if (err) return done(err); - console.log(output); + console.log(output); // eslint-disable-line no-console }); }); gulp.task('build:prod', [ - 'build:server', + 'build:server', 'build:client', 'apidoc', ]); diff --git a/gulp/gulp-console.js b/gulp/gulp-console.js index 9edbdd5380..e7dc976265 100644 --- a/gulp/gulp-console.js +++ b/gulp/gulp-console.js @@ -7,10 +7,11 @@ import gulp from 'gulp'; // Add additional properties to the repl's context let improveRepl = (context) => { - // Let "exit" and "quit" terminate the console ['exit', 'quit'].forEach((term) => { - Object.defineProperty(context, term, { get () { process.exit(); }}); + Object.defineProperty(context, term, { get () { + process.exit(); + }}); }); // "clear" clears the screen @@ -18,12 +19,12 @@ let improveRepl = (context) => { process.stdout.write('\u001B[2J\u001B[0;0f'); }}); - context.Challenge = require('../website/server/models/challenge').model; - context.Group = require('../website/server/models/group').model; - context.User = require('../website/server/models/user').model; + context.Challenge = require('../website/server/models/challenge').model; // eslint-disable-line global-require + context.Group = require('../website/server/models/group').model; // eslint-disable-line global-require + context.User = require('../website/server/models/user').model; // eslint-disable-line global-require - var isProd = nconf.get('NODE_ENV') === 'production'; - var mongooseOptions = !isProd ? {} : { + const isProd = nconf.get('NODE_ENV') === 'production'; + const mongooseOptions = !isProd ? {} : { replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }, server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }, }; @@ -31,16 +32,15 @@ let improveRepl = (context) => { mongoose.connect( nconf.get('NODE_DB_URI'), mongooseOptions, - function (err) { + (err) => { if (err) throw err; logger.info('Connected with Mongoose'); } ) ); - }; -gulp.task('console', (cb) => { +gulp.task('console', () => { improveRepl(repl.start({ prompt: 'Habitica > ', }).context); diff --git a/gulp/gulp-sprites.js b/gulp/gulp-sprites.js index 381c34345c..884da11cc5 100644 --- a/gulp/gulp-sprites.js +++ b/gulp/gulp-sprites.js @@ -14,75 +14,35 @@ const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3; const IMG_DIST_PATH = 'website/static/sprites/'; const CSS_DIST_PATH = 'website/client/assets/css/sprites/'; -gulp.task('sprites:compile', ['sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions']); +function checkForSpecialTreatment (name) { + let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame/; + return name.match(regex) || name === 'head_0'; +} -gulp.task('sprites:main', () => { - let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png'); - return createSpritesStream('main', mainSrc); -}); +function calculateImgDimensions (img, addPadding) { + let dims = sizeOf(img); -gulp.task('sprites:largeSprites', () => { - let largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png'); - return createSpritesStream('largeSprites', largeSrc); -}); - -gulp.task('sprites:clean', (done) => { - clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done); -}); - -gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSprites'], () => { - console.log('Verifiying that images do not exceed max dimensions'); - - let numberOfSheetsThatAreTooBig = 0; - - let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`); - - each(distSpritesheets, (img, index) => { - let spriteSize = calculateImgDimensions(img); - - if (spriteSize > MAX_SPRITESHEET_SIZE) { - numberOfSheetsThatAreTooBig++; - let name = basename(img, '.png'); - console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); - } - }); - - if (numberOfSheetsThatAreTooBig > 0) { - console.error(`${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle them, but there is a margin of error in these calculations so it is probably okay. Mention this to an admin so they can test a staging site on mobile Safari after your PR is merged.`); // https://github.com/HabitRPG/habitica/pull/6683#issuecomment-185462180 - } else { - console.log('All images are within the correct dimensions'); + let requiresSpecialTreatment = checkForSpecialTreatment(img); + if (requiresSpecialTreatment) { + let newWidth = dims.width < 90 ? 90 : dims.width; + let newHeight = dims.height < 90 ? 90 : dims.height; + dims = { + width: newWidth, + height: newHeight, + }; } -}); -function createSpritesStream (name, src) { - let spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src); - let stream = mergeStream(); + let padding = 0; - each(spritesheetSliceIndicies, (start, index) => { - let slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]); + if (addPadding) { + padding = dims.width * 8 + dims.height * 8; + } - let spriteData = gulp.src(slicedSrc) - .pipe(spritesmith({ - imgName: `spritesmith-${name}-${index}.png`, - cssName: `spritesmith-${name}-${index}.css`, - algorithm: 'binary-tree', - padding: 1, - cssTemplate: 'website/raw_sprites/css/css.template.handlebars', - cssVarMap: cssVarMap, - })); + if (!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims); // eslint-disable-line no-console - let imgStream = spriteData.img - .pipe(imagemin()) - .pipe(gulp.dest(IMG_DIST_PATH)); + let totalPixelSize = dims.width * dims.height + padding; - let cssStream = spriteData.css - .pipe(gulp.dest(CSS_DIST_PATH)); - - stream.add(imgStream); - stream.add(cssStream); - }); - - return stream; + return totalPixelSize; } function calculateSpritesheetsSrcIndicies (src) { @@ -102,37 +62,6 @@ function calculateSpritesheetsSrcIndicies (src) { return slices; } -function calculateImgDimensions (img, addPadding) { - let dims = sizeOf(img); - - let requiresSpecialTreatment = checkForSpecialTreatment(img); - if (requiresSpecialTreatment) { - let newWidth = dims.width < 90 ? 90 : dims.width; - let newHeight = dims.height < 90 ? 90 : dims.height; - dims = { - width: newWidth, - height: newHeight, - }; - } - - let padding = 0; - - if (addPadding) { - padding = (dims.width * 8) + (dims.height * 8); - } - - if (!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims); - - let totalPixelSize = (dims.width * dims.height) + padding; - - return totalPixelSize; -} - -function checkForSpecialTreatment (name) { - let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame/; - return name.match(regex) || name === 'head_0'; -} - function cssVarMap (sprite) { // For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class, which works as a // 60x60 image pointing at the proper part of the 90x90 sprite. @@ -141,18 +70,93 @@ function cssVarMap (sprite) { if (requiresSpecialTreatment) { sprite.custom = { px: { - offset_x: `-${ sprite.x + 25 }px`, - offset_y: `-${ sprite.y + 15 }px`, + offsetX: `-${ sprite.x + 25 }px`, + offsetY: `-${ sprite.y + 15 }px`, width: '60px', height: '60px', }, }; } - if (~sprite.name.indexOf('shirt')) - sprite.custom.px.offset_y = `-${ sprite.y + 30 }px`; // even more for shirts - if (~sprite.name.indexOf('hair_base')) { - let styleArray = sprite.name.split('_').slice(2,3); + if (sprite.name.indexOf('shirt') !== -1) + sprite.custom.px.offsetY = `-${ sprite.y + 30 }px`; // even more for shirts + if (sprite.name.indexOf('hair_base') !== -1) { + let styleArray = sprite.name.split('_').slice(2, 3); if (Number(styleArray[0]) > 14) - sprite.custom.px.offset_y = `-${ sprite.y }px`; // don't crop updos + sprite.custom.px.offsetY = `-${ sprite.y }px`; // don't crop updos } } + +function createSpritesStream (name, src) { + let spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src); + let stream = mergeStream(); + + each(spritesheetSliceIndicies, (start, index) => { + let slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]); + + let spriteData = gulp.src(slicedSrc) + .pipe(spritesmith({ + imgName: `spritesmith-${name}-${index}.png`, + cssName: `spritesmith-${name}-${index}.css`, + algorithm: 'binary-tree', + padding: 1, + cssTemplate: 'website/raw_sprites/css/css.template.handlebars', + cssVarMap, + })); + + let imgStream = spriteData.img + .pipe(imagemin()) + .pipe(gulp.dest(IMG_DIST_PATH)); + + let cssStream = spriteData.css + .pipe(gulp.dest(CSS_DIST_PATH)); + + stream.add(imgStream); + stream.add(cssStream); + }); + + return stream; +} + +gulp.task('sprites:compile', ['sprites:clean', 'sprites:main', 'sprites:largeSprites', 'sprites:checkCompiledDimensions']); + +gulp.task('sprites:main', () => { + let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png'); + return createSpritesStream('main', mainSrc); +}); + +gulp.task('sprites:largeSprites', () => { + let largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png'); + return createSpritesStream('largeSprites', largeSrc); +}); + +gulp.task('sprites:clean', (done) => { + clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done); +}); + +gulp.task('sprites:checkCompiledDimensions', ['sprites:main', 'sprites:largeSprites'], () => { + console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console + + let numberOfSheetsThatAreTooBig = 0; + + let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`); + + each(distSpritesheets, (img) => { + let spriteSize = calculateImgDimensions(img); + + if (spriteSize > MAX_SPRITESHEET_SIZE) { + numberOfSheetsThatAreTooBig++; + let name = basename(img, '.png'); + console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); // eslint-disable-line no-console + } + }); + + if (numberOfSheetsThatAreTooBig > 0) { + // https://github.com/HabitRPG/habitica/pull/6683#issuecomment-185462180 + console.error( // eslint-disable-line no-console + `${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle + them, but there is a margin of error in these calculations so it is probably okay. Mention + this to an admin so they can test a staging site on mobile Safari after your PR is merged.`); + } else { + console.log('All images are within the correct dimensions'); // eslint-disable-line no-console + } +}); diff --git a/gulp/gulp-tests.js b/gulp/gulp-tests.js index 5c4a708eff..ca46bd4201 100644 --- a/gulp/gulp-tests.js +++ b/gulp/gulp-tests.js @@ -1,21 +1,12 @@ import { pipe, - awaitPort, - kill, - runMochaTests, } from './taskHelper'; -import { server as karma } from 'karma'; import mongoose from 'mongoose'; import { exec } from 'child_process'; -import psTree from 'ps-tree'; import gulp from 'gulp'; -import Bluebird from 'bluebird'; import runSequence from 'run-sequence'; import os from 'os'; import nconf from 'nconf'; -import fs from 'fs'; - -const i18n = require('../website/server/libs/i18n'); // TODO rewrite @@ -24,7 +15,6 @@ let server; const TEST_DB_URI = nconf.get('TEST_DB_URI'); -const API_V3_TEST_COMMAND = 'npm run test:api-v3'; const SANITY_TEST_COMMAND = 'npm run test:sanity'; const COMMON_TEST_COMMAND = 'npm run test:common'; const CONTENT_TEST_COMMAND = 'npm run test:content'; @@ -34,14 +24,14 @@ const CONTENT_OPTIONS = {maxBuffer: 1024 * 500}; let testResults = []; let testCount = (stdout, regexp) => { let match = stdout.match(regexp); - return parseInt(match && match[1] || 0); + return parseInt(match && match[1] || 0, 10); }; let testBin = (string, additionalEnvVariables = '') => { if (os.platform() === 'win32') { - if (additionalEnvVariables != '') { + if (additionalEnvVariables !== '') { additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set '); - additionalEnvVariables = 'set ' + additionalEnvVariables + '&&'; + additionalEnvVariables = `set ${additionalEnvVariables}&&`; } return `set NODE_ENV=test&&${additionalEnvVariables}${string}`; } else { @@ -49,9 +39,9 @@ let testBin = (string, additionalEnvVariables = '') => { } }; -gulp.task('test:nodemon', (done) => { - process.env.PORT = TEST_SERVER_PORT; - process.env.NODE_DB_URI = TEST_DB_URI; +gulp.task('test:nodemon', () => { + process.env.PORT = TEST_SERVER_PORT; // eslint-disable-line no-process-env + process.env.NODE_DB_URI = TEST_DB_URI; // eslint-disable-line no-process-env runSequence('nodemon'); }); @@ -68,8 +58,12 @@ gulp.task('test:prepare:mongo', (cb) => { gulp.task('test:prepare:server', ['test:prepare:mongo'], () => { if (!server) { server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => { - if (error) { throw `Problem with the server: ${error}`; } - if (stderr) { console.error(stderr); } + if (error) { + throw new Error(`Problem with the server: ${error}`); + } + if (stderr) { + console.error(stderr); // eslint-disable-line no-console + } }); } }); @@ -84,7 +78,7 @@ gulp.task('test:prepare', [ gulp.task('test:sanity', (cb) => { let runner = exec( testBin(SANITY_TEST_COMMAND), - (err, stdout, stderr) => { + (err) => { if (err) { process.exit(1); } @@ -97,7 +91,7 @@ gulp.task('test:sanity', (cb) => { gulp.task('test:common', ['test:prepare:build'], (cb) => { let runner = exec( testBin(COMMON_TEST_COMMAND), - (err, stdout, stderr) => { + (err) => { if (err) { process.exit(1); } @@ -118,7 +112,7 @@ gulp.task('test:common:watch', ['test:common:clean'], () => { gulp.task('test:common:safe', ['test:prepare:build'], (cb) => { let runner = exec( testBin(COMMON_TEST_COMMAND), - (err, stdout, stderr) => { + (err, stdout) => { // eslint-disable-line handle-callback-err testResults.push({ suite: 'Common Specs\t', pass: testCount(stdout, /(\d+) passing/), @@ -135,7 +129,7 @@ gulp.task('test:content', ['test:prepare:build'], (cb) => { let runner = exec( testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, - (err, stdout, stderr) => { + (err) => { if (err) { process.exit(1); } @@ -157,7 +151,7 @@ gulp.task('test:content:safe', ['test:prepare:build'], (cb) => { let runner = exec( testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, - (err, stdout, stderr) => { + (err, stdout) => { // eslint-disable-line handle-callback-err testResults.push({ suite: 'Content Specs\t', pass: testCount(stdout, /(\d+) passing/), @@ -173,7 +167,7 @@ gulp.task('test:content:safe', ['test:prepare:build'], (cb) => { gulp.task('test:api-v3:unit', (done) => { let runner = exec( testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-unit --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/unit --recursive --require ./test/helpers/start-server'), - (err, stdout, stderr) => { + (err) => { if (err) { process.exit(1); } @@ -192,7 +186,7 @@ gulp.task('test:api-v3:integration', (done) => { let runner = exec( testBin('node_modules/.bin/istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'), {maxBuffer: 500 * 1024}, - (err, stdout, stderr) => { + (err) => { if (err) { process.exit(1); } @@ -212,7 +206,7 @@ gulp.task('test:api-v3:integration:separate-server', (done) => { let runner = exec( testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'), {maxBuffer: 500 * 1024}, - (err, stdout, stderr) => done(err) + (err) => done(err) ); pipe(runner); diff --git a/gulp/gulp-transifex-test.js b/gulp/gulp-transifex-test.js index d6d8594f70..9318eeb0a2 100644 --- a/gulp/gulp-transifex-test.js +++ b/gulp/gulp-transifex-test.js @@ -1,6 +1,5 @@ import fs from 'fs'; import _ from 'lodash'; -import nconf from 'nconf'; import gulp from 'gulp'; import { postToSlack, conf } from './taskHelper'; @@ -12,8 +11,82 @@ const SLACK_CONFIG = { const LOCALES = './website/common/locales/'; const ENGLISH_LOCALE = `${LOCALES}en/`; + + +function getArrayOfLanguages () { + let languages = fs.readdirSync(LOCALES); + languages.shift(); // Remove README.md from array of languages + + return languages; +} + const ALL_LANGUAGES = getArrayOfLanguages(); +function stripOutNonJsonFiles (collection) { + let onlyJson = _.filter(collection, (file) => { + return file.match(/[a-zA-Z]*\.json/); + }); + + return onlyJson; +} + +function eachTranslationFile (languages, cb) { + let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE)); + + _.each(languages, (lang) => { + _.each(jsonFiles, (filename) => { + let parsedTranslationFile; + try { + const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`); + parsedTranslationFile = JSON.parse(translationFile); + } catch (err) { + return cb(err); + } + + let englishFile = fs.readFileSync(ENGLISH_LOCALE + filename); + let parsedEnglishFile = JSON.parse(englishFile); + + cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile); + }); + }); +} + +function eachTranslationString (languages, cb) { + eachTranslationFile(languages, (error, language, filename, englishJSON, translationJSON) => { + if (error) return; + _.each(englishJSON, (string, key) => { + const translationString = translationJSON[key]; + cb(language, filename, key, string, translationString); + }); + }); +} + +function formatMessageForPosting (msg, items) { + let body = `*Warning:* ${msg}`; + body += '\n\n```\n'; + body += items.join('\n'); + body += '\n```'; + + return body; +} + +function getStringsWith (json, interpolationRegex) { + let strings = {}; + + _.each(json, (fileName) => { + const rawFile = fs.readFileSync(ENGLISH_LOCALE + fileName); + const parsedJson = JSON.parse(rawFile); + + strings[fileName] = {}; + _.each(parsedJson, (value, key) => { + const match = value.match(interpolationRegex); + if (match) strings[fileName][key] = match; + }); + }); + + return strings; +} + const malformedStringExceptions = { messageDropFood: true, armoireFood: true, @@ -23,7 +96,6 @@ const malformedStringExceptions = { gulp.task('transifex', ['transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings']); gulp.task('transifex:missingFiles', () => { - let missingStrings = []; eachTranslationFile(ALL_LANGUAGES, (error) => { @@ -40,7 +112,6 @@ gulp.task('transifex:missingFiles', () => { }); gulp.task('transifex:missingStrings', () => { - let missingStrings = []; eachTranslationString(ALL_LANGUAGES, (language, filename, key, englishString, translationString) => { @@ -58,7 +129,6 @@ gulp.task('transifex:missingStrings', () => { }); gulp.task('transifex:malformedStrings', () => { - let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE)); let interpolationRegex = /<%= [a-zA-Z]* %>/g; let stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex); @@ -66,25 +136,23 @@ gulp.task('transifex:malformedStrings', () => { let stringsWithMalformedInterpolations = []; let stringsWithIncorrectNumberOfInterpolations = []; - let count = 0; - _.each(ALL_LANGUAGES, function (lang) { - - _.each(stringsToLookFor, function (strings, file) { - let translationFile = fs.readFileSync(LOCALES + lang + '/' + file); + _.each(ALL_LANGUAGES, (lang) => { + _.each(stringsToLookFor, (strings, filename) => { + let translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`); let parsedTranslationFile = JSON.parse(translationFile); - _.each(strings, function (value, key) { + _.each(strings, (value, key) => { // eslint-disable-line max-nested-callbacks let translationString = parsedTranslationFile[key]; if (!translationString) return; - let englishOccurences = stringsToLookFor[file][key]; + let englishOccurences = stringsToLookFor[filename][key]; let translationOccurences = translationString.match(interpolationRegex); if (!translationOccurences) { - let malformedString = `${lang} - ${file} - ${key} - ${translationString}`; + let malformedString = `${lang} - ${filename} - ${key} - ${translationString}`; stringsWithMalformedInterpolations.push(malformedString); } else if (englishOccurences.length !== translationOccurences.length && !malformedStringExceptions[key]) { - let missingInterpolationString = `${lang} - ${file} - ${key} - ${translationString}`; + let missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`; stringsWithIncorrectNumberOfInterpolations.push(missingInterpolationString); } }); @@ -103,74 +171,3 @@ gulp.task('transifex:malformedStrings', () => { postToSlack(formattedMessage, SLACK_CONFIG); } }); - -function getArrayOfLanguages () { - let languages = fs.readdirSync(LOCALES); - languages.shift(); // Remove README.md from array of languages - - return languages; -} - -function eachTranslationFile (languages, cb) { - let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE)); - - _.each(languages, (lang) => { - _.each(jsonFiles, (filename) => { - try { - var translationFile = fs.readFileSync(LOCALES + lang + '/' + filename); - var parsedTranslationFile = JSON.parse(translationFile); - } catch (err) { - return cb(err); - } - - let englishFile = fs.readFileSync(ENGLISH_LOCALE + filename); - let parsedEnglishFile = JSON.parse(englishFile); - - cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile); - }); - }); -} - -function eachTranslationString (languages, cb) { - eachTranslationFile(languages, (error, language, filename, englishJSON, translationJSON) => { - if (error) return; - _.each(englishJSON, (string, key) => { - var translationString = translationJSON[key]; - cb(language, filename, key, string, translationString); - }); - }); -} - -function formatMessageForPosting (msg, items) { - let body = `*Warning:* ${msg}`; - body += '\n\n```\n'; - body += items.join('\n'); - body += '\n```'; - - return body; -} - -function getStringsWith (json, interpolationRegex) { - var strings = {}; - - _.each(json, function (file_name) { - var raw_file = fs.readFileSync(ENGLISH_LOCALE + file_name); - var parsed_json = JSON.parse(raw_file); - - strings[file_name] = {}; - _.each(parsed_json, function (value, key) { - var match = value.match(interpolationRegex); - if (match) strings[file_name][key] = match; - }); - }); - - return strings; -} - -function stripOutNonJsonFiles (collection) { - let onlyJson = _.filter(collection, (file) => { - return file.match(/[a-zA-Z]*\.json/); - }); - - return onlyJson; -} diff --git a/gulp/taskHelper.js b/gulp/taskHelper.js index 249e6982c5..83560d3f46 100644 --- a/gulp/taskHelper.js +++ b/gulp/taskHelper.js @@ -12,7 +12,7 @@ import { resolve } from 'path'; * Get access to configruable values */ nconf.argv().env().file({ file: 'config.json' }); -export var conf = nconf; +export const conf = nconf; /* * Kill a child process and any sub-children that process may have spawned. @@ -26,11 +26,12 @@ export function kill (proc) { pids.forEach(kill); return; } try { - exec(/^win/.test(process.platform) - ? `taskkill /PID ${pid} /T /F` - : `kill -9 ${pid}`); + exec(/^win/.test(process.platform) ? + `taskkill /PID ${pid} /T /F` : + `kill -9 ${pid}`); + } catch (e) { + console.log(e); // eslint-disable-line no-console } - catch (e) { console.log(e); } }); }; @@ -44,21 +45,25 @@ export function kill (proc) { * before failing. */ export function awaitPort (port, max = 60) { - return new Bluebird((reject, resolve) => { - let socket, timeout, interval; + return new Bluebird((rej, res) => { + let socket; + let timeout; + let interval; timeout = setTimeout(() => { clearInterval(interval); - reject(`Timed out after ${max} seconds`); + rej(`Timed out after ${max} seconds`); }, max * 1000); interval = setInterval(() => { - socket = net.connect({port: port}, () => { + socket = net.connect({port}, () => { clearInterval(interval); clearTimeout(timeout); socket.destroy(); - resolve(); - }).on('error', () => { socket.destroy; }); + res(); + }).on('error', () => { + socket.destroy(); + }); }, 1000); }); } @@ -67,8 +72,12 @@ export function awaitPort (port, max = 60) { * Pipe the child's stdin and stderr to the parent process. */ export function pipe (child) { - child.stdout.on('data', (data) => { process.stdout.write(data); }); - child.stderr.on('data', (data) => { process.stderr.write(data); }); + child.stdout.on('data', (data) => { + process.stdout.write(data); + }); + child.stderr.on('data', (data) => { + process.stderr.write(data); + }); } /* @@ -78,8 +87,8 @@ export function postToSlack (msg, config = {}) { let slackUrl = nconf.get('SLACK_URL'); if (!slackUrl) { - console.error('No slack post url specified. Your message was:'); - console.log(msg); + console.error('No slack post url specified. Your message was:'); // eslint-disable-line no-console + console.log(msg); // eslint-disable-line no-console return; } @@ -89,15 +98,15 @@ export function postToSlack (msg, config = {}) { channel: `#${config.channel || '#general'}`, username: config.username || 'gulp task', text: msg, - icon_emoji: `:${config.emoji || 'gulp'}:`, + icon_emoji: `:${config.emoji || 'gulp'}:`, // eslint-disable-line camelcase }) - .end((err, res) => { - if (err) console.error('Unable to post to slack', err); + .end((err) => { + if (err) console.error('Unable to post to slack', err); // eslint-disable-line no-console }); } export function runMochaTests (files, server, cb) { - require('../test/helpers/globals.helper'); + require('../test/helpers/globals.helper'); // eslint-disable-line global-require let mocha = new Mocha({reporter: 'spec'}); let tests = glob(files); @@ -108,7 +117,7 @@ export function runMochaTests (files, server, cb) { }); mocha.run((numberOfFailures) => { - if (!process.env.RUN_INTEGRATION_TEST_FOREVER) { + if (!process.env.RUN_INTEGRATION_TEST_FOREVER) { // eslint-disable-line no-process-env if (server) kill(server); process.exit(numberOfFailures); } diff --git a/gulpfile.js b/gulpfile.js index be729233ab..59188792bc 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -8,11 +8,11 @@ require('babel-register'); -if (process.env.NODE_ENV === 'production') { - require('./gulp/gulp-apidoc'); - require('./gulp/gulp-build'); - require('./gulp/gulp-bootstrap'); +if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env + require('./gulp/gulp-apidoc'); // eslint-disable-line global-require + require('./gulp/gulp-build'); // eslint-disable-line global-require + require('./gulp/gulp-bootstrap'); // eslint-disable-line global-require } else { - require('glob').sync('./gulp/gulp-*').forEach(require); - require('gulp').task('default', ['test']); + require('glob').sync('./gulp/gulp-*').forEach(require); // eslint-disable-line global-require + require('gulp').task('default', ['test']); // eslint-disable-line global-require }