Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: support add new problem by script #32

Merged
merged 5 commits into from
Feb 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Please follow the commit specification. See [`.commitlintrc.json`](https://githu
### Commonly used NPM scripts

```bash
# add new problem
$ yarn new
# run project in development mode
$ yarn dev
# build all dist files
Expand Down
7 changes: 5 additions & 2 deletions config/problems.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,22 @@
"key": "HelloWorld",
"subject": "Basic Tutorial",
"subjectKey": "BasicTutorial",
"title": "Hello, world!"
"title": "Hello, world!",
"author": "ZLY201"
},
{
"key": "EverydayTypes",
"subject": "Basic Tutorial",
"subjectKey": "BasicTutorial",
"title": "EveryDay Types"
"title": "EveryDay Types",
"author": "ZLY201"
},
{
"key": "TransposeMatrix",
"subject": "Difficulties",
"subjectKey": "Difficulties",
"title": "Transpose Matrix",
"author": "ZLY201",
"cases": [
{
"source": "[[1, 2]]",
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dev": "yarn build:ssr && rspack serve --watch",
"build:ssr": "yarn clean && rspack build --config=rspack.ssr.config.ts",
"build": "yarn build:ssr && rspack build && rm -rf dist/ssr",
"new": "ts-node tools/addNewProblem.ts",
"lint": "eslint --fix --color --cache --quiet .",
"prepare": "husky install"
},
Expand Down Expand Up @@ -58,6 +59,7 @@
"@types/event-emitter": "^0.3.4",
"@types/lodash.debounce": "^4.0.7",
"@types/node": "^20.8.9",
"@types/prompts": "^2.4.9",
"@types/react": "^17.0.67",
"@types/react-copy-to-clipboard": "^5.0.6",
"@types/react-dom": "^17.0.21",
Expand All @@ -82,6 +84,7 @@
"lint-staged": "^14.0.1",
"monaco-editor": "^0.44.0",
"prettier": "^3.0.3",
"prompts": "^2.4.2",
"style-loader": "^3.3.3",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
Expand Down
33 changes: 13 additions & 20 deletions src/modules/Question/Description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Skeleton } from '@arco-design/web-react';
import debounce from 'lodash.debounce';
import Markdown from '@src/components/Markdown';
import Context from '@src/utils/context';
import linkJson from '@config/links.json';
import {
getProblemDocs,
NULL_CASE,
Expand All @@ -24,15 +23,7 @@ const Description = function () {
setting: { theme, language },
},
] = useContext(Context);
const {
key,
title,
contributor: { name, link } = {
name: 'ZLY201',
link: linkJson['github-zly201'],
},
cases = [NULL_CASE],
} = currentProblem;
const { key, title, author, cases = [NULL_CASE] } = currentProblem;
const [desc, setDesc] = useState('');
const [state, setState] = useState(false);
const [loading, setLoading] = useState(true);
Expand Down Expand Up @@ -107,16 +98,18 @@ const Description = function () {
</div>
</Skeleton>
</div>
<div className={styles['desc-footer']}>
<a
href={link}
target={'_blank'}
rel="noreferrer"
className={styles['desc-contributor']}
>
Provided By @{name}
</a>
</div>
{author && (
<div className={styles['desc-footer']}>
<a
href={`https://github.com/${author}`}
target={'_blank'}
rel="noreferrer"
className={styles['desc-contributor']}
>
Provided By @{author}
</a>
</div>
)}
</div>
);
};
Expand Down
5 changes: 1 addition & 4 deletions src/utils/problems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ export type Problem = {
subject: string;
subjectKey: string;
title: string;
contributor?: {
name: string;
link: string;
};
author?: string;
keywords?: string[];
cases?: {
source: string;
Expand Down
117 changes: 117 additions & 0 deletions tools/addNewProblem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import fs from 'fs';
import path from 'path';
import prompts from 'prompts';
import chalk from 'chalk';
import problemJson from '../config/problems.json';

const PROBLEMS_PATH = path.resolve(__dirname, '../problems');
const NEW_TYPE_TAG = 'new problem type';
const HELLO_WORLD_PATH = path.resolve(
PROBLEMS_PATH,
'basic-tutorial/1-hello-world',
);
const PROBLEM_JSON_PATH = path.resolve(__dirname, '../config/problems.json');

function handleStringWithDivider(source: string, divider: string = '') {
return source
.split('-')
.map(str => `${str[0].toUpperCase()}${str.slice(1)}`)
.join(divider);
}

async function main() {
const types: string[] = [];
const typeFiles = fs.readdirSync(PROBLEMS_PATH);
typeFiles.forEach(function (item) {
const stat = fs.lstatSync(path.resolve(PROBLEMS_PATH, item));
if (stat.isDirectory() === true) {
types.push(item);
}
});
const typesChoices: prompts.Choice[] = types.map(type => ({
title: type,
value: type,
}));
typesChoices.push({
title: NEW_TYPE_TAG,
value: NEW_TYPE_TAG,
description: 'Add a new problem type',
});
let { problemType } = await prompts({
type: 'select',
name: 'problemType',
message: 'What type of problem do you want to create?',
choices: typesChoices,
});
if (problemType === NEW_TYPE_TAG) {
const { newTypeName } = await prompts({
type: 'text',
name: 'newTypeName',
initial: 'template-type',
message: 'What is the name of the new type?',
validate: value =>
value === NEW_TYPE_TAG || types.includes(value)
? 'This type already exists!'
: Boolean(value),
});
fs.mkdirSync(path.resolve(PROBLEMS_PATH, newTypeName));
problemType = newTypeName;
}
const problemDirPath = path.resolve(PROBLEMS_PATH, problemType);
const problemsFiles = fs.readdirSync(problemDirPath);
const problemNumber =
problemsFiles.filter(function (item) {
const stat = fs.lstatSync(path.resolve(problemDirPath, item));
return stat.isDirectory();
}).length + 1;
const { newProblemName } = await prompts({
type: 'text',
name: 'newProblemName',
message: 'What is the name of the new problem?',
initial: 'template-problem',
validate: value =>
value === NEW_TYPE_TAG ||
problemsFiles.includes(`${problemNumber}-${value}`)
? 'This problem already exists!'
: Boolean(value),
});
const { githubName } = await prompts({
type: 'text',
name: 'githubName',
message: 'Your github name to thanks:',
});
const newProblemPath = path.resolve(
problemDirPath,
`${problemNumber}-${newProblemName}`,
);
fs.cpSync(HELLO_WORLD_PATH, newProblemPath, { recursive: true });
problemJson.push({
key: handleStringWithDivider(newProblemName),
subject: handleStringWithDivider(problemType, ' '),
subjectKey: handleStringWithDivider(problemType),
title: handleStringWithDivider(newProblemName, ' '),
author: githubName,
cases: [],
});
fs.writeFileSync(
PROBLEM_JSON_PATH,
JSON.stringify(problemJson, undefined, 2),
{
encoding: 'utf-8',
},
);
console.log(
`The new problem ${chalk.underline.green(
`${problemType}:${newProblemName}`,
)} has been created at ${chalk.underline.blue(
`problems/${problemNumber}-${newProblemName}`,
)}.`,
);
console.log(
`Please go ${chalk.blue.underline(
'config/problems.json',
)} to edit the config of this new problem.`,
);
}

main();
26 changes: 26 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1941,6 +1941,14 @@
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901"
integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==

"@types/prompts@^2.4.9":
version "2.4.9"
resolved "https://registry.yarnpkg.com/@types/prompts/-/prompts-2.4.9.tgz#8775a31e40ad227af511aa0d7f19a044ccbd371e"
integrity sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==
dependencies:
"@types/node" "*"
kleur "^3.0.3"

"@types/prop-types@*":
version "15.7.10"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.10.tgz#892afc9332c4d62a5ea7e897fe48ed2085bbb08a"
Expand Down Expand Up @@ -5209,6 +5217,11 @@ kind-of@^6.0.3:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==

kleur@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==

kleur@^4.0.3:
version "4.1.5"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
Expand Down Expand Up @@ -6657,6 +6670,14 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==

prompts@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069"
integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==
dependencies:
kleur "^3.0.3"
sisteransi "^1.0.5"

prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
Expand Down Expand Up @@ -7373,6 +7394,11 @@ sirv@^1.0.7:
mrmime "^1.0.0"
totalist "^1.0.0"

sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==

slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
Expand Down
Loading