mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-24 11:03:17 -04:00
feat(curriculum): implement selective build mode for curriculum processing (#63081)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -338,13 +338,18 @@ export async function parseCurriculumStructure(filter?: Filter) {
|
||||
|
||||
export async function buildCurriculum(lang: string, filters?: Filter) {
|
||||
const contentDir = getContentDir(lang);
|
||||
const fccSuperblock = process.env.FCC_SUPERBLOCK;
|
||||
|
||||
const combinedFilters: Filter | undefined = fccSuperblock
|
||||
? { ...filters, superBlock: fccSuperblock }
|
||||
: filters;
|
||||
|
||||
const builder = new SuperblockCreator(
|
||||
getBlockCreator(lang, !isEmpty(filters))
|
||||
getBlockCreator(lang, !isEmpty(combinedFilters))
|
||||
);
|
||||
|
||||
const { fullSuperblockList, certifications } =
|
||||
await parseCurriculumStructure(filters);
|
||||
await parseCurriculumStructure(combinedFilters);
|
||||
|
||||
const fullCurriculum: {
|
||||
[key: string]: unknown;
|
||||
@@ -357,7 +362,6 @@ export async function buildCurriculum(lang: string, filters?: Filter) {
|
||||
const superOrder = getSuperOrder(name);
|
||||
const upcomingSuperOrder = getSuperOrder(name, true);
|
||||
|
||||
// If a superblock is not in either order list it should not exist.
|
||||
if (isUndefined(superOrder) && isUndefined(upcomingSuperOrder)) {
|
||||
throw Error(`Invalid superBlock: ${name}`);
|
||||
}
|
||||
@@ -365,8 +369,8 @@ export async function buildCurriculum(lang: string, filters?: Filter) {
|
||||
});
|
||||
|
||||
for (const superblock of liveSuperblocks) {
|
||||
fullCurriculum[superblock.name] =
|
||||
await builder.processSuperblock(superblock);
|
||||
const processedSuperblock = await builder.processSuperblock(superblock);
|
||||
fullCurriculum[superblock.name] = processedSuperblock;
|
||||
}
|
||||
|
||||
for (const cert of certifications) {
|
||||
|
||||
@@ -73,20 +73,27 @@ export function filterByBlock<T extends { blocks: { dashedName: string }[] }>(
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the superblocks array to only include the superblock with the specified name.
|
||||
* Filters the superblocks array to only include superblocks with the specified name(s).
|
||||
* If no superBlock is provided, returns the original superblocks array.
|
||||
* Supports comma-separated superblock names for filtering multiple superblocks.
|
||||
*
|
||||
* @param {Array<Object>} superblocks - Array of superblock objects.
|
||||
* @param {Object} [options] - Options object
|
||||
* @param {string} [options.superBlock] - The name of the superblock to filter for.
|
||||
* @returns {Array<Object>} Filtered array of superblocks containing only the specified superblock, or the original array if superBlock is not provided.
|
||||
* @param {string} [options.superBlock] - The name(s) of the superblock(s) to filter for (comma-separated for multiple).
|
||||
* @returns {Array<Object>} Filtered array of superblocks containing only the specified superblock(s), or the original array if superBlock is not provided.
|
||||
*/
|
||||
export function filterBySuperblock<T extends { name: string }>(
|
||||
superblocks: T[],
|
||||
{ superBlock }: { superBlock?: string } = {}
|
||||
): T[] {
|
||||
if (!superBlock) return superblocks;
|
||||
return superblocks.filter(({ name }) => name === superBlock);
|
||||
|
||||
const superBlockList = superBlock
|
||||
.split(',')
|
||||
.map(s => s.trim())
|
||||
.filter(s => s.length > 0);
|
||||
|
||||
return superblocks.filter(({ name }) => superBlockList.includes(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,6 +182,12 @@ export function closestFilters(
|
||||
): Filter | undefined {
|
||||
if (target?.superBlock) {
|
||||
const superblockNames = superblocks.map(({ name }) => name);
|
||||
|
||||
// If there are multiple superblocks, do not attempt to find a closest match.
|
||||
if (target.superBlock.includes(',')) {
|
||||
return target;
|
||||
}
|
||||
|
||||
return {
|
||||
...target,
|
||||
superBlock: closestMatch(target.superBlock, superblockNames)
|
||||
|
||||
@@ -15,16 +15,23 @@ import {
|
||||
|
||||
const globalConfigPath = path.resolve(__dirname, '../../../shared-dist/config');
|
||||
|
||||
// We are defaulting to English because the ids for the challenges are same
|
||||
// across all languages.
|
||||
const isSelectiveBuild = !!process.env.FCC_SUPERBLOCK;
|
||||
|
||||
void getChallengesForLang('english')
|
||||
.then(result => {
|
||||
buildExtCurriculumDataV1(
|
||||
result as unknown as CurriculumV1<CurriculumPropsV1>
|
||||
);
|
||||
buildExtCurriculumDataV2(
|
||||
result as unknown as CurriculumV2<CurriculumPropsV2>
|
||||
);
|
||||
if (!isSelectiveBuild) {
|
||||
console.log('Building external curriculum data...');
|
||||
buildExtCurriculumDataV1(
|
||||
result as unknown as CurriculumV1<CurriculumPropsV1>
|
||||
);
|
||||
buildExtCurriculumDataV2(
|
||||
result as unknown as CurriculumV2<CurriculumPropsV2>
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
'Skipping external curriculum build (selective build mode active)'
|
||||
);
|
||||
}
|
||||
return result;
|
||||
})
|
||||
.then(JSON.stringify)
|
||||
|
||||
Reference in New Issue
Block a user