From d01e0e421ea61f4e6b66905afbb4ded677cf475f Mon Sep 17 00:00:00 2001 From: Alex Chaffee Date: Mon, 26 Mar 2018 14:20:54 -0400 Subject: [PATCH] feat(seed): add dasherized titles to unpacked filenames --- CONTRIBUTING.md | 10 ++++++---- common/utils/index.js | 3 +++ seed/repack.js | 4 +--- seed/unpack.js | 21 ++++++++++++++++++--- seed/unpackedChallenge.js | 4 ++-- 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7d97028d4e..a926e9db81 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -499,6 +499,8 @@ When editing the unpacked files, you must only insert or edit lines between comm Unpacked lines that begin with `//--JSON:` are parsed and inserted verbatim. +If you want to **add a challenge**, **change the order** of challenges in a block, or **edit the title** or any other fields of a challenge, you must do that work *inside the main seed JSON file* and then re-run `unpack`. + ## Challenge Template ``` @@ -539,9 +541,9 @@ see also - [Challenge Style Guide](seed/challenge-style-guide.md) -- [Challenge schema](../common/models/challenge.json) - lists all of the fields inside challenge, and describes some of them +- [Challenge schema](./common/models/challenge.json) - lists all of the fields inside challenge, and describes some of them -- [Challenge types](../common/ap/utils/challengeTypes.js) - what the numeric challenge type values mean (enum) +- [Challenge types](./common/ap/utils/challengeTypes.js) - what the numeric challenge type values mean (enum) ### How We Review and Merge Pull Requests @@ -595,9 +597,9 @@ Be sure to post in the PR conversation that you have made the requested changes. - [Contributing to FreeCodeCamp - Writing ES6 Challenge Tests ](https://www.youtube.com/watch?v=iOdD84OSfAE#t=2h49m55s) - a video following [Ethan Arrowood](https://twitter.com/ArrowoodTech) as he contributes to the curriculum - - [Challenge schema](../common/models/challenge.json) - lists all of the fields inside challenge, and describes some of them + - [Challenge schema](./common/models/challenge.json) - lists all of the fields inside challenge, and describes some of them - - [Challenge types](../common/ap/utils/challengeTypes.js) - what the numeric challenge type values mean (enum) + - [Challenge types](./common/ap/utils/challengeTypes.js) - what the numeric challenge type values mean (enum) * Bugs and Issues: diff --git a/common/utils/index.js b/common/utils/index.js index 64e6beeac2..36fcadf900 100644 --- a/common/utils/index.js +++ b/common/utils/index.js @@ -5,3 +5,6 @@ export function dashify(str) { .replace(/[^a-z0-9\-\.]/gi, '') .replace(/\:/g, ''); } +// todo: unify with server/utils/index.js:dasherize +const dasherize = dashify; +export { dasherize }; diff --git a/seed/repack.js b/seed/repack.js index 149d66697d..e8106437ae 100644 --- a/seed/repack.js +++ b/seed/repack.js @@ -3,10 +3,8 @@ import fs from 'fs-extra'; import path from 'path'; import {UnpackedChallenge, ChallengeFile} from './unpackedChallenge'; -const jsdiff = require('diff'); - // Repack all challenges from all -// seed/unpacked/00-foo/bar/000-id.html files +// seed/unpacked/00-foo/bar/000-xxx-id.html files // into // seed/challenges/00-foo/bar.json files diff --git a/seed/unpack.js b/seed/unpack.js index 6307b19fa1..4f3e460ff8 100644 --- a/seed/unpack.js +++ b/seed/unpack.js @@ -15,9 +15,10 @@ import {UnpackedChallenge, ChallengeFile} from './unpackedChallenge'; // todo: figure out embedded images etc. served from elsewhere in the project // todo: prettier/clearer CSS +let unpackedDir = path.join(__dirname, 'unpacked'); + // bundle up the test-running JS function createUnpackedBundle() { - let unpackedDir = path.join(__dirname, 'unpacked'); fs.mkdirp(unpackedDir, (err) => { if (err && err.code !== 'EEXIST') { console.log(err); @@ -44,20 +45,34 @@ function createUnpackedBundle() { let currentlyUnpackingDir = null; +async function cleanUnpackedDir(unpackedChallengeBlockDir) { + let promiseToDelete = function(filePath) { + filePath = path.join(unpackedChallengeBlockDir, filePath); + return new Promise(() => fs.unlink(filePath)); + }; + let promises = fs.readdirSync(unpackedChallengeBlockDir) + .filter(filePath => (/\.html$/i).test(filePath)) + .map(promiseToDelete); + await Promise.all(promises); +} + function unpackChallengeBlock(challengeBlock) { let challengeBlockPath = path.parse(challengeBlock.fileName); let unpackedChallengeBlockDir = path.join( - __dirname, - 'unpacked', + unpackedDir, challengeBlockPath.dir, challengeBlockPath.name ); + fs.mkdirp(unpackedChallengeBlockDir, (err) => { if (err && err.code !== 'EEXIST') { console.log(err); throw err; } + // remove existing unpacked files + cleanUnpackedDir(unpackedChallengeBlockDir); + if (currentlyUnpackingDir !== challengeBlockPath.dir) { currentlyUnpackingDir = challengeBlockPath.dir; console.log(`Unpacking into ${currentlyUnpackingDir}:`); diff --git a/seed/unpackedChallenge.js b/seed/unpackedChallenge.js index 79a594d51d..28931dcbb8 100644 --- a/seed/unpackedChallenge.js +++ b/seed/unpackedChallenge.js @@ -2,6 +2,7 @@ import fs from 'fs-extra'; import path from 'path'; import _ from 'lodash'; +import { dasherize } from '../common/utils'; const jsonLinePrefix = '//--JSON:'; const paragraphBreak = ''; @@ -28,7 +29,6 @@ class ChallengeFile { }); } - readChunks() { // todo: make this work async // todo: make sure it works with encodings @@ -142,7 +142,7 @@ class UnpackedChallenge { // eslint-disable-next-line no-nested-ternary let prefix = ((this.index < 10) ? '00' : (this.index < 100) ? '0' : '') + this.index; - return `${prefix}-${this.challenge.id}`; + return `${prefix}-${dasherize(this.challenge.title)}-${this.challenge.id}`; } expandedDescription() {