feat: create script to add step between two steps
This commit is contained in:
committed by
Mrugesh Mohapatra
parent
8223903aac
commit
282e7d922b
@ -16,6 +16,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"create-empty-steps": "cross-env CALLING_DIR=$INIT_CWD node ./tools/create-empty-steps",
|
"create-empty-steps": "cross-env CALLING_DIR=$INIT_CWD node ./tools/create-empty-steps",
|
||||||
"create-next-step": "cross-env CALLING_DIR=$INIT_CWD node ./tools/create-next-step",
|
"create-next-step": "cross-env CALLING_DIR=$INIT_CWD node ./tools/create-next-step",
|
||||||
|
"create-step-between": "cross-env CALLING_DIR=$INIT_CWD node ./tools/create-step-between",
|
||||||
"reorder-steps": "cross-env CALLING_DIR=$INIT_CWD node ./tools/reorder-steps",
|
"reorder-steps": "cross-env CALLING_DIR=$INIT_CWD node ./tools/reorder-steps",
|
||||||
"develop": "gulp",
|
"develop": "gulp",
|
||||||
"lint": "gulp lint",
|
"lint": "gulp lint",
|
||||||
|
@ -14,8 +14,8 @@ A one-off script that will automatically add the next step based on the last ste
|
|||||||
npm run create-next-step
|
npm run create-next-step
|
||||||
```
|
```
|
||||||
|
|
||||||
## [create-next-step.js](create-next-step.js)
|
## [create-empty-steps.js](create-empty-steps.js)
|
||||||
A one-off script that will automatically add a specified numbers of steps at a specific starting step number. The challenge seed code will be empty.
|
A one-off script that automatically adds a specified number of steps at a specific starting step number. The challenge seed code for all steps created will be empty.
|
||||||
|
|
||||||
**Note:** This script also runs [reorder-steps.js](reorder-steps.js).
|
**Note:** This script also runs [reorder-steps.js](reorder-steps.js).
|
||||||
|
|
||||||
@ -26,6 +26,17 @@ A one-off script that will automatically add a specified numbers of steps at a s
|
|||||||
npm run create-empty-steps start=X num=Y # where X is the starting step number and Y is the number of steps to create.
|
npm run create-empty-steps start=X num=Y # where X is the starting step number and Y is the number of steps to create.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## [create-step-between.js](create-step-between.js)
|
||||||
|
A one-off script that automatically adds a new step between two existing consecutive steps. The challenge seed code will use the existing starting step's challenge seed code with the editable region markers (ERMs) removed.
|
||||||
|
|
||||||
|
**Note:** This script also runs [reorder-steps.js](reorder-steps.js).
|
||||||
|
|
||||||
|
### How to run script:
|
||||||
|
1. Change to the directory of the project.
|
||||||
|
2. Run the following npm command:
|
||||||
|
```bash
|
||||||
|
npm run create-step-between start=X end=Y # where X is the starting step number and Y is the following step number.
|
||||||
|
|
||||||
## [reorder-steps.js](reorder-steps.js)
|
## [reorder-steps.js](reorder-steps.js)
|
||||||
A one-off script that automatically reorders the step files in a project's markdown files based on the filename. It also updates the `challengeOrder` property array in the project's `meta.json` with the new order of the steps.
|
A one-off script that automatically reorders the step files in a project's markdown files based on the filename. It also updates the `challengeOrder` property array in the project's `meta.json` with the new order of the steps.
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
const path = require('path');
|
const {
|
||||||
|
reorderSteps,
|
||||||
|
createStepFile,
|
||||||
|
getExistingStepNums,
|
||||||
|
getProjectPath
|
||||||
|
} = require('./utils');
|
||||||
|
|
||||||
const { reorderSteps, createStepFile } = require('./utils');
|
const anyStepExists = (steps, stepsToFind) =>
|
||||||
|
stepsToFind.some(num => steps.includes(num));
|
||||||
|
|
||||||
const projectPath = (process.env.CALLING_DIR || process.cwd()) + path.sep;
|
const projectPath = getProjectPath();
|
||||||
const argValuePairs = process.argv.slice(2);
|
const argValuePairs = process.argv.slice(2);
|
||||||
|
|
||||||
const args = argValuePairs.reduce((argsObj, arg) => {
|
const args = argValuePairs.reduce((argsObj, arg) => {
|
||||||
@ -23,6 +29,12 @@ if (num > 20) {
|
|||||||
|
|
||||||
const maxStepNum = stepStart + num - 1;
|
const maxStepNum = stepStart + num - 1;
|
||||||
|
|
||||||
|
const existingSteps = getExistingStepNums(projectPath);
|
||||||
|
|
||||||
|
if (anyStepExists(existingSteps, [start, maxStepNum])) {
|
||||||
|
throw `Step not created. At least one of the steps specified between ${start} and ${maxStepNum} already exists.`;
|
||||||
|
}
|
||||||
|
|
||||||
for (let stepNum = stepStart; stepNum <= maxStepNum; stepNum++) {
|
for (let stepNum = stepStart; stepNum <= maxStepNum; stepNum++) {
|
||||||
createStepFile({ stepNum, projectPath });
|
createStepFile({ stepNum, projectPath });
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const { reorderSteps, createStepFile } = require('./utils');
|
const {
|
||||||
|
reorderSteps,
|
||||||
|
createStepFile,
|
||||||
|
getChallengeSeed,
|
||||||
|
getProjectPath
|
||||||
|
} = require('./utils');
|
||||||
|
|
||||||
const getLastStepFileContent = () => {
|
const getLastStepFileContent = () => {
|
||||||
const filesArr = [];
|
const filesArr = [];
|
||||||
@ -20,24 +25,14 @@ const getLastStepFileContent = () => {
|
|||||||
if (filesArr.length !== lastStepFileNum) {
|
if (filesArr.length !== lastStepFileNum) {
|
||||||
throw `Error: The last file step is ${lastStepFileNum} and there are ${filesArr.length} files.`;
|
throw `Error: The last file step is ${lastStepFileNum} and there are ${filesArr.length} files.`;
|
||||||
}
|
}
|
||||||
const fileContent = fs.readFileSync(projectPath + fileName, 'utf8');
|
|
||||||
const matchedSection = fileContent
|
|
||||||
.toString()
|
|
||||||
.match(/<section id='challengeSeed'>(?<challengeSeed>[\s\S]+)<\/section>/);
|
|
||||||
let finalChallengeSeed;
|
|
||||||
if (matchedSection) {
|
|
||||||
let {
|
|
||||||
groups: { challengeSeed }
|
|
||||||
} = matchedSection;
|
|
||||||
finalChallengeSeed = challengeSeed ? challengeSeed : '';
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
nextStepNum: lastStepFileNum + 1,
|
nextStepNum: lastStepFileNum + 1,
|
||||||
challengeSeed: finalChallengeSeed
|
challengeSeed: getChallengeSeed(projectPath + fileName)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const projectPath = (process.env.CALLING_DIR || process.cwd()) + path.sep;
|
const projectPath = getProjectPath();
|
||||||
|
|
||||||
const { nextStepNum, challengeSeed } = getLastStepFileContent();
|
const { nextStepNum, challengeSeed } = getLastStepFileContent();
|
||||||
|
|
||||||
|
53
curriculum/tools/create-step-between.js
Normal file
53
curriculum/tools/create-step-between.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
const {
|
||||||
|
reorderSteps,
|
||||||
|
createStepFile,
|
||||||
|
getChallengeSeed,
|
||||||
|
padWithLeadingZeros,
|
||||||
|
getExistingStepNums,
|
||||||
|
getProjectPath
|
||||||
|
} = require('./utils');
|
||||||
|
|
||||||
|
const allStepsExist = (steps, stepsToFind) =>
|
||||||
|
stepsToFind.every(num => steps.includes(num));
|
||||||
|
|
||||||
|
const projectPath = getProjectPath();
|
||||||
|
const argValuePairs = process.argv.slice(2);
|
||||||
|
|
||||||
|
const args = argValuePairs.reduce((argsObj, arg) => {
|
||||||
|
const [argument, value] = arg.replace(/\s/g, '').split('=');
|
||||||
|
if (!argument || !value) {
|
||||||
|
throw `Invalid argument/value specified: ${arg}`;
|
||||||
|
}
|
||||||
|
return { ...argsObj, [argument]: value };
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
let { start, end } = args;
|
||||||
|
start = parseInt(start, 10);
|
||||||
|
end = parseInt(end, 10);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Number.isInteger(start) ||
|
||||||
|
!Number.isInteger(end) ||
|
||||||
|
start < 1 ||
|
||||||
|
start !== end - 1
|
||||||
|
) {
|
||||||
|
throw 'Step not created. Steps specified must be' +
|
||||||
|
' consecutive numbers and start step must be greater than 0.';
|
||||||
|
}
|
||||||
|
|
||||||
|
const existingSteps = getExistingStepNums(projectPath);
|
||||||
|
if (!allStepsExist(existingSteps, [start, end])) {
|
||||||
|
throw 'Step not created. At least one of the steps specified does not exist.';
|
||||||
|
}
|
||||||
|
|
||||||
|
const challengeSeed = getChallengeSeed(
|
||||||
|
`${projectPath}part-${padWithLeadingZeros(start)}.md`
|
||||||
|
);
|
||||||
|
createStepFile({
|
||||||
|
stepNum: start,
|
||||||
|
projectPath,
|
||||||
|
challengeSeed,
|
||||||
|
stepBetween: true
|
||||||
|
});
|
||||||
|
console.log(`Sucessfully added step between step #${start} and step #${end}`);
|
||||||
|
reorderSteps();
|
@ -20,11 +20,20 @@ const removeErms = seedCode => {
|
|||||||
.join('\n');
|
.join('\n');
|
||||||
};
|
};
|
||||||
|
|
||||||
const createStepFile = ({ projectPath, stepNum, challengeSeed = '' }) => {
|
const createStepFile = ({
|
||||||
|
projectPath,
|
||||||
|
stepNum,
|
||||||
|
challengeSeed = '',
|
||||||
|
stepBetween = false
|
||||||
|
}) => {
|
||||||
if (challengeSeed) {
|
if (challengeSeed) {
|
||||||
challengeSeed = removeErms(challengeSeed);
|
challengeSeed = removeErms(challengeSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const descStepNum = stepBetween ? stepNum + 1 : stepNum;
|
||||||
|
const stepDescription = `${
|
||||||
|
stepBetween ? 'new' : ''
|
||||||
|
} step ${descStepNum} instructions`;
|
||||||
const challengeSeedSection = `<section id='challengeSeed'>
|
const challengeSeedSection = `<section id='challengeSeed'>
|
||||||
|
|
||||||
${challengeSeed.trim()}
|
${challengeSeed.trim()}
|
||||||
@ -41,7 +50,7 @@ isHidden: true
|
|||||||
## Description
|
## Description
|
||||||
<section id='description'>
|
<section id='description'>
|
||||||
|
|
||||||
step ${stepNum} instructions
|
${stepDescription}
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -61,14 +70,13 @@ tests:
|
|||||||
${challengeSeedSection}
|
${challengeSeedSection}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
fs.writeFileSync(
|
let finalStepNum = padWithLeadingZeros(stepNum);
|
||||||
`${projectPath}part-${padWithLeadingZeros(stepNum)}.md`,
|
finalStepNum += stepBetween ? 'a' : '';
|
||||||
template
|
fs.writeFileSync(`${projectPath}part-${finalStepNum}.md`, template);
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const reorderSteps = () => {
|
const reorderSteps = () => {
|
||||||
const projectPath = (process.env.CALLING_DIR || process.cwd()) + path.sep;
|
const projectPath = getProjectPath();
|
||||||
|
|
||||||
const projectName = process.env.CALLING_DIR
|
const projectName = process.env.CALLING_DIR
|
||||||
? process.env.CALLING_DIR.split(path.sep)
|
? process.env.CALLING_DIR.split(path.sep)
|
||||||
@ -110,6 +118,7 @@ const reorderSteps = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (foundFinal) {
|
if (foundFinal) {
|
||||||
filesArr.push('final.md');
|
filesArr.push('final.md');
|
||||||
}
|
}
|
||||||
@ -161,8 +170,47 @@ const reorderSteps = () => {
|
|||||||
console.log('Reordered steps');
|
console.log('Reordered steps');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
const getChallengeSeed = challengeFilePath => {
|
||||||
padWithLeadingZeros,
|
const fileContent = fs.readFileSync(challengeFilePath, 'utf8');
|
||||||
createStepFile,
|
const matchedSection = fileContent
|
||||||
reorderSteps
|
.toString()
|
||||||
|
.match(/<section id='challengeSeed'>(?<challengeSeed>[\s\S]+)<\/section>/);
|
||||||
|
let finalChallengeSeed = '';
|
||||||
|
if (matchedSection) {
|
||||||
|
let {
|
||||||
|
groups: { challengeSeed }
|
||||||
|
} = matchedSection;
|
||||||
|
finalChallengeSeed = challengeSeed ? challengeSeed : '';
|
||||||
|
}
|
||||||
|
return finalChallengeSeed;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getExistingStepNums = projectPath => {
|
||||||
|
return fs.readdirSync(projectPath).reduce((stepNums, fileName) => {
|
||||||
|
if (
|
||||||
|
path.extname(fileName).toLowerCase() === '.md' &&
|
||||||
|
!fileName.endsWith('final.md')
|
||||||
|
) {
|
||||||
|
let stepNum = fileName.split('.')[0].split('-')[1];
|
||||||
|
if (!/^\d{3}$/.test(stepNum)) {
|
||||||
|
throw `Step not created. File ${fileName} has a step number containing non-digits.` +
|
||||||
|
' Please run reorder-steps script first.';
|
||||||
|
}
|
||||||
|
stepNum = parseInt(stepNum, 10);
|
||||||
|
stepNums.push(stepNum);
|
||||||
|
}
|
||||||
|
return stepNums;
|
||||||
|
}, []);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getProjectPath = () =>
|
||||||
|
(process.env.CALLING_DIR || process.cwd()) + path.sep;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
createStepFile,
|
||||||
|
getChallengeSeed,
|
||||||
|
padWithLeadingZeros,
|
||||||
|
reorderSteps,
|
||||||
|
getExistingStepNums,
|
||||||
|
getProjectPath
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user