diff --git a/client/utils/build-challenges.js b/client/utils/build-challenges.js index e09c8d61467..948631afd51 100644 --- a/client/utils/build-challenges.js +++ b/client/utils/build-challenges.js @@ -2,10 +2,6 @@ const path = require('path'); const _ = require('lodash'); -const { - getChallengesForLang -} = require('@freecodecamp/curriculum/get-challenges'); - const { getBlockCreator, getSuperblocks, @@ -14,12 +10,14 @@ const { const { getContentDir, getBlockStructure, - getSuperblockStructure + getSuperblockStructure, + CURRICULUM_DIR } = require('@freecodecamp/curriculum/file-handler'); const { transformSuperBlock } = require('@freecodecamp/curriculum/build-superblock'); const { getSuperOrder } = require('@freecodecamp/curriculum/super-order'); +const { readFile } = require('fs/promises'); const curriculumLocale = process.env.CURRICULUM_LOCALE || 'english'; @@ -72,7 +70,12 @@ exports.replaceChallengeNodes = () => { }; exports.buildChallenges = async function buildChallenges() { - const curriculum = await getChallengesForLang(curriculumLocale); + const curriculum = JSON.parse( + await readFile( + path.resolve(CURRICULUM_DIR, 'generated', 'curriculum.json'), + 'utf-8' + ) + ); const superBlocks = Object.keys(curriculum); const blocks = superBlocks .map(superBlock => curriculum[superBlock].blocks) diff --git a/curriculum/src/config.ts b/curriculum/src/config.ts index 20cd146e828..34001a9816b 100644 --- a/curriculum/src/config.ts +++ b/curriculum/src/config.ts @@ -1,4 +1,5 @@ -import { resolve } from 'path'; +import { resolve } from 'node:path'; +import assert from 'node:assert'; import { config } from 'dotenv'; import { availableLangs } from '@freecodecamp/shared/config/i18n'; @@ -7,20 +8,15 @@ config({ path: resolve(__dirname, '../../.env') }); const curriculumLangs = availableLangs.curriculum; -// checks that the CURRICULUM_LOCALE exists and is an available language -export function testedLang() { - if (process.env.CURRICULUM_LOCALE) { - if (curriculumLangs.includes(process.env.CURRICULUM_LOCALE)) { - return process.env.CURRICULUM_LOCALE; - } else { - throw Error(`${process.env.CURRICULUM_LOCALE} is not a supported language. - Before the site can be built, this language needs to be manually approved`); - } - } else { - throw Error('CURRICULUM_LOCALE must be set for testing'); - } +function isAllowedLang(lang: string): lang is (typeof curriculumLangs)[number] { + return curriculumLangs.includes(lang as (typeof curriculumLangs)[number]); } +assert.ok(process.env.CURRICULUM_LOCALE); +assert.ok(isAllowedLang(process.env.CURRICULUM_LOCALE)); + +export const CURRICULUM_LOCALE = process.env.CURRICULUM_LOCALE; + export const SHOW_UPCOMING_CHANGES = process.env.SHOW_UPCOMING_CHANGES === 'true'; diff --git a/curriculum/src/file-handler.ts b/curriculum/src/file-handler.ts index fc248f7b11d..9dd72174e67 100644 --- a/curriculum/src/file-handler.ts +++ b/curriculum/src/file-handler.ts @@ -26,7 +26,7 @@ if (typeof __dirname !== 'undefined') { __dirnameCompat = dirname(fileURLToPath(metaUrl)); } -const CURRICULUM_DIR = resolve(__dirnameCompat, '..'); +export const CURRICULUM_DIR = resolve(__dirnameCompat, '..'); const I18N_CURRICULUM_DIR = resolve( CURRICULUM_DIR, 'i18n-curriculum', diff --git a/curriculum/src/generate/build-curriculum.ts b/curriculum/src/generate/build-curriculum.ts index 38973f25c61..873aac408b3 100644 --- a/curriculum/src/generate/build-curriculum.ts +++ b/curriculum/src/generate/build-curriculum.ts @@ -2,10 +2,11 @@ import fs from 'fs'; import path from 'path'; import { getChallengesForLang } from '../get-challenges'; +import { CURRICULUM_LOCALE } from '../config'; const globalConfigPath = path.resolve(__dirname, '../../generated/'); -void getChallengesForLang('english') +void getChallengesForLang(CURRICULUM_LOCALE) .then(JSON.stringify) .then(json => { fs.mkdirSync(globalConfigPath, { recursive: true }); diff --git a/curriculum/src/lint-localized.ts b/curriculum/src/lint-localized.ts index 4cd1299afdc..c8572c76007 100644 --- a/curriculum/src/lint-localized.ts +++ b/curriculum/src/lint-localized.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import { configure } from '@freecodecamp/challenge-linter'; -import { testedLang } from './config'; +import { CURRICULUM_LOCALE } from './config'; const CONFIG_PATH = path.resolve(__dirname, '../challenges/.markdownlint.yaml'); const { lintAll } = configure(CONFIG_PATH); -lintAll(`challenges/${testedLang()}/**/*.md`); +lintAll(`challenges/${CURRICULUM_LOCALE}/**/*.md`); diff --git a/curriculum/src/test/daily-challenges.test.js b/curriculum/src/test/daily-challenges.test.js index cdc56e5527a..3d538124fe1 100644 --- a/curriculum/src/test/daily-challenges.test.js +++ b/curriculum/src/test/daily-challenges.test.js @@ -4,12 +4,11 @@ vi.stubEnv('SHOW_UPCOMING_CHANGES', 'true'); // We need to use dynamic imports here to ensure the environment variable is set // before the module is loaded. -const { testedLang } = await import('../config.js'); +const { CURRICULUM_LOCALE } = await import('../config.js'); const { getChallenges } = await import('./test-challenges.js'); describe('Daily Coding Challenges', async () => { - const lang = testedLang(); - const challenges = await getChallenges(lang, { + const challenges = await getChallenges(CURRICULUM_LOCALE, { superBlock: 'dev-playground' }); @@ -57,7 +56,7 @@ describe('Daily Coding Challenges', async () => { } // skip these for non-English for now. - if (lang !== 'english') continue; + if (CURRICULUM_LOCALE !== 'english') continue; if (jsChallenge.title !== pyChallenge.title) { errors.push( diff --git a/curriculum/src/test/test-challenges.js b/curriculum/src/test/test-challenges.js index 9db5891a9df..3960c251b21 100644 --- a/curriculum/src/test/test-challenges.js +++ b/curriculum/src/test/test-challenges.js @@ -16,7 +16,7 @@ import { challengeSchemaValidator } from '../../schema/challenge-schema.js'; import { curriculumSchemaValidator } from '../../schema/curriculum-schema.js'; import { validateMetaSchema } from '../../schema/meta-schema.js'; import { getBlockStructure } from '../file-handler.js'; -import { FCC_CHALLENGE_ID, testedLang } from '../config.js'; +import { FCC_CHALLENGE_ID, CURRICULUM_LOCALE } from '../config.js'; import ChallengeTitles from './utils/challenge-titles.js'; import MongoIds from './utils/mongo-ids.js'; import createPseudoWorker from './utils/pseudo-worker.js'; @@ -79,8 +79,7 @@ async function newPageContext() { } export async function defineTestsForBlock(testFilter) { - const lang = testedLang(); - const challenges = await getChallenges(lang, testFilter); + const challenges = await getChallenges(CURRICULUM_LOCALE, testFilter); const nonCertificationChallenges = challenges.filter( ({ challengeType }) => challengeType !== 7 ); @@ -107,7 +106,7 @@ export async function defineTestsForBlock(testFilter) { } } - const challengeData = { meta, challenges, lang }; + const challengeData = { meta, challenges, lang: CURRICULUM_LOCALE }; describe('Check challenges', async () => { beforeAll(async () => { diff --git a/curriculum/turbo.json b/curriculum/turbo.json index 77b0fdd98af..0b21130b7db 100644 --- a/curriculum/turbo.json +++ b/curriculum/turbo.json @@ -4,7 +4,7 @@ "tasks": { "build": { "outputs": ["dist/**", "generated/**"], - "env": ["FCC_*", "SHOW_UPCOMING_CHANGES"] + "env": ["FCC_*", "SHOW_UPCOMING_CHANGES", "CURRICULUM_LOCALE"] }, "test": { "passThroughEnv": ["VITEST_POOL_ID", "PUPPETEER_WS_ENDPOINT"], diff --git a/docker/api/Dockerfile b/docker/api/Dockerfile index 61beabfbdf6..86e76a2bd93 100644 --- a/docker/api/Dockerfile +++ b/docker/api/Dockerfile @@ -26,6 +26,8 @@ RUN cd api && pnpm prisma generate # following env vars. ARG SHOW_UPCOMING_CHANGES=false ENV SHOW_UPCOMING_CHANGES=$SHOW_UPCOMING_CHANGES +ARG CURRICULUM_LOCALE=english +ENV CURRICULUM_LOCALE=$CURRICULUM_LOCALE RUN pnpm turbo -F=@freecodecamp/api build diff --git a/tools/challenge-helper-scripts/turbo.json b/tools/challenge-helper-scripts/turbo.json new file mode 100644 index 00000000000..abbf5e13935 --- /dev/null +++ b/tools/challenge-helper-scripts/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://v2-8-7.turborepo.dev/schema.json", + "extends": ["//"], + "tasks": { + "test": { + "env": ["CURRICULUM_LOCALE", "SHOW_UPCOMING_CHANGES"] + } + } +}