@rhseung/ps-cli 1.7.4 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -19
- package/dist/{chunk-OJZLQ6FK.js → chunk-VIHXBCOZ.js} +30 -4
- package/dist/commands/fetch.js +5 -2
- package/dist/commands/run.js +40 -20
- package/dist/commands/test.js +17 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ ps test [문제번호] [옵션]
|
|
|
95
95
|
- `--language`, `-l`: 언어 선택 (지정 시 자동 감지 무시)
|
|
96
96
|
- 지원 언어: python, javascript, typescript, cpp
|
|
97
97
|
- `--watch`, `-w`: watch 모드 (파일 변경 시 자동 재테스트)
|
|
98
|
-
- solution._,
|
|
98
|
+
- solution._, testcases/\*\*/_.txt 파일 변경 감지
|
|
99
99
|
|
|
100
100
|
**예제:**
|
|
101
101
|
|
|
@@ -111,7 +111,7 @@ ps test --language python # Python으로 테스트
|
|
|
111
111
|
|
|
112
112
|
- 현재 디렉토리 또는 지정한 문제 번호의 테스트 실행
|
|
113
113
|
- solution.\* 파일을 자동으로 찾아 언어 감지
|
|
114
|
-
- input
|
|
114
|
+
- testcases/{번호}/input.txt와 testcases/{번호}/output.txt 파일을 기반으로 테스트
|
|
115
115
|
- 문제의 시간 제한을 자동으로 적용
|
|
116
116
|
|
|
117
117
|
---
|
|
@@ -131,22 +131,25 @@ ps run [문제번호] [옵션]
|
|
|
131
131
|
- `--language`, `-l`: 언어 선택 (지정 시 자동 감지 무시)
|
|
132
132
|
- 지원 언어: python, javascript, typescript, cpp
|
|
133
133
|
- `--input`, `-i`: 입력 파일 지정
|
|
134
|
-
-
|
|
134
|
+
- 숫자만 입력 시 testcases/{숫자}/input.txt로 자동 변환 (예: `--input 1`)
|
|
135
|
+
- 전체 경로도 지원 (예: testcases/1/input.txt)
|
|
135
136
|
|
|
136
137
|
**예제:**
|
|
137
138
|
|
|
138
139
|
```bash
|
|
139
|
-
ps run
|
|
140
|
-
ps run 1000
|
|
141
|
-
ps run --language python
|
|
142
|
-
ps run --input
|
|
140
|
+
ps run # 현재 디렉토리에서 표준 입력으로 실행
|
|
141
|
+
ps run 1000 # 1000번 문제 표준 입력으로 실행
|
|
142
|
+
ps run --language python # Python으로 표준 입력으로 실행
|
|
143
|
+
ps run --input 1 # 테스트 케이스 1번 사용
|
|
144
|
+
ps run --input testcases/1/input.txt # 전체 경로로 입력 파일 지정
|
|
143
145
|
```
|
|
144
146
|
|
|
145
147
|
**설명:**
|
|
146
148
|
|
|
147
149
|
- 현재 디렉토리 또는 지정한 문제 번호의 코드 실행
|
|
148
150
|
- solution.\* 파일을 자동으로 찾아 언어 감지
|
|
149
|
-
- input
|
|
151
|
+
- --input 옵션으로 입력 파일 지정 가능 (예: `--input 1` 또는 `--input testcases/1/input.txt`)
|
|
152
|
+
- 옵션 없이 실행 시 표준 입력으로 입력 받기
|
|
150
153
|
- 테스트 케이스 검증 없이 단순 실행
|
|
151
154
|
|
|
152
155
|
---
|
|
@@ -425,17 +428,6 @@ npm unlink -g @rhseung/ps-cli
|
|
|
425
428
|
|
|
426
429
|
**주의:** `npm link`를 사용하면 글로벌 설치된 버전이 링크된 버전으로 대체됩니다.
|
|
427
430
|
|
|
428
|
-
### 방법 3: 프로젝트 내에서만 테스트
|
|
429
|
-
|
|
430
|
-
```bash
|
|
431
|
-
# 빌드
|
|
432
|
-
bun run build
|
|
433
|
-
|
|
434
|
-
# 프로젝트 디렉토리 내에서만
|
|
435
|
-
bun run ps init
|
|
436
|
-
bun run ps fetch 1000
|
|
437
|
-
```
|
|
438
|
-
|
|
439
431
|
## 라이선스
|
|
440
432
|
|
|
441
433
|
MIT
|
|
@@ -6,7 +6,23 @@ import {
|
|
|
6
6
|
// src/services/runner.ts
|
|
7
7
|
import { readFile } from "fs/promises";
|
|
8
8
|
import { join } from "path";
|
|
9
|
+
import { createInterface } from "readline";
|
|
9
10
|
import { execa, execaCommand } from "execa";
|
|
11
|
+
async function readStdin() {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const lines = [];
|
|
14
|
+
const rl = createInterface({
|
|
15
|
+
input: process.stdin,
|
|
16
|
+
output: process.stdout
|
|
17
|
+
});
|
|
18
|
+
rl.on("line", (line) => {
|
|
19
|
+
lines.push(line);
|
|
20
|
+
});
|
|
21
|
+
rl.on("close", () => {
|
|
22
|
+
resolve(lines.join("\n"));
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
10
26
|
async function runSolution({
|
|
11
27
|
problemDir,
|
|
12
28
|
language,
|
|
@@ -16,7 +32,15 @@ async function runSolution({
|
|
|
16
32
|
const langConfig = getLanguageConfig(language);
|
|
17
33
|
const solutionFile = `solution.${langConfig.extension}`;
|
|
18
34
|
const solutionPath = join(problemDir, solutionFile);
|
|
19
|
-
|
|
35
|
+
let input;
|
|
36
|
+
let capturedInput;
|
|
37
|
+
if (inputPath) {
|
|
38
|
+
input = await readFile(inputPath, "utf-8");
|
|
39
|
+
capturedInput = input;
|
|
40
|
+
} else {
|
|
41
|
+
capturedInput = await readStdin();
|
|
42
|
+
input = capturedInput;
|
|
43
|
+
}
|
|
20
44
|
const start = Date.now();
|
|
21
45
|
try {
|
|
22
46
|
if (langConfig.compileCommand) {
|
|
@@ -27,7 +51,7 @@ async function runSolution({
|
|
|
27
51
|
}
|
|
28
52
|
const child = execa(langConfig.runCommand, [solutionPath], {
|
|
29
53
|
cwd: problemDir,
|
|
30
|
-
input,
|
|
54
|
+
...input !== void 0 ? { input } : { stdin: "inherit" },
|
|
31
55
|
timeout: timeoutMs
|
|
32
56
|
});
|
|
33
57
|
const result = await child;
|
|
@@ -39,7 +63,8 @@ async function runSolution({
|
|
|
39
63
|
stderr,
|
|
40
64
|
exitCode,
|
|
41
65
|
timedOut: false,
|
|
42
|
-
durationMs
|
|
66
|
+
durationMs,
|
|
67
|
+
...capturedInput !== void 0 && { input: capturedInput }
|
|
43
68
|
};
|
|
44
69
|
} catch (error) {
|
|
45
70
|
const durationMs = Date.now() - start;
|
|
@@ -50,7 +75,8 @@ async function runSolution({
|
|
|
50
75
|
stderr: err.stderr ?? err.shortMessage ?? err.message,
|
|
51
76
|
exitCode: err.exitCode ?? null,
|
|
52
77
|
timedOut: Boolean(err.timedOut),
|
|
53
|
-
durationMs
|
|
78
|
+
durationMs,
|
|
79
|
+
...capturedInput !== void 0 && { input: capturedInput }
|
|
54
80
|
};
|
|
55
81
|
}
|
|
56
82
|
return {
|
package/dist/commands/fetch.js
CHANGED
|
@@ -122,10 +122,13 @@ async function generateProblemFiles(problem, language = "python") {
|
|
|
122
122
|
"utf-8"
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
|
+
const testcasesDir = join(problemDir, "testcases");
|
|
125
126
|
for (let i = 0; i < problem.testCases.length; i++) {
|
|
126
127
|
const testCase = problem.testCases[i];
|
|
127
|
-
const
|
|
128
|
-
|
|
128
|
+
const caseDir = join(testcasesDir, String(i + 1));
|
|
129
|
+
await mkdir(caseDir, { recursive: true });
|
|
130
|
+
const inputPath = join(caseDir, "input.txt");
|
|
131
|
+
const outputPath = join(caseDir, "output.txt");
|
|
129
132
|
await writeFile(inputPath, testCase.input, "utf-8");
|
|
130
133
|
await writeFile(outputPath, testCase.output, "utf-8");
|
|
131
134
|
}
|
package/dist/commands/run.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runSolution
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-VIHXBCOZ.js";
|
|
5
5
|
import {
|
|
6
6
|
Command,
|
|
7
7
|
CommandBuilder,
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
} from "../chunk-7MQMPJ3X.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/run.tsx
|
|
18
|
-
import { readdir } from "fs/promises";
|
|
19
18
|
import { join } from "path";
|
|
20
19
|
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
21
20
|
import { Spinner } from "@inkjs/ui";
|
|
@@ -77,6 +76,17 @@ function RunView({
|
|
|
77
76
|
onComplete
|
|
78
77
|
});
|
|
79
78
|
if (status === "loading") {
|
|
79
|
+
if (!inputFile) {
|
|
80
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
81
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\uD45C\uC900 \uC785\uB825 \uB300\uAE30 \uC911" }) }),
|
|
82
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
83
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\uC785\uB825\uC744 \uC785\uB825\uD55C \uD6C4, \uB9C8\uC9C0\uB9C9 \uC904\uC5D0\uC11C Enter\uB97C \uB204\uB974\uACE0:" }),
|
|
84
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\u2022 macOS/Linux: Ctrl+D" }),
|
|
85
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\u2022 Windows: Ctrl+Z (\uADF8\uB9AC\uACE0 Enter)" }),
|
|
86
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: '\uC608: "3 4" \uC785\uB825 \u2192 Enter \u2192 Ctrl+D' })
|
|
87
|
+
] })
|
|
88
|
+
] });
|
|
89
|
+
}
|
|
80
90
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: "\uCF54\uB4DC \uC2E4\uD589 \uC911..." }) });
|
|
81
91
|
}
|
|
82
92
|
if (status === "error") {
|
|
@@ -87,7 +97,7 @@ function RunView({
|
|
|
87
97
|
}
|
|
88
98
|
if (result) {
|
|
89
99
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
90
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
100
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
91
101
|
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\uC2E4\uD589 \uACB0\uACFC" }),
|
|
92
102
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
93
103
|
problemDir,
|
|
@@ -102,9 +112,13 @@ function RunView({
|
|
|
102
112
|
result.exitCode,
|
|
103
113
|
")"
|
|
104
114
|
] }) : /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: "\uC2E4\uD589 \uC644\uB8CC" }),
|
|
115
|
+
result.input && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
116
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\uC785\uB825:" }),
|
|
117
|
+
/* @__PURE__ */ jsx(Text, { children: result.input.trim() })
|
|
118
|
+
] }),
|
|
105
119
|
result.stdout && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
106
120
|
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\uCD9C\uB825:" }),
|
|
107
|
-
/* @__PURE__ */ jsx(Text, { children: result.stdout })
|
|
121
|
+
/* @__PURE__ */ jsx(Text, { children: result.stdout.trim() })
|
|
108
122
|
] }),
|
|
109
123
|
result.stderr && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
110
124
|
/* @__PURE__ */ jsx(Text, { color: "yellow", dimColor: true, children: "\uC5D0\uB7EC \uCD9C\uB825:" }),
|
|
@@ -123,7 +137,20 @@ function RunView({
|
|
|
123
137
|
var RunCommand = class extends Command {
|
|
124
138
|
async execute(args, flags) {
|
|
125
139
|
const context = await resolveProblemContext(args);
|
|
126
|
-
|
|
140
|
+
let inputPath;
|
|
141
|
+
if (flags.input) {
|
|
142
|
+
const inputValue = flags.input;
|
|
143
|
+
if (/^\d+$/.test(inputValue)) {
|
|
144
|
+
inputPath = join(
|
|
145
|
+
context.archiveDir,
|
|
146
|
+
"testcases",
|
|
147
|
+
inputValue,
|
|
148
|
+
"input.txt"
|
|
149
|
+
);
|
|
150
|
+
} else {
|
|
151
|
+
inputPath = join(context.archiveDir, inputValue);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
127
154
|
const detectedLanguage = await resolveLanguage(
|
|
128
155
|
context.archiveDir,
|
|
129
156
|
flags.language
|
|
@@ -134,15 +161,6 @@ var RunCommand = class extends Command {
|
|
|
134
161
|
inputFile: inputPath
|
|
135
162
|
});
|
|
136
163
|
}
|
|
137
|
-
// 입력 파일 찾기: private 메서드
|
|
138
|
-
async findInputFile(problemDir) {
|
|
139
|
-
const files = await readdir(problemDir);
|
|
140
|
-
const inputFile = files.find((f) => f === "input1.txt") || files.find((f) => f === "input.txt");
|
|
141
|
-
if (!inputFile) {
|
|
142
|
-
throw new Error("input.txt \uB610\uB294 input1.txt \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
143
|
-
}
|
|
144
|
-
return join(problemDir, inputFile);
|
|
145
|
-
}
|
|
146
164
|
};
|
|
147
165
|
RunCommand = __decorateClass([
|
|
148
166
|
CommandDef({
|
|
@@ -150,7 +168,8 @@ RunCommand = __decorateClass([
|
|
|
150
168
|
description: `\uCF54\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4 (\uD14C\uC2A4\uD2B8 \uC5C6\uC774).
|
|
151
169
|
- \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uCF54\uB4DC \uC2E4\uD589
|
|
152
170
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
153
|
-
- input
|
|
171
|
+
- --input \uC635\uC158\uC73C\uB85C \uC785\uB825 \uD30C\uC77C \uC9C0\uC815 \uAC00\uB2A5 (\uC608: testcases/1/input.txt)
|
|
172
|
+
- \uC635\uC158 \uC5C6\uC774 \uC2E4\uD589 \uC2DC \uD45C\uC900 \uC785\uB825\uC73C\uB85C \uC785\uB825 \uBC1B\uAE30
|
|
154
173
|
- \uD14C\uC2A4\uD2B8 \uCF00\uC774\uC2A4 \uAC80\uC99D \uC5C6\uC774 \uB2E8\uC21C \uC2E4\uD589`,
|
|
155
174
|
flags: [
|
|
156
175
|
{
|
|
@@ -165,17 +184,18 @@ RunCommand = __decorateClass([
|
|
|
165
184
|
name: "input",
|
|
166
185
|
options: {
|
|
167
186
|
shortFlag: "i",
|
|
168
|
-
description: "\uC785\uB825 \uD30C\uC77C \uC9C0\uC815 (\
|
|
187
|
+
description: "\uC785\uB825 \uD30C\uC77C \uC9C0\uC815 (\uC608: 1 \uB610\uB294 testcases/1/input.txt)"
|
|
169
188
|
}
|
|
170
189
|
}
|
|
171
190
|
],
|
|
172
191
|
autoDetectProblemId: true,
|
|
173
192
|
autoDetectLanguage: true,
|
|
174
193
|
examples: [
|
|
175
|
-
"run
|
|
176
|
-
"run 1000
|
|
177
|
-
"run --language python
|
|
178
|
-
"run --input
|
|
194
|
+
"run # \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uD45C\uC900 \uC785\uB825\uC73C\uB85C \uC2E4\uD589",
|
|
195
|
+
"run 1000 # 1000\uBC88 \uBB38\uC81C \uD45C\uC900 \uC785\uB825\uC73C\uB85C \uC2E4\uD589",
|
|
196
|
+
"run --language python # Python\uC73C\uB85C \uD45C\uC900 \uC785\uB825\uC73C\uB85C \uC2E4\uD589",
|
|
197
|
+
"run --input 1 # \uD14C\uC2A4\uD2B8 \uCF00\uC774\uC2A4 1\uBC88 \uC0AC\uC6A9",
|
|
198
|
+
"run --input testcases/1/input.txt # \uC804\uCCB4 \uACBD\uB85C\uB85C \uC785\uB825 \uD30C\uC77C \uC9C0\uC815"
|
|
179
199
|
]
|
|
180
200
|
})
|
|
181
201
|
], RunCommand);
|
package/dist/commands/test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runSolution
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-VIHXBCOZ.js";
|
|
5
5
|
import {
|
|
6
6
|
Command,
|
|
7
7
|
CommandBuilder,
|
|
@@ -122,8 +122,14 @@ async function runAllTests({
|
|
|
122
122
|
language,
|
|
123
123
|
timeoutMs
|
|
124
124
|
}) {
|
|
125
|
-
const
|
|
126
|
-
|
|
125
|
+
const testcasesDir = join(problemDir, "testcases");
|
|
126
|
+
let caseDirs = [];
|
|
127
|
+
try {
|
|
128
|
+
const entries = await readdir(testcasesDir);
|
|
129
|
+
caseDirs = entries.filter((entry) => /^\d+$/.test(entry)).sort((a, b) => Number(a) - Number(b)).map((entry) => join(testcasesDir, entry));
|
|
130
|
+
} catch {
|
|
131
|
+
return { results: [], summary: buildSummary([]) };
|
|
132
|
+
}
|
|
127
133
|
const results = [];
|
|
128
134
|
let effectiveTimeout = timeoutMs;
|
|
129
135
|
if (effectiveTimeout == null) {
|
|
@@ -147,11 +153,10 @@ async function runAllTests({
|
|
|
147
153
|
if (effectiveTimeout == null) {
|
|
148
154
|
effectiveTimeout = 5e3;
|
|
149
155
|
}
|
|
150
|
-
for (const
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const outputPath = join(problemDir, `output${caseId}.txt`);
|
|
156
|
+
for (const caseDir of caseDirs) {
|
|
157
|
+
const caseId = Number(join(caseDir).split("/").pop() || "0");
|
|
158
|
+
const inputPath = join(caseDir, "input.txt");
|
|
159
|
+
const outputPath = join(caseDir, "output.txt");
|
|
155
160
|
let expected;
|
|
156
161
|
try {
|
|
157
162
|
expected = await readFile(outputPath, "utf-8");
|
|
@@ -160,7 +165,7 @@ async function runAllTests({
|
|
|
160
165
|
caseId,
|
|
161
166
|
inputPath,
|
|
162
167
|
status: "error",
|
|
163
|
-
error: "\uAE30\uB300 \uCD9C\uB825(output
|
|
168
|
+
error: "\uAE30\uB300 \uCD9C\uB825(output.txt)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
164
169
|
});
|
|
165
170
|
continue;
|
|
166
171
|
}
|
|
@@ -246,8 +251,7 @@ function useTestRunner({
|
|
|
246
251
|
const watcher = chokidar.watch(
|
|
247
252
|
[
|
|
248
253
|
join2(problemDir, "solution.*"),
|
|
249
|
-
join2(problemDir, "
|
|
250
|
-
join2(problemDir, "output*.txt")
|
|
254
|
+
join2(problemDir, "testcases", "**", "*.txt")
|
|
251
255
|
],
|
|
252
256
|
{
|
|
253
257
|
ignoreInitial: true
|
|
@@ -335,7 +339,7 @@ TestCommand = __decorateClass([
|
|
|
335
339
|
description: `\uC608\uC81C \uC785\uCD9C\uB825 \uAE30\uBC18\uC73C\uB85C \uB85C\uCEEC \uD14C\uC2A4\uD2B8\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.
|
|
336
340
|
- \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uD14C\uC2A4\uD2B8 \uC2E4\uD589
|
|
337
341
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
338
|
-
- input
|
|
342
|
+
- testcases/{\uBC88\uD638}/input.txt\uC640 testcases/{\uBC88\uD638}/output.txt \uD30C\uC77C\uC744 \uAE30\uBC18\uC73C\uB85C \uD14C\uC2A4\uD2B8
|
|
339
343
|
- \uBB38\uC81C\uC758 \uC2DC\uAC04 \uC81C\uD55C\uC744 \uC790\uB3D9\uC73C\uB85C \uC801\uC6A9
|
|
340
344
|
- --watch \uC635\uC158\uC73C\uB85C \uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8`,
|
|
341
345
|
flags: [
|
|
@@ -352,7 +356,7 @@ TestCommand = __decorateClass([
|
|
|
352
356
|
options: {
|
|
353
357
|
shortFlag: "w",
|
|
354
358
|
description: `watch \uBAA8\uB4DC (\uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8)
|
|
355
|
-
solution.*,
|
|
359
|
+
solution.*, testcases/**/*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0`
|
|
356
360
|
}
|
|
357
361
|
}
|
|
358
362
|
],
|