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:
Oliver Eyton-Williams
2021-12-09 20:53:12 +01:00
committed by GitHub
parent 40acfa708b
commit 9ad29e03d5
19 changed files with 42 additions and 295 deletions

View File

@ -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);
};
};

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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;

View File

@ -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