From d095fd5d901903f7a3679d1ddbd5c967af68a47f Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 9 Nov 2015 17:27:56 -0800 Subject: [PATCH 1/3] Feature in dev mode always pull from disk --- common/models/challenge.json | 4 ++++ gulpfile.js | 10 ++++++--- seed/getChallenges.js | 5 ++++- seed/index.js | 3 +++ server/boot/challenge.js | 30 ++++++++++++++++--------- server/utils/getFromDisk$.js | 31 ++++++++++++++++++++++++++ server/views/coursewares/showHTML.jade | 1 - 7 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 server/utils/getFromDisk$.js diff --git a/common/models/challenge.json b/common/models/challenge.json index 72953fa78e..10ce49a058 100644 --- a/common/models/challenge.json +++ b/common/models/challenge.json @@ -54,6 +54,10 @@ "default": [], "description": "prepended to user code" }, + "fileName": { + "type": "string", + "description": "filename challenge comes from. Used in dev mode" + }, "challengeSeed": { "type": "array" }, diff --git a/gulpfile.js b/gulpfile.js index 1730d0971a..a5612bb938 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -93,8 +93,7 @@ var paths = { ], challenges: [ - 'seed/challenges/*.json', - 'seed/under-construction/*.json' + 'seed/challenges/*.json' ] }; @@ -399,10 +398,15 @@ var watchDependents = [ 'pack-watch-manifest' ]; +gulp.task('reload', () => { + notify({ message: 'test changed' }); + reload(); +}); + gulp.task('watch', watchDependents, function() { gulp.watch(paths.lessFiles, ['less']); gulp.watch(paths.js, ['js']); - gulp.watch(paths.challenges, ['test-challenges']); + gulp.watch(paths.challenges, ['test-challenges', 'reload']); gulp.watch(paths.js, ['js', 'dependents']); gulp.watch(paths.dependents, ['dependents']); gulp.watch(paths.manifest + '/*.json', ['build-manifest-watch']); diff --git a/seed/getChallenges.js b/seed/getChallenges.js index f86a3fc8c6..771050de0d 100644 --- a/seed/getChallenges.js +++ b/seed/getChallenges.js @@ -10,7 +10,10 @@ module.exports = function getChallenges() { try { return getFilesFor('challenges') .map(function(file) { - return require('./challenges/' + file); + var challengeSpec = require('./challenges/' + file); + challengeSpec.fileName = file; + + return challengeSpec; }); } catch (e) { console.log('error', e); diff --git a/seed/index.js b/seed/index.js index c11360d6a7..6b252a2486 100644 --- a/seed/index.js +++ b/seed/index.js @@ -18,6 +18,7 @@ destroy() var order = challengeSpec.order; var block = challengeSpec.name; var isBeta = !!challengeSpec.isBeta; + var fileName = challengeSpec.fileName; console.log('parsed %s successfully', block); // challenge file has no challenges... @@ -37,6 +38,8 @@ destroy() .toLowerCase() .replace(/\:/g, '') .replace(/\s/g, '-'); + + challenge.fileName = fileName; challenge.order = order; challenge.suborder = index + 1; challenge.block = block; diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 69e9298d7c..ca316bc97e 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -4,7 +4,15 @@ import moment from 'moment'; import { Observable, Scheduler } from 'rx'; import assign from 'object.assign'; import debugFactory from 'debug'; -import utils from '../utils'; + +import { + dasherize, + unDasherize, + getMDNLinks, + randomVerb, + randomPhrase, + randomCompliment +} from '../utils'; import { saveUser, @@ -16,6 +24,8 @@ import { ifNoUserSend } from '../utils/middleware'; +import getFromDisk$ from '../utils/getFromDisk$'; + const isDev = process.env.NODE_ENV !== 'production'; const isBeta = !!process.env.BETA; const debug = debugFactory('freecc:challenges'); @@ -31,10 +41,6 @@ const challengeView = { 7: 'coursewares/showStep' }; -const dasherize = utils.dasherize; -const unDasherize = utils.unDasherize; -const getMDNLinks = utils.getMDNLinks; - /* function makeChallengesUnique(challengeArr) { // clone and reverse challenges @@ -262,6 +268,12 @@ module.exports = function(app) { return testChallengeName.test(challenge.name); }) .last({ defaultValue: null }) + .flatMap(challenge => { + if (challenge && isDev) { + return getFromDisk$(challenge); + } + return Observable.just(challenge); + }) .flatMap(challenge => { // Handle not found @@ -311,11 +323,9 @@ module.exports = function(app) { MDNlinks: getMDNLinks(challenge.MDNlinks), // htmls specific - environment: utils.whichEnvironment(), - - verb: utils.randomVerb(), - phrase: utils.randomPhrase(), - compliment: utils.randomCompliment() + verb: randomVerb(), + phrase: randomPhrase(), + compliment: randomCompliment() }); }) .subscribe( diff --git a/server/utils/getFromDisk$.js b/server/utils/getFromDisk$.js new file mode 100644 index 0000000000..299fdde6be --- /dev/null +++ b/server/utils/getFromDisk$.js @@ -0,0 +1,31 @@ +import _ from 'lodash'; +import path from 'path'; +import { Observable } from 'rx'; + +const basePath = process.cwd() + '/seed/challenges/'; + +export default function getFromDisk$(challenge) { + delete require.cache[require.resolve( + path.join(basePath, challenge.fileName) + )]; + + return Observable.just(require(path.join(basePath, challenge.fileName))) + .map(challengeSpec => challengeSpec.challenges[challenge.suborder - 1]) + .map(challenge => { + challenge.head = challenge.head || []; + challenge.tail = challenge.tail || []; + challenge.challengeType = '' + challenge.challengeType; + + challenge.name = + _.capitalize(challenge.type) + + ': ' + + challenge.title.replace(/[^a-zA-Z0-9\s]/g, ''); + + challenge.dashedName = challenge.name + .toLowerCase() + .replace(/\:/g, '') + .replace(/\s/g, '-'); + + return challenge; + }); +} diff --git a/server/views/coursewares/showHTML.jade b/server/views/coursewares/showHTML.jade index 698918cf6e..b7e3fce299 100644 --- a/server/views/coursewares/showHTML.jade +++ b/server/views/coursewares/showHTML.jade @@ -100,7 +100,6 @@ block content common.challengeType = !{JSON.stringify(challengeType)}; common.dashedName = !{JSON.stringify(dashedName)}; - common.prodOrDev = !{JSON.stringify(environment)}; common.started = Math.floor(Date.now()); include ../partials/challenge-footer From 533a3f1d580e0715226226ed74a80b5328737a39 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 9 Nov 2015 22:31:31 -0800 Subject: [PATCH 2/3] Don't use es6 in gulpfile --- gulpfile.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index a5612bb938..614403a623 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -398,7 +398,7 @@ var watchDependents = [ 'pack-watch-manifest' ]; -gulp.task('reload', () => { +gulp.task('reload', function() { notify({ message: 'test changed' }); reload(); }); From 1619a09da25e7a3704101395bcea6790eb159145 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 9 Nov 2015 22:37:16 -0800 Subject: [PATCH 3/3] Add helpful error message if no filename --- server/utils/getFromDisk$.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/utils/getFromDisk$.js b/server/utils/getFromDisk$.js index 299fdde6be..b6e24fe3ca 100644 --- a/server/utils/getFromDisk$.js +++ b/server/utils/getFromDisk$.js @@ -5,6 +5,12 @@ import { Observable } from 'rx'; const basePath = process.cwd() + '/seed/challenges/'; export default function getFromDisk$(challenge) { + if (challenge && !challenge.fileName) { + throw new Error( + `Challenge ${challenge.name} has no fileName. + Did you remember run node seed?` + ); + } delete require.cache[require.resolve( path.join(basePath, challenge.fileName) )];