Skip to content

Commit 5af52e3

Browse files
cli finish basically (#5)
* feat(cli): 简化命令 使得命令可以在任何路径下运行 * fix:依赖调整 * fix:cli指令文件修改 * fix:修复路径带空格无法识别的bug * docs:调整todo * test(test): 补充测试用例 * test: add parse file path test case * fix:指令重构 * feat:scripts目录提升 * docs:目录文档 * fix:目录调整 * fix:目录调整 * chore:引入依赖包 * feat: node vm执行index.js脚本 * docs:更新贡献者 * chore:忽略缓存文件 * refactor: directory refactor BREAKING CHANGE: srcipts即将废弃,视图交互性代码完善1/3 * feat: finish the view create & check * feat:完成lc&lk指令 * fix: 优化代码 * feat: add getQuestionChineseName function to get chinese name * chore: del scripts and .vscode files & ignore .vscode * docs: update todo & achive * perf: better scripts and easy mode to create question in project * feat: publish config & build config * chore: del src * fix: perfect version for cli install * fix:指令打包完善 * fix:easy mode script * docs:todo 拆分成单独文件 * chore:路径调整成全局路径 * docs: add CHANGELOG and TO-DO --------- Co-authored-by: Hedwig-Fang <706964007@qq.com>
1 parent 1b8324d commit 5af52e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1567
-566
lines changed

.gitignore

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ dist-ssr
1515
*.local
1616

1717
# Editor directories and files
18+
.vscode
1819
.vscode/*
1920
!.vscode/extensions.json
2021
.idea
@@ -24,4 +25,10 @@ dist-ssr
2425
*.njsproj
2526
*.sln
2627
*.sw?
27-
coverage/**
28+
coverage/**
29+
30+
# store file
31+
resources/stores/*
32+
33+
# cli-dist
34+
pl-cli

.vscode/launch.json

-18
This file was deleted.

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# 1.0.0
2+
- cli: lk/lf/lc 脚本实现 检测/查找/创建 功能,强而有力地支持了题目的便捷创建.
3+
- template project: easy mode 实现交互性创建,leet-create和leet-check保持src目录下创建题解.
4+
- plugin: 插件化的设计完善,进行立项.

Readme.md

+15-50
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,13 @@
11
# Leetcode practice
22

3-
力扣练习库!开始你的每日一题!
4-
在编辑器中编写你的代码,简单有效的执行和计时!
5-
6-
## TO-DO List
7-
8-
### 功能
9-
10-
#### 优先级高
11-
12-
- [ ] 获取更完备的测试用例,增强用户体验
13-
- [ ] 获取题解和代码
14-
- [ ] commit到leetcode
15-
- [ ] 私人项目部署的实现方案
16-
17-
#### 优先级中
18-
19-
- [ ] 创建一个单独指令lc,用于项目的单独指令,忽略npm/yarn/pnpm的执行差异/歧义
3+
在力扣练习平台!开始你的每日一题!
204

21-
#### 优先级低
22-
23-
- [ ] 实现在编辑器中预览图片(感觉可以不做)
24-
25-
#### 代码优化及基础建设
26-
27-
- [ ] 优化随机题目的随机方式,减少请求
28-
- [ ] commonJS -> ES6 Module
29-
- [ ] 优化src下代码结构
30-
- [ ] 封装npm包,方便后续做成编辑器插件
31-
32-
### 已完归档
5+
在编辑器中编写你的代码,简单有效的执行和计时!
336

34-
- [x] 1.模板:获取js的函数体并替换生成文件中的@function
35-
- [x] 2.模板:从detail中获取输入用例的数据填充@Testcase
36-
- [x] 3.模板:获取跳转每日一题的链接替换@url
37-
- [x] 4.函数:优化时间和资源统计函数
38-
- [x] 5.优化创建时的体验,添加重复时候的确认覆盖或者添加额外符号
39-
- [x] 6.特殊数据结构的处理(链表ListNode,树TreeNode,无向连通图Node)的处理
40-
- [x] 7.创建某一特定编号的题目脚本,以及实现随机题目【随机题目汇集本地题目,然后排除自己本地存在的题目进行随机】
41-
- [x] 8.加入eslint
7+
我们的目标就是让所有人:
8+
> 只用专注于代码的实现,而非繁琐的输入输出!
429
43-
## How to use for yourself ?
10+
## Usage
4411

4512
fork分支`template`的内容,其非内容部分会与主分支保持同步,意思是去除部分我的题目代码,然后使用指令创建你自己的题解即可!
4613

@@ -69,8 +36,8 @@ yarn leet-create
6936

7037
会通过接口获取今日题目,并会在`src`目录下根据`题目的id`+`题目的英文翻译`创建一个目录,并将今日题目和基础示例代码填充到`index.js`中。
7138

72-
![创建目录](./resources/leet-create-0.png)
73-
![填充文件](resources/leet-create-1.png)
39+
![创建目录](resources/images/leet-create-0.png)
40+
![填充文件](resources/images/leet-create-1.png)
7441

7542
### 2. 检验今天的题目
7643

@@ -79,8 +46,6 @@ yarn leet-check
7946
```
8047

8148
此指令会根据今天的题目信息去执行对应的题目文件,输出结果。
82-
> NOTE:缓存的实现是在`commom/resouces/store.json`,如果只想让内容在本地存在,不上传到个人项目中的话,执行`git update-index --aussume-unchanged common/resources/store.json`来忽略本地的文件变更即可。
83-
>
8449

8550
```shell
8651
yarn leet-check
@@ -100,7 +65,7 @@ Done in 0.18s.
10065

10166
```
10267

103-
![检测题目](resources/leet-check.png)
68+
![检测题目](resources/images/leet-check.png)
10469

10570
### 3. 创建自己想要练习的题目
10671

@@ -123,9 +88,9 @@ yarn leet-create -i "LCP 29"
12388
└── index.js # 模板js文件 可以替换题目
12489
```
12590

126-
![1314cmd.png](resources/1314-cmd.png)
127-
![1314.png](resources/1314.png)
128-
![1314详情.png](resources/1314-detail.png)
91+
![1314cmd.png](resources/images/1314-cmd.png)
92+
![1314.png](resources/images/1314.png)
93+
![1314详情.png](resources/images/1314-detail.png)
12994

13095
### 4. 检验自己想要练习的结果
13196

@@ -177,7 +142,7 @@ Done in 0.19s.
177142

178143
```
179144

180-
![1314-check.png](resources/1314-check.png)
145+
![1314-check.png](resources/images/1314-check.png)
181146

182147
### 5. 获取随机题目
183148

@@ -191,7 +156,6 @@ yarn leet-create -r
191156
D:\GitHub\leetcode-practice> yarn leet-create -r
192157
yarn run v1.22.19
193158
$ node common/scripts/create.js -r
194-
[store]数据存储成功[random-question-info]:[[object Object]]
195159
[fulfillQuestion]题目[43][字符串相乘]已完成填充.
196160
Done in 1.78s.
197161
```
@@ -235,5 +199,6 @@ Done in 0.19s.
235199
236200
## Contributor
237201

238-
[EternalHeart](https://github.com/wh131462)
239-
[SmallTeddy](https://github.com/SmallTeddy)
202+
[<img src="https://avatars.githubusercontent.com/u/48346853" style="border-radius:50%;" width="30" height="30" alt="EternalHeart"/>](https://github.com/wh131462)
203+
[<img src="https://avatars.githubusercontent.com/u/61453917" style="border-radius:50%;" width="30" height="30" alt="SmartTeddy"/>](https://github.com/SmallTeddy)
204+
[<img src="https://avatars.githubusercontent.com/u/35305691" style="border-radius:50%;" width="30" height="30" alt="Hedwig-Fang"/>](https://github.com/Hedwig-Fang)

TO-DO.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## TO-DO List
2+
3+
### 功能
4+
5+
#### 优先级高
6+
7+
- [ ] commit到leetcode
8+
- [ ] 项目的升级检测以及升级脚本
9+
- [ ] 插件制作-WS/VS code
10+
11+
#### 优先级中
12+
13+
- [ ] 获取题解和代码
14+
- [ ] 获取更完备的测试用例,增强用户体验
15+
16+
#### 优先级低
17+
18+
#### 代码优化及基础建设
19+
20+
- [ ] 优化随机题目的随机方式,减少请求
21+
22+
### 已完归档
23+
24+
- [x] 1.模板:获取js的函数体并替换生成文件中的@function
25+
- [x] 2.模板:从detail中获取输入用例的数据填充@Testcase
26+
- [x] 3.模板:获取跳转每日一题的链接替换@url
27+
- [x] 4.函数:优化时间和资源统计函数
28+
- [x] 5.优化创建时的体验,添加重复时候的确认覆盖或者添加额外符号
29+
- [x] 6.特殊数据结构的处理(链表ListNode,树TreeNode,无向连通图Node)的处理
30+
- [x] 7.创建某一特定编号的题目脚本,以及实现随机题目【随机题目汇集本地题目,然后排除自己本地存在的题目进行随机】
31+
- [x] 8.加入eslint
32+
- [x] 9.私人项目部署的实现方案
33+
- [x] 10.commonJS -> ES6 Module
34+
- [x] 11.实现在编辑器中预览图片(markdown中可以查看)
35+
- [x] 12.使用realm进行持久化,替换store.json
36+
- [x] 13.实现lk/lf/lc指令的封装
37+
- [x] 14.重构工具代码,对UI和logic进行解耦
38+
- [x] 15.封装npm包,方便后续做成编辑器插件

bin/lc.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#! /usr/bin/env node
2+
import {program} from "commander";
3+
import {artFontLogo} from "#resources/text/art-font-logo.js";
4+
import {examples} from "#resources/text/examples.js";
5+
import {love} from "#resources/text/love.js";
6+
import {aim} from "#resources/text/aim.js";
7+
import {referMode} from "#common/utils/create-check/refer-mode.js";
8+
import {getArgs} from "#common/utils/create-check/get-args.js";
9+
import {getQuestionToday} from "#common/utils/question-getter/getQuestionToday.js";
10+
import {createQuestion} from "#common/utils/question-handler/createQuestion.js";
11+
import path from "path";
12+
import {getQuestionFileName} from "#common/utils/question-handler/getQuestionFileName.js";
13+
import {createQuestionCopy} from "#common/utils/question-handler/createQuestionCopy.js";
14+
import {getQuestionRandom} from "#common/utils/question-getter/getQuestionRandom.js";
15+
import {getQuestionById} from "#common/utils/question-getter/getQuestionById.js";
16+
import {setQuestion} from "#common/utils/store/store-realm.js";
17+
import {getQuestionChineseName} from "#common/utils/question-handler/getQuestionChineseName.js";
18+
import {easyCreateView} from "#common/view/create.view.js";
19+
import {description} from "#resources/text/description.js";
20+
21+
const version = process.env.VERSION??'0.0.0';
22+
program
23+
.version(version)
24+
.description(`${description}\n${artFontLogo}\n${aim}`)
25+
.addHelpText('after', examples+love)
26+
.arguments("[identity]")
27+
.option('-t, --today', 'Get a question today.')
28+
.option('-i, --identity <identity>', 'Specify a question by identity.')
29+
.option('-r, --random', 'Get a question randomly.')
30+
.option('-e, --easy', 'Use easy mode.')
31+
.option('-d, --directory <directory>', 'Set the question directory.')
32+
.parse(process.argv)
33+
34+
const cmdArgs = program.args;
35+
const cmdOpts = program.opts();
36+
/**
37+
* 执行逻辑:
38+
* 目录检测 - 设置基础目录
39+
* 模式检测 - 检测是不是easy mode
40+
* [参数检测 - 执行对应参数]
41+
*/
42+
// 根据dir 参数来设置基本目录
43+
const baseDir = cmdOpts.directory?path.join(process.cwd(),cmdOpts.directory):process.cwd();
44+
if(cmdOpts.easy){
45+
await easyCreateView();
46+
process.exit(0);;
47+
}
48+
// 创建
49+
const create = (mode,question)=>{
50+
console.log(`MODE: ${mode}`);
51+
return new Promise(resolve=>{
52+
setQuestion(mode,question);
53+
const questionDir = path.join(baseDir,getQuestionFileName(question))
54+
createQuestion(question,questionDir).then(async (path)=>{
55+
if(!path)path = await createQuestionCopy(question,questionDir);
56+
console.log(`题目[${getQuestionChineseName(question)}]获取成功!\n题目文件地址为:${path}`)
57+
resolve(true)
58+
})
59+
})
60+
}
61+
// 模式对应的action
62+
const callModeAction = {
63+
'today': () => {
64+
getQuestionToday().then(question=>{
65+
create("today",question).then(()=>{
66+
process.exit(0)
67+
});
68+
})
69+
},
70+
'random': () => {
71+
getQuestionRandom().then(question=>{
72+
create("random",question).then(()=>{
73+
process.exit(0)
74+
});
75+
})
76+
},
77+
'identity': (id) => {
78+
getQuestionById(id).then(question=>{
79+
create("identity",question).then(()=>{
80+
process.exit(0)
81+
});
82+
})
83+
},
84+
}
85+
// 获取模式和参数
86+
const mode = referMode(cmdArgs, cmdOpts);
87+
const args = getArgs(mode,cmdArgs,cmdOpts);
88+
// 执行指令分发
89+
await callModeAction[mode](args);

bin/lf.js

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#! /usr/bin/env node
2+
const version = process.env.VERSION??'0.0.0';

bin/lk.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#! /usr/bin/env node
2+
import {program} from "commander";
3+
import {artFontLogo} from "#resources/text/art-font-logo.js";
4+
import {examples} from "#resources/text/examples.js";
5+
import {love} from "#resources/text/love.js";
6+
import {aim} from "#resources/text/aim.js";
7+
import {referMode} from "#common/utils/create-check/refer-mode.js";
8+
import {getArgs} from "#common/utils/create-check/get-args.js";
9+
import fs from "fs";
10+
import path from "path";
11+
import {checkQuestion} from "#common/utils/question-handler/checkQuestion.js";
12+
import {getQuestionByMode} from "#common/utils/store/store-realm.js";
13+
import {getQuestionById} from "#common/utils/question-getter/getQuestionById.js";
14+
import {getQuestionFileName} from "#common/utils/question-handler/getQuestionFileName.js";
15+
import {getQuestionChineseName} from "#common/utils/question-handler/getQuestionChineseName.js";
16+
import {easyCheckView} from "#common/view/check.view.js";
17+
import {description} from "#resources/text/description.js";
18+
19+
const version = process.env.VERSION ?? '0.0.0';
20+
program
21+
.version(version)
22+
.description(`${description}\n${artFontLogo}\n${aim}`)
23+
.addHelpText('after', examples + love)
24+
.arguments("[identity]")
25+
.option('-t, --today', 'Check the question today.')
26+
.option('-i, --identity <identity>', 'Check the specified question by identity.')
27+
.option('-r, --random', 'Check the last random question.')
28+
.option('-e, --easy', 'Use easy mode.')
29+
.option('-d, --directory <directory>', 'Set the question directory.')
30+
.parse(process.argv)
31+
32+
const cmdArgs = program.args;
33+
const cmdOpts = program.opts();
34+
/**
35+
* 执行逻辑:
36+
* 目录检测 - 设置基础目录
37+
* 模式检测 - 检测是不是easy mode
38+
* [参数检测 - 执行对应参数]
39+
*/
40+
41+
// 根据dir 参数来设置基本目录
42+
const baseDir = cmdOpts.directory ? path.join(process.cwd(), cmdOpts.directory) : process.cwd();
43+
if (cmdOpts.easy) {
44+
await easyCheckView();
45+
process.exit(0);
46+
}
47+
//
48+
// 检测函数
49+
const check = async (mode, question) => {
50+
const filePath = path.join(baseDir, getQuestionFileName(question), 'index.js');
51+
if (!fs.existsSync(filePath)) {
52+
console.log(`文件[${filePath}]不存在,请确保已经创建!`)
53+
} else {
54+
console.log(`MODE: ${mode}\n题目[${getQuestionChineseName(question)}]检测结果:`)
55+
await checkQuestion(filePath);
56+
}
57+
return true;
58+
}
59+
// 模式对应的action
60+
const callModeAction = {
61+
'today': async () => {
62+
const question = await getQuestionByMode("today");
63+
await check('today', question)
64+
process.exit(0);
65+
},
66+
'random': async () => {
67+
const question = await getQuestionByMode("random");
68+
await check('today', question)
69+
process.exit(0);
70+
},
71+
'identity': async (id) => {
72+
const question = !id ?
73+
await getQuestionByMode(mode) :
74+
await getQuestionById(id);
75+
await check('today', question)
76+
process.exit(0);
77+
},
78+
}
79+
// 获取模式和参数
80+
const mode = referMode(cmdArgs, cmdOpts);
81+
const args = getArgs(mode, cmdArgs, cmdOpts);
82+
// 执行指令分发
83+
callModeAction[mode](args);

common/resources/store.json

-1
This file was deleted.

0 commit comments

Comments
 (0)