@rhseung/ps-cli 1.7.3 → 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 +277 -24
- package/dist/{chunk-TNGUME4H.js → chunk-F4LZ6ENP.js} +23 -24
- package/dist/{chunk-OJZLQ6FK.js → chunk-VIHXBCOZ.js} +30 -4
- package/dist/commands/{solve.js → archive.js} +37 -37
- package/dist/commands/config.js +16 -16
- package/dist/commands/fetch.js +42 -15
- package/dist/commands/init.js +51 -37
- package/dist/commands/open.js +2 -7
- package/dist/commands/run.js +44 -28
- package/dist/commands/search.js +4 -4
- package/dist/commands/stats.js +1 -1
- package/dist/commands/submit.js +5 -10
- package/dist/commands/test.js +21 -21
- package/package.json +2 -1
package/dist/commands/run.js
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
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,
|
|
8
8
|
CommandDef,
|
|
9
|
-
getProblemId,
|
|
10
9
|
resolveLanguage,
|
|
11
10
|
resolveProblemContext
|
|
12
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
13
12
|
import {
|
|
14
13
|
__decorateClass,
|
|
15
14
|
getSupportedLanguagesString
|
|
16
15
|
} from "../chunk-7MQMPJ3X.js";
|
|
17
16
|
|
|
18
17
|
// src/commands/run.tsx
|
|
19
|
-
import { readdir } from "fs/promises";
|
|
20
18
|
import { join } from "path";
|
|
21
19
|
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
22
20
|
import { Spinner } from "@inkjs/ui";
|
|
@@ -78,6 +76,17 @@ function RunView({
|
|
|
78
76
|
onComplete
|
|
79
77
|
});
|
|
80
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
|
+
}
|
|
81
90
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: "\uCF54\uB4DC \uC2E4\uD589 \uC911..." }) });
|
|
82
91
|
}
|
|
83
92
|
if (status === "error") {
|
|
@@ -88,7 +97,7 @@ function RunView({
|
|
|
88
97
|
}
|
|
89
98
|
if (result) {
|
|
90
99
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
91
|
-
/* @__PURE__ */ jsxs(Box, {
|
|
100
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
92
101
|
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\uC2E4\uD589 \uACB0\uACFC" }),
|
|
93
102
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
94
103
|
problemDir,
|
|
@@ -103,9 +112,13 @@ function RunView({
|
|
|
103
112
|
result.exitCode,
|
|
104
113
|
")"
|
|
105
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
|
+
] }),
|
|
106
119
|
result.stdout && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
107
120
|
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "\uCD9C\uB825:" }),
|
|
108
|
-
/* @__PURE__ */ jsx(Text, { children: result.stdout })
|
|
121
|
+
/* @__PURE__ */ jsx(Text, { children: result.stdout.trim() })
|
|
109
122
|
] }),
|
|
110
123
|
result.stderr && /* @__PURE__ */ jsxs(Box, { marginTop: 1, flexDirection: "column", children: [
|
|
111
124
|
/* @__PURE__ */ jsx(Text, { color: "yellow", dimColor: true, children: "\uC5D0\uB7EC \uCD9C\uB825:" }),
|
|
@@ -123,30 +136,31 @@ function RunView({
|
|
|
123
136
|
}
|
|
124
137
|
var RunCommand = class extends Command {
|
|
125
138
|
async execute(args, flags) {
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
const context = await resolveProblemContext(args);
|
|
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
|
+
}
|
|
131
154
|
const detectedLanguage = await resolveLanguage(
|
|
132
|
-
context.
|
|
155
|
+
context.archiveDir,
|
|
133
156
|
flags.language
|
|
134
157
|
);
|
|
135
158
|
await this.renderView(RunView, {
|
|
136
|
-
problemDir: context.
|
|
159
|
+
problemDir: context.archiveDir,
|
|
137
160
|
language: detectedLanguage,
|
|
138
161
|
inputFile: inputPath
|
|
139
162
|
});
|
|
140
163
|
}
|
|
141
|
-
// 입력 파일 찾기: private 메서드
|
|
142
|
-
async findInputFile(problemDir) {
|
|
143
|
-
const files = await readdir(problemDir);
|
|
144
|
-
const inputFile = files.find((f) => f === "input1.txt") || files.find((f) => f === "input.txt");
|
|
145
|
-
if (!inputFile) {
|
|
146
|
-
throw new Error("input.txt \uB610\uB294 input1.txt \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
147
|
-
}
|
|
148
|
-
return join(problemDir, inputFile);
|
|
149
|
-
}
|
|
150
164
|
};
|
|
151
165
|
RunCommand = __decorateClass([
|
|
152
166
|
CommandDef({
|
|
@@ -154,7 +168,8 @@ RunCommand = __decorateClass([
|
|
|
154
168
|
description: `\uCF54\uB4DC\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4 (\uD14C\uC2A4\uD2B8 \uC5C6\uC774).
|
|
155
169
|
- \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uCF54\uB4DC \uC2E4\uD589
|
|
156
170
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
157
|
-
- 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
|
|
158
173
|
- \uD14C\uC2A4\uD2B8 \uCF00\uC774\uC2A4 \uAC80\uC99D \uC5C6\uC774 \uB2E8\uC21C \uC2E4\uD589`,
|
|
159
174
|
flags: [
|
|
160
175
|
{
|
|
@@ -169,17 +184,18 @@ RunCommand = __decorateClass([
|
|
|
169
184
|
name: "input",
|
|
170
185
|
options: {
|
|
171
186
|
shortFlag: "i",
|
|
172
|
-
description: "\uC785\uB825 \uD30C\uC77C \uC9C0\uC815 (\
|
|
187
|
+
description: "\uC785\uB825 \uD30C\uC77C \uC9C0\uC815 (\uC608: 1 \uB610\uB294 testcases/1/input.txt)"
|
|
173
188
|
}
|
|
174
189
|
}
|
|
175
190
|
],
|
|
176
191
|
autoDetectProblemId: true,
|
|
177
192
|
autoDetectLanguage: true,
|
|
178
193
|
examples: [
|
|
179
|
-
"run
|
|
180
|
-
"run 1000
|
|
181
|
-
"run --language python
|
|
182
|
-
"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"
|
|
183
199
|
]
|
|
184
200
|
})
|
|
185
201
|
], RunCommand);
|
package/dist/commands/search.js
CHANGED
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
Command,
|
|
17
17
|
CommandBuilder,
|
|
18
18
|
CommandDef,
|
|
19
|
-
|
|
19
|
+
getArchiveDirPath,
|
|
20
20
|
getTierColor,
|
|
21
21
|
getTierName
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
23
23
|
import {
|
|
24
24
|
__decorateClass
|
|
25
25
|
} from "../chunk-7MQMPJ3X.js";
|
|
@@ -270,7 +270,7 @@ function WorkbookSearchView({
|
|
|
270
270
|
] });
|
|
271
271
|
}
|
|
272
272
|
const problemsWithSolvedStatus = problems.map((problem) => {
|
|
273
|
-
const problemDirPath =
|
|
273
|
+
const problemDirPath = getArchiveDirPath(problem.problemId);
|
|
274
274
|
const isSolved = existsSync(problemDirPath);
|
|
275
275
|
return {
|
|
276
276
|
problemId: problem.problemId,
|
|
@@ -362,7 +362,7 @@ function SearchView({ query, onComplete }) {
|
|
|
362
362
|
const searchResults = await searchProblems(query, currentPage);
|
|
363
363
|
const resultsWithSolvedStatus = searchResults.problems.map(
|
|
364
364
|
(problem) => {
|
|
365
|
-
const problemDirPath =
|
|
365
|
+
const problemDirPath = getArchiveDirPath(problem.problemId);
|
|
366
366
|
const isSolved = existsSync(problemDirPath);
|
|
367
367
|
return {
|
|
368
368
|
...problem,
|
package/dist/commands/stats.js
CHANGED
package/dist/commands/submit.js
CHANGED
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
CommandDef,
|
|
9
9
|
detectProblemIdFromPath,
|
|
10
10
|
findSolutionFile,
|
|
11
|
-
getProblemId,
|
|
12
11
|
resolveLanguage,
|
|
13
12
|
resolveProblemContext
|
|
14
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
15
14
|
import {
|
|
16
15
|
__decorateClass,
|
|
17
16
|
getSupportedLanguagesString
|
|
@@ -195,19 +194,15 @@ function SubmitView({
|
|
|
195
194
|
}
|
|
196
195
|
var SubmitCommand = class extends Command {
|
|
197
196
|
async execute(args, flags) {
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
problemId !== null ? [problemId.toString()] : [],
|
|
201
|
-
{ requireId: true }
|
|
202
|
-
);
|
|
203
|
-
const sourcePath = await findSolutionFile(context.problemDir);
|
|
197
|
+
const context = await resolveProblemContext(args, { requireId: true });
|
|
198
|
+
const sourcePath = await findSolutionFile(context.archiveDir);
|
|
204
199
|
const detectedLanguage = await resolveLanguage(
|
|
205
|
-
context.
|
|
200
|
+
context.archiveDir,
|
|
206
201
|
flags.language
|
|
207
202
|
);
|
|
208
203
|
let finalProblemId = context.problemId;
|
|
209
204
|
if (finalProblemId === null) {
|
|
210
|
-
finalProblemId = detectProblemIdFromPath(context.
|
|
205
|
+
finalProblemId = detectProblemIdFromPath(context.archiveDir);
|
|
211
206
|
}
|
|
212
207
|
if (finalProblemId === null) {
|
|
213
208
|
throw new Error(
|
package/dist/commands/test.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
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,
|
|
8
8
|
CommandDef,
|
|
9
|
-
getProblemId,
|
|
10
9
|
resolveLanguage,
|
|
11
10
|
resolveProblemContext
|
|
12
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
13
12
|
import {
|
|
14
13
|
__decorateClass,
|
|
15
14
|
getSupportedLanguagesString
|
|
@@ -123,8 +122,14 @@ async function runAllTests({
|
|
|
123
122
|
language,
|
|
124
123
|
timeoutMs
|
|
125
124
|
}) {
|
|
126
|
-
const
|
|
127
|
-
|
|
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
|
+
}
|
|
128
133
|
const results = [];
|
|
129
134
|
let effectiveTimeout = timeoutMs;
|
|
130
135
|
if (effectiveTimeout == null) {
|
|
@@ -148,11 +153,10 @@ async function runAllTests({
|
|
|
148
153
|
if (effectiveTimeout == null) {
|
|
149
154
|
effectiveTimeout = 5e3;
|
|
150
155
|
}
|
|
151
|
-
for (const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const
|
|
155
|
-
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");
|
|
156
160
|
let expected;
|
|
157
161
|
try {
|
|
158
162
|
expected = await readFile(outputPath, "utf-8");
|
|
@@ -161,7 +165,7 @@ async function runAllTests({
|
|
|
161
165
|
caseId,
|
|
162
166
|
inputPath,
|
|
163
167
|
status: "error",
|
|
164
|
-
error: "\uAE30\uB300 \uCD9C\uB825(output
|
|
168
|
+
error: "\uAE30\uB300 \uCD9C\uB825(output.txt)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
165
169
|
});
|
|
166
170
|
continue;
|
|
167
171
|
}
|
|
@@ -247,8 +251,7 @@ function useTestRunner({
|
|
|
247
251
|
const watcher = chokidar.watch(
|
|
248
252
|
[
|
|
249
253
|
join2(problemDir, "solution.*"),
|
|
250
|
-
join2(problemDir, "
|
|
251
|
-
join2(problemDir, "output*.txt")
|
|
254
|
+
join2(problemDir, "testcases", "**", "*.txt")
|
|
252
255
|
],
|
|
253
256
|
{
|
|
254
257
|
ignoreInitial: true
|
|
@@ -317,16 +320,13 @@ function TestView({
|
|
|
317
320
|
}
|
|
318
321
|
var TestCommand = class extends Command {
|
|
319
322
|
async execute(args, flags) {
|
|
320
|
-
const
|
|
321
|
-
const context = await resolveProblemContext(
|
|
322
|
-
problemId !== null && problemId !== void 0 ? [problemId.toString()] : []
|
|
323
|
-
);
|
|
323
|
+
const context = await resolveProblemContext(args);
|
|
324
324
|
const language = await resolveLanguage(
|
|
325
|
-
context.
|
|
325
|
+
context.archiveDir,
|
|
326
326
|
flags.language
|
|
327
327
|
);
|
|
328
328
|
await this.renderView(TestView, {
|
|
329
|
-
problemDir: context.
|
|
329
|
+
problemDir: context.archiveDir,
|
|
330
330
|
language,
|
|
331
331
|
watch: Boolean(flags.watch),
|
|
332
332
|
timeoutMs: flags.timeoutMs
|
|
@@ -339,7 +339,7 @@ TestCommand = __decorateClass([
|
|
|
339
339
|
description: `\uC608\uC81C \uC785\uCD9C\uB825 \uAE30\uBC18\uC73C\uB85C \uB85C\uCEEC \uD14C\uC2A4\uD2B8\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.
|
|
340
340
|
- \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uD14C\uC2A4\uD2B8 \uC2E4\uD589
|
|
341
341
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
342
|
-
- input
|
|
342
|
+
- testcases/{\uBC88\uD638}/input.txt\uC640 testcases/{\uBC88\uD638}/output.txt \uD30C\uC77C\uC744 \uAE30\uBC18\uC73C\uB85C \uD14C\uC2A4\uD2B8
|
|
343
343
|
- \uBB38\uC81C\uC758 \uC2DC\uAC04 \uC81C\uD55C\uC744 \uC790\uB3D9\uC73C\uB85C \uC801\uC6A9
|
|
344
344
|
- --watch \uC635\uC158\uC73C\uB85C \uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8`,
|
|
345
345
|
flags: [
|
|
@@ -356,7 +356,7 @@ TestCommand = __decorateClass([
|
|
|
356
356
|
options: {
|
|
357
357
|
shortFlag: "w",
|
|
358
358
|
description: `watch \uBAA8\uB4DC (\uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8)
|
|
359
|
-
solution.*,
|
|
359
|
+
solution.*, testcases/**/*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0`
|
|
360
360
|
}
|
|
361
361
|
}
|
|
362
362
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhseung/ps-cli",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5",
|
|
4
4
|
"description": "백준(BOJ) 문제 해결을 위한 통합 CLI 도구",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"build": "tsup && node scripts/add-shebang.js",
|
|
16
16
|
"prepublishOnly": "npm run build",
|
|
17
17
|
"dev": "tsup --watch",
|
|
18
|
+
"ps": "node dist/index.js",
|
|
18
19
|
"typecheck": "tsc --noEmit",
|
|
19
20
|
"lint": "eslint",
|
|
20
21
|
"format": "prettier --check .",
|