refactor: handle certs separately (#44434)
* refactor: split createChallenge into two functions * refactor: remove certification metas * fix: remove the metas I missed
This commit is contained in:
committed by
GitHub
parent
40acfa708b
commit
9ad29e03d5
@ -6,6 +6,7 @@ const envData = require('../../config/env.json');
|
||||
const {
|
||||
getChallengesForLang,
|
||||
createChallenge,
|
||||
createCertification,
|
||||
challengesDir,
|
||||
getChallengesDirForLang
|
||||
} = require('../../curriculum/getChallenges');
|
||||
@ -25,13 +26,11 @@ exports.replaceChallengeNode = () => {
|
||||
`../../curriculum/challenges/_meta/${blockName}/meta.json`
|
||||
);
|
||||
delete require.cache[require.resolve(metaPath)];
|
||||
const isCert = path.extname(filePath) === '.yml';
|
||||
const meta = require(metaPath);
|
||||
return await createChallenge(
|
||||
challengesDir,
|
||||
filePath,
|
||||
curriculumLocale,
|
||||
meta
|
||||
);
|
||||
return isCert
|
||||
? await createCertification(challengesDir, filePath, curriculumLocale)
|
||||
: await createChallenge(challengesDir, filePath, curriculumLocale, meta);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Back End Development and APIs Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "back-end-development-and-apis-certification",
|
||||
"order": 5,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac38a17523bc",
|
||||
"Back End Development and APIs Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Data Analysis with Python Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "data-analysis-with-python-v7-certification",
|
||||
"order": 8,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5e46fc95ac417301a38fb934",
|
||||
"Data Analysis with Python Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Data Visualization Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "data-visualization-certification",
|
||||
"order": 3,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5a553ca864b52e1d8bceea14",
|
||||
"Data Visualization Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Front End Development Libraries Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "front-end-development-libraries-certification",
|
||||
"order": 2,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561acd10cb82ac38a17513bc",
|
||||
"Front End Development Libraries Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Information Security Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "information-security-v7-certification",
|
||||
"order": 9,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5e6021435ac9d0ecd8b94b00",
|
||||
"Information Security Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "JavaScript Algorithms and Data Structures Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "javascript-algorithms-and-data-structures-certification",
|
||||
"order": 1,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561abd10cb81ac38a17513bc",
|
||||
"JavaScript Algorithms and Data Structures Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Legacy Back End Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "legacy-back-end-certification",
|
||||
"order": 12,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"660add10cb82ac38a17513be",
|
||||
"Legacy Back End Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Legacy Data Visualization Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "legacy-data-visualization-certification",
|
||||
"order": 13,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac39a17513bc",
|
||||
"Legacy Data Visualization Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Legacy Front End Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "legacy-front-end-certification",
|
||||
"order": 11,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac38a17513be",
|
||||
"Legacy Front End Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Legacy Full Stack Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "full-stack-certification",
|
||||
"order": 15,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac38a17213bd",
|
||||
"Legacy Full Stack Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Legacy Information Security and Quality Assurance Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "information-security-and-quality-assurance-certification",
|
||||
"order": 14,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac38a17213bc",
|
||||
"Legacy Information Security and Quality Assurance Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Machine Learning with Python Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "machine-learning-with-python-v7-certification",
|
||||
"order": 10,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5e46fc95ac417301a38fb935",
|
||||
"Machine Learning with Python Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Quality Assurance Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "quality-assurance-v7-certification",
|
||||
"order": 6,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5e611829481575a52dc59c0e",
|
||||
"Quality Assurance Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Relational Databases Certification",
|
||||
"isUpcomingChange": true,
|
||||
"dashedName": "relational-databases-v8-certification",
|
||||
"order": 4,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"606243f50267e718b1e755f4",
|
||||
"Relational Databases Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Responsive Web Design Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "responsive-web-design-certification",
|
||||
"order": 0,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"561add10cb82ac38a17513bc",
|
||||
"Responsive Web Design Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "Scientific Computing with Python Certification",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "scientific-computing-with-python-v7-certification",
|
||||
"order": 7,
|
||||
"time": "",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "certifications",
|
||||
"challengeOrder": [
|
||||
[
|
||||
"5e44431b903586ffb414c951",
|
||||
"Scientific Computing with Python Certification"
|
||||
]
|
||||
],
|
||||
"isPrivate": true
|
||||
}
|
@ -172,6 +172,13 @@ exports.getChallengesForLang = async function getChallengesForLang(lang) {
|
||||
};
|
||||
|
||||
async function buildBlocks({ basename: blockName }, curriculum, superBlock) {
|
||||
// TODO: this is a hack to avoid fetching the meta for the certifications.
|
||||
// Instead, the certifications should be moved from the challenges directory
|
||||
// and handled separately.
|
||||
if (superBlock === 'certifications') {
|
||||
curriculum[superBlock].blocks[blockName] = { challenges: [] };
|
||||
return;
|
||||
}
|
||||
const metaPath = path.resolve(
|
||||
__dirname,
|
||||
`./challenges/_meta/${blockName}/meta.json`
|
||||
@ -199,10 +206,10 @@ async function buildSuperBlocks({ path, fullPath }, curriculum) {
|
||||
return walk(fullPath, curriculum, { depth: 1, type: 'directories' }, cb);
|
||||
}
|
||||
|
||||
async function buildChallenges({ path }, curriculum, lang) {
|
||||
async function buildChallenges({ path: filePath }, curriculum, lang) {
|
||||
// path is relative to getChallengesDirForLang(lang)
|
||||
const block = getBlockNameFromPath(path);
|
||||
const { name: superBlock } = superBlockInfoFromPath(path);
|
||||
const block = getBlockNameFromPath(filePath);
|
||||
const { name: superBlock } = superBlockInfoFromPath(filePath);
|
||||
let challengeBlock;
|
||||
|
||||
// TODO: this try block and process exit can all go once errors terminate the
|
||||
@ -219,8 +226,10 @@ async function buildChallenges({ path }, curriculum, lang) {
|
||||
process.exit(1);
|
||||
}
|
||||
const { meta } = challengeBlock;
|
||||
|
||||
const challenge = await createChallenge(challengesDir, path, lang, meta);
|
||||
const isCert = path.extname(filePath) === '.yml';
|
||||
const challenge = isCert
|
||||
? await createCertification(challengesDir, filePath, lang)
|
||||
: await createChallenge(challengesDir, filePath, lang, meta);
|
||||
|
||||
challengeBlock.challenges = [...challengeBlock.challenges, challenge];
|
||||
}
|
||||
@ -236,6 +245,17 @@ async function parseTranslation(transPath, dict, lang, parse = parseMD) {
|
||||
: translatedChal;
|
||||
}
|
||||
|
||||
async function createCertification(basePath, filePath, lang) {
|
||||
function getFullPath(pathLang) {
|
||||
return path.resolve(__dirname, basePath, pathLang, filePath);
|
||||
}
|
||||
const { name: superBlock } = superBlockInfoFromPath(filePath);
|
||||
const useEnglish = lang === 'english' || !isAuditedCert(lang, superBlock);
|
||||
return useEnglish
|
||||
? parseCert(getFullPath('english'))
|
||||
: parseCert(getFullPath(lang));
|
||||
}
|
||||
|
||||
async function createChallenge(basePath, filePath, lang, maybeMeta) {
|
||||
function getFullPath(pathLang) {
|
||||
return path.resolve(__dirname, basePath, pathLang, filePath);
|
||||
@ -264,18 +284,11 @@ ${getFullPath('english')}
|
||||
// while the auditing is ongoing, we default to English for un-audited certs
|
||||
// once that's complete, we can revert to using isEnglishChallenge(fullPath)
|
||||
const useEnglish = lang === 'english' || !isAuditedCert(lang, superBlock);
|
||||
const isCert = path.extname(filePath) === '.yml';
|
||||
let challenge;
|
||||
|
||||
if (isCert) {
|
||||
challenge = await (useEnglish
|
||||
? parseCert(getFullPath('english'))
|
||||
: parseCert(getFullPath(lang)));
|
||||
} else {
|
||||
challenge = await (useEnglish
|
||||
? parseMD(getFullPath('english'))
|
||||
: parseTranslation(getFullPath(lang), COMMENT_TRANSLATIONS, lang));
|
||||
}
|
||||
const challenge = await (useEnglish
|
||||
? parseMD(getFullPath('english'))
|
||||
: parseTranslation(getFullPath(lang), COMMENT_TRANSLATIONS, lang));
|
||||
|
||||
const challengeOrder = findIndex(
|
||||
meta.challengeOrder,
|
||||
([id]) => id === challenge.id
|
||||
@ -363,3 +376,4 @@ function getBlockNameFromPath(filePath) {
|
||||
exports.hasEnglishSource = hasEnglishSource;
|
||||
exports.parseTranslation = parseTranslation;
|
||||
exports.createChallenge = createChallenge;
|
||||
exports.createCertification = createCertification;
|
||||
|
@ -198,7 +198,10 @@ async function setup() {
|
||||
const meta = {};
|
||||
for (const challenge of challenges) {
|
||||
const dashedBlockName = challenge.block;
|
||||
if (!meta[dashedBlockName]) {
|
||||
// certifications do not have dashedBlockName's and don't have metas so
|
||||
// we can skip them.
|
||||
// TODO: omit certifications from the list of challenges
|
||||
if (dashedBlockName && !meta[dashedBlockName]) {
|
||||
meta[dashedBlockName] = await getMetaForBlock(dashedBlockName);
|
||||
}
|
||||
}
|
||||
@ -296,6 +299,9 @@ function populateTestsForLang({ lang, challenges, meta }) {
|
||||
this.timeout(5000);
|
||||
challenges.forEach((challenge, id) => {
|
||||
const dashedBlockName = challenge.block;
|
||||
// TODO: once certifications are not included in the list of challenges,
|
||||
// stop returning early here.
|
||||
if (typeof dashedBlockName === 'undefined') return;
|
||||
describe(challenge.block || 'No block', function () {
|
||||
describe(challenge.title || 'No title', function () {
|
||||
// Note: the title in meta.json are purely for human readability and
|
||||
|
Reference in New Issue
Block a user