2022-01-25 11:34:16 +01:00
|
|
|
import fs from 'fs';
|
|
|
|
import path from 'path';
|
|
|
|
import ObjectID from 'bson-objectid';
|
|
|
|
import * as matter from 'gray-matter';
|
|
|
|
import { getMetaData } from '../challenge-helper-scripts/helpers/get-project-path-metadata';
|
|
|
|
import { parseMDSync } from '../challenge-parser/parser';
|
|
|
|
import { getProjectMetaPath } from './helpers/get-project-meta-path';
|
|
|
|
import { getProjectPath } from './helpers/get-project-path';
|
|
|
|
import { ChallengeSeed, getStepTemplate } from './helpers/get-step-template';
|
|
|
|
import { padWithLeadingZeros } from './helpers/pad-with-leading-zeros';
|
|
|
|
|
|
|
|
interface Options {
|
|
|
|
projectPath: string;
|
|
|
|
stepNum: number;
|
|
|
|
challengeSeeds?: Record<string, ChallengeSeed>;
|
|
|
|
stepBetween?: boolean;
|
|
|
|
}
|
2020-08-25 02:35:46 -07:00
|
|
|
|
2020-08-27 18:57:51 -07:00
|
|
|
const createStepFile = ({
|
|
|
|
projectPath,
|
|
|
|
stepNum,
|
2021-03-31 09:19:46 -06:00
|
|
|
challengeSeeds = {},
|
2020-08-27 18:57:51 -07:00
|
|
|
stepBetween = false
|
2022-01-25 11:34:16 +01:00
|
|
|
}: Options) => {
|
|
|
|
const challengeId = new ObjectID();
|
2021-03-31 09:19:46 -06:00
|
|
|
|
2020-08-27 18:57:51 -07:00
|
|
|
let finalStepNum = padWithLeadingZeros(stepNum);
|
|
|
|
finalStepNum += stepBetween ? 'a' : '';
|
2021-07-06 19:22:12 -05:00
|
|
|
|
|
|
|
const template = getStepTemplate({
|
|
|
|
challengeId,
|
|
|
|
challengeSeeds,
|
|
|
|
stepBetween,
|
|
|
|
stepNum
|
|
|
|
});
|
|
|
|
|
2021-10-21 10:07:52 -07:00
|
|
|
fs.writeFileSync(`${projectPath}step-${finalStepNum}.md`, template);
|
2021-07-06 19:22:12 -05:00
|
|
|
|
2021-06-08 21:27:45 +02:00
|
|
|
return challengeId;
|
2020-08-25 02:35:46 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
const reorderSteps = () => {
|
2020-08-27 18:57:51 -07:00
|
|
|
const projectPath = getProjectPath();
|
2020-08-25 02:35:46 -07:00
|
|
|
|
|
|
|
const projectName = process.env.CALLING_DIR
|
2021-03-11 00:31:46 +05:30
|
|
|
? process.env.CALLING_DIR.split(path.sep).slice(-1).toString()
|
|
|
|
: process.cwd().split(path.sep).slice(-1).toString();
|
2020-08-25 02:35:46 -07:00
|
|
|
|
|
|
|
const curriculumPath = process.env.CALLING_DIR
|
|
|
|
? ''
|
2020-09-11 08:47:34 -07:00
|
|
|
: path.join(__dirname, '../');
|
2020-08-25 02:35:46 -07:00
|
|
|
|
2021-07-06 19:22:12 -05:00
|
|
|
const projectMetaPath = getProjectMetaPath(curriculumPath, projectName);
|
|
|
|
|
|
|
|
const parsedData = getMetaData(projectMetaPath);
|
2020-08-25 02:35:46 -07:00
|
|
|
|
|
|
|
let foundFinal = false;
|
|
|
|
const filesArr = [];
|
|
|
|
fs.readdirSync(projectPath).forEach(fileName => {
|
|
|
|
if (path.extname(fileName).toLowerCase() === '.md') {
|
|
|
|
if (!fileName.endsWith('final.md')) {
|
|
|
|
filesArr.push(fileName);
|
|
|
|
} else {
|
|
|
|
foundFinal = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2020-08-27 18:57:51 -07:00
|
|
|
|
2020-08-25 02:35:46 -07:00
|
|
|
if (foundFinal) {
|
|
|
|
filesArr.push('final.md');
|
|
|
|
}
|
|
|
|
|
|
|
|
const filesToReorder = filesArr.map((fileName, i) => {
|
|
|
|
const newStepNum = i + 1;
|
|
|
|
const newFileName =
|
|
|
|
fileName !== 'final.md'
|
2021-10-21 10:07:52 -07:00
|
|
|
? `step-${padWithLeadingZeros(newStepNum)}.md`
|
2020-08-25 02:35:46 -07:00
|
|
|
: 'final.md';
|
|
|
|
return {
|
|
|
|
oldFileName: fileName,
|
|
|
|
newFileName,
|
|
|
|
newStepNum
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2022-01-25 11:34:16 +01:00
|
|
|
const challengeOrder: string[][] = [];
|
2020-08-25 02:35:46 -07:00
|
|
|
|
|
|
|
filesToReorder.forEach(({ oldFileName, newFileName, newStepNum }) => {
|
|
|
|
fs.renameSync(
|
|
|
|
`${projectPath}${oldFileName}`,
|
|
|
|
`${projectPath}${newFileName}.tmp`
|
|
|
|
);
|
|
|
|
const filePath = `${projectPath}${newFileName}.tmp`;
|
|
|
|
const frontMatter = matter.read(filePath);
|
2022-01-25 11:34:16 +01:00
|
|
|
const challengeID =
|
|
|
|
(frontMatter.data.id as string) || new ObjectID().toString();
|
2020-08-25 02:35:46 -07:00
|
|
|
const title =
|
2021-10-21 10:07:52 -07:00
|
|
|
newFileName === 'final.md' ? 'Final Prototype' : `Step ${newStepNum}`;
|
|
|
|
const dashedName = `step-${newStepNum}`;
|
2020-08-25 02:35:46 -07:00
|
|
|
challengeOrder.push(['' + challengeID, title]);
|
|
|
|
const newData = {
|
|
|
|
...frontMatter.data,
|
|
|
|
id: challengeID,
|
2021-04-27 20:29:49 +02:00
|
|
|
title,
|
|
|
|
dashedName
|
2020-08-25 02:35:46 -07:00
|
|
|
};
|
2022-01-25 11:34:16 +01:00
|
|
|
fs.writeFileSync(filePath, matter.stringify(frontMatter.content, newData));
|
2020-08-25 02:35:46 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
filesToReorder.forEach(({ newFileName }) => {
|
|
|
|
fs.renameSync(
|
|
|
|
`${projectPath}${newFileName}.tmp`,
|
|
|
|
`${projectPath}${newFileName}`
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
const newMeta = { ...parsedData, challengeOrder };
|
|
|
|
fs.writeFileSync(projectMetaPath, JSON.stringify(newMeta, null, 2));
|
|
|
|
};
|
|
|
|
|
2022-01-25 11:34:16 +01:00
|
|
|
const getChallengeSeeds = (
|
|
|
|
challengeFilePath: string
|
|
|
|
): Record<string, ChallengeSeed> => {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
|
2021-09-07 15:54:11 +01:00
|
|
|
return parseMDSync(challengeFilePath).challengeFiles;
|
2020-08-27 18:57:51 -07:00
|
|
|
};
|
|
|
|
|
2022-01-25 11:34:16 +01:00
|
|
|
export { createStepFile, reorderSteps, getChallengeSeeds };
|