@rhseung/ps-cli 1.7.4 → 1.8.0
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 +29 -24
- package/dist/{chunk-GCOFFYJ3.js → chunk-3LR2NGRC.js} +12 -4
- package/dist/{chunk-F4LZ6ENP.js → chunk-JPDN34C7.js} +67 -3
- package/dist/chunk-PY6GW22W.js +13 -0
- package/dist/{chunk-A6STXEAE.js → chunk-QB2R47PW.js} +8 -1
- package/dist/{chunk-OJZLQ6FK.js → chunk-VIHXBCOZ.js} +30 -4
- package/dist/commands/archive.js +25 -14
- package/dist/commands/config.js +56 -2
- package/dist/commands/fetch.js +19 -14
- package/dist/commands/init.js +1 -1
- package/dist/commands/open.js +56 -12
- package/dist/commands/run.js +57 -37
- package/dist/commands/search.js +51 -19
- package/dist/commands/stats.js +119 -37
- package/dist/commands/submit.js +13 -11
- package/dist/commands/test.js +35 -31
- package/dist/index.js +77 -2
- package/package.json +1 -1
package/dist/commands/stats.js
CHANGED
|
@@ -3,18 +3,26 @@ import {
|
|
|
3
3
|
source_default
|
|
4
4
|
} from "../chunk-ASMT3CRD.js";
|
|
5
5
|
import {
|
|
6
|
-
getUserStats
|
|
7
|
-
|
|
6
|
+
getUserStats,
|
|
7
|
+
getUserTop100
|
|
8
|
+
} from "../chunk-QB2R47PW.js";
|
|
9
|
+
import {
|
|
10
|
+
defineFlags
|
|
11
|
+
} from "../chunk-PY6GW22W.js";
|
|
8
12
|
import {
|
|
9
13
|
Command,
|
|
10
14
|
CommandBuilder,
|
|
11
15
|
CommandDef,
|
|
12
16
|
calculateTierProgress,
|
|
17
|
+
findProjectRoot,
|
|
18
|
+
getArchiveDir,
|
|
13
19
|
getNextTierMinRating,
|
|
14
20
|
getSolvedAcHandle,
|
|
21
|
+
getSolvingDir,
|
|
15
22
|
getTierColor,
|
|
16
|
-
getTierName
|
|
17
|
-
|
|
23
|
+
getTierName,
|
|
24
|
+
getTierShortName
|
|
25
|
+
} from "../chunk-JPDN34C7.js";
|
|
18
26
|
import {
|
|
19
27
|
__decorateClass
|
|
20
28
|
} from "../chunk-7MQMPJ3X.js";
|
|
@@ -25,40 +33,98 @@ import { Spinner } from "@inkjs/ui";
|
|
|
25
33
|
import { Box, Text, Transform } from "ink";
|
|
26
34
|
|
|
27
35
|
// src/hooks/use-user-stats.ts
|
|
36
|
+
import { existsSync } from "fs";
|
|
37
|
+
import { readdir, stat } from "fs/promises";
|
|
38
|
+
import { join } from "path";
|
|
28
39
|
import { useEffect, useState } from "react";
|
|
40
|
+
async function countProblems(dir) {
|
|
41
|
+
let count = 0;
|
|
42
|
+
try {
|
|
43
|
+
if (!existsSync(dir)) return 0;
|
|
44
|
+
const entries = await readdir(dir);
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (entry.startsWith(".")) continue;
|
|
47
|
+
const fullPath = join(dir, entry);
|
|
48
|
+
const s = await stat(fullPath);
|
|
49
|
+
if (s.isDirectory()) {
|
|
50
|
+
if (existsSync(join(fullPath, "meta.json"))) {
|
|
51
|
+
count++;
|
|
52
|
+
} else {
|
|
53
|
+
count += await countProblems(fullPath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
return count;
|
|
60
|
+
}
|
|
29
61
|
function useUserStats({
|
|
30
62
|
handle,
|
|
31
|
-
onComplete
|
|
63
|
+
onComplete,
|
|
64
|
+
fetchLocalCount = false
|
|
32
65
|
}) {
|
|
33
66
|
const [status, setStatus] = useState(
|
|
34
67
|
"loading"
|
|
35
68
|
);
|
|
36
69
|
const [user, setUser] = useState(null);
|
|
70
|
+
const [top100, setTop100] = useState(null);
|
|
71
|
+
const [localSolvedCount, setLocalSolvedCount] = useState(null);
|
|
37
72
|
const [error, setError] = useState(null);
|
|
38
73
|
useEffect(() => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
74
|
+
async function fetchData() {
|
|
75
|
+
try {
|
|
76
|
+
const [userData, top100Data] = await Promise.all([
|
|
77
|
+
getUserStats(handle),
|
|
78
|
+
getUserTop100(handle)
|
|
79
|
+
]);
|
|
80
|
+
setUser(userData);
|
|
81
|
+
setTop100(top100Data);
|
|
82
|
+
if (fetchLocalCount) {
|
|
83
|
+
const projectRoot = findProjectRoot();
|
|
84
|
+
if (projectRoot) {
|
|
85
|
+
const archiveDir = getArchiveDir();
|
|
86
|
+
const solvingDir = getSolvingDir();
|
|
87
|
+
const archivePath = join(projectRoot, archiveDir);
|
|
88
|
+
const solvingPath = join(projectRoot, solvingDir);
|
|
89
|
+
const [archiveCount, solvingCount] = await Promise.all([
|
|
90
|
+
countProblems(archivePath),
|
|
91
|
+
countProblems(solvingPath)
|
|
92
|
+
]);
|
|
93
|
+
setLocalSolvedCount(archiveCount + solvingCount);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
setStatus("success");
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
onComplete();
|
|
99
|
+
}, 5e3);
|
|
100
|
+
} catch (err) {
|
|
101
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
102
|
+
setStatus("error");
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
onComplete();
|
|
105
|
+
}, 3e3);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
void fetchData();
|
|
52
109
|
}, [handle, onComplete]);
|
|
53
110
|
return {
|
|
54
111
|
status,
|
|
55
112
|
user,
|
|
113
|
+
top100,
|
|
114
|
+
localSolvedCount,
|
|
56
115
|
error
|
|
57
116
|
};
|
|
58
117
|
}
|
|
59
118
|
|
|
60
119
|
// src/commands/stats.tsx
|
|
61
120
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
121
|
+
var statsFlagsSchema = {
|
|
122
|
+
handle: {
|
|
123
|
+
type: "string",
|
|
124
|
+
shortFlag: "h",
|
|
125
|
+
description: "Solved.ac \uD578\uB4E4 (\uC124\uC815\uC5D0 \uC800\uC7A5\uB41C \uAC12 \uC0AC\uC6A9 \uAC00\uB2A5)"
|
|
126
|
+
}
|
|
127
|
+
};
|
|
62
128
|
function ProgressBarWithColor({ value, colorFn }) {
|
|
63
129
|
const width = process.stdout.columns || 40;
|
|
64
130
|
const barWidth = Math.max(10, Math.min(30, width - 20));
|
|
@@ -69,10 +135,11 @@ function ProgressBarWithColor({ value, colorFn }) {
|
|
|
69
135
|
const barText = filledBar + emptyBar;
|
|
70
136
|
return /* @__PURE__ */ jsx(Transform, { transform: (output) => colorFn(output), children: /* @__PURE__ */ jsx(Text, { children: barText }) });
|
|
71
137
|
}
|
|
72
|
-
function StatsView({ handle, onComplete }) {
|
|
73
|
-
const { status, user, error } = useUserStats({
|
|
138
|
+
function StatsView({ handle, onComplete, showLocalStats }) {
|
|
139
|
+
const { status, user, top100, localSolvedCount, error } = useUserStats({
|
|
74
140
|
handle,
|
|
75
|
-
onComplete
|
|
141
|
+
onComplete,
|
|
142
|
+
fetchLocalCount: showLocalStats
|
|
76
143
|
});
|
|
77
144
|
if (status === "loading") {
|
|
78
145
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: "\uD1B5\uACC4\uB97C \uBD88\uB7EC\uC624\uB294 \uC911..." }) });
|
|
@@ -90,10 +157,16 @@ function StatsView({ handle, onComplete }) {
|
|
|
90
157
|
const nextTierMin = getNextTierMinRating(user.tier);
|
|
91
158
|
const progress = user.tier === 31 ? 100 : calculateTierProgress(user.rating, user.tier);
|
|
92
159
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
160
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [
|
|
161
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", bold: true, children: [
|
|
162
|
+
"\u2728 ",
|
|
163
|
+
user.handle
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsxs(Text, { color: "blue", underline: true, children: [
|
|
166
|
+
"https://solved.ac/profile/",
|
|
167
|
+
user.handle
|
|
168
|
+
] })
|
|
169
|
+
] }),
|
|
97
170
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, flexDirection: "row", gap: 1, children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
98
171
|
tierColorFn(tierName),
|
|
99
172
|
" ",
|
|
@@ -113,7 +186,12 @@ function StatsView({ handle, onComplete }) {
|
|
|
113
186
|
"\uD574\uACB0\uD55C \uBB38\uC81C:",
|
|
114
187
|
" ",
|
|
115
188
|
/* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: user.solvedCount.toLocaleString() }),
|
|
116
|
-
"\uAC1C"
|
|
189
|
+
"\uAC1C",
|
|
190
|
+
localSolvedCount !== null && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
191
|
+
" (\uB85C\uCEEC: ",
|
|
192
|
+
localSolvedCount,
|
|
193
|
+
"\uAC1C)"
|
|
194
|
+
] })
|
|
117
195
|
] }),
|
|
118
196
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
119
197
|
"\uD074\uB798\uC2A4: ",
|
|
@@ -132,7 +210,17 @@ function StatsView({ handle, onComplete }) {
|
|
|
132
210
|
] })
|
|
133
211
|
] })
|
|
134
212
|
}
|
|
135
|
-
)
|
|
213
|
+
),
|
|
214
|
+
top100 && top100.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
215
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "yellow", children: "\u{1F3C6} \uC0C1\uC704 100\uBB38\uC81C \uD2F0\uC5B4 \uBD84\uD3EC" }) }),
|
|
216
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: Array.from({ length: Math.ceil(top100.length / 10) }).map(
|
|
217
|
+
(_, rowIndex) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: top100.slice(rowIndex * 10, (rowIndex + 1) * 10).map((p, colIndex) => {
|
|
218
|
+
const tierColor2 = getTierColor(p.level);
|
|
219
|
+
const tierColorFn2 = typeof tierColor2 === "string" ? source_default.hex(tierColor2) : tierColor2.multiline;
|
|
220
|
+
return /* @__PURE__ */ jsx(Box, { width: 4, children: /* @__PURE__ */ jsx(Text, { children: tierColorFn2(getTierShortName(p.level)) }) }, colIndex);
|
|
221
|
+
}) }, rowIndex)
|
|
222
|
+
) })
|
|
223
|
+
] })
|
|
136
224
|
] });
|
|
137
225
|
}
|
|
138
226
|
return null;
|
|
@@ -153,8 +241,10 @@ var StatsCommand = class extends Command {
|
|
|
153
241
|
process.exit(1);
|
|
154
242
|
return;
|
|
155
243
|
}
|
|
244
|
+
const showLocalStats = !args[0] && !flags.handle;
|
|
156
245
|
await this.renderView(StatsView, {
|
|
157
|
-
handle
|
|
246
|
+
handle,
|
|
247
|
+
showLocalStats
|
|
158
248
|
});
|
|
159
249
|
}
|
|
160
250
|
};
|
|
@@ -164,15 +254,7 @@ StatsCommand = __decorateClass([
|
|
|
164
254
|
description: `Solved.ac\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uD1B5\uACC4\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.
|
|
165
255
|
- \uD2F0\uC5B4, \uB808\uC774\uD305, \uD574\uACB0\uD55C \uBB38\uC81C \uC218 \uB4F1 \uD45C\uC2DC
|
|
166
256
|
- \uADF8\uB77C\uB370\uC774\uC158\uC73C\uB85C \uC2DC\uAC01\uC801\uC73C\uB85C \uD45C\uC2DC`,
|
|
167
|
-
flags:
|
|
168
|
-
{
|
|
169
|
-
name: "handle",
|
|
170
|
-
options: {
|
|
171
|
-
shortFlag: "h",
|
|
172
|
-
description: "Solved.ac \uD578\uB4E4 (\uC124\uC815\uC5D0 \uC800\uC7A5\uB41C \uAC12 \uC0AC\uC6A9 \uAC00\uB2A5)"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
],
|
|
257
|
+
flags: defineFlags(statsFlagsSchema),
|
|
176
258
|
autoDetectProblemId: false,
|
|
177
259
|
examples: ["stats myhandle", "stats --handle myhandle"]
|
|
178
260
|
})
|
package/dist/commands/submit.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
openBrowser
|
|
4
4
|
} from "../chunk-QGMWUOJ3.js";
|
|
5
|
+
import {
|
|
6
|
+
defineFlags
|
|
7
|
+
} from "../chunk-PY6GW22W.js";
|
|
5
8
|
import {
|
|
6
9
|
Command,
|
|
7
10
|
CommandBuilder,
|
|
@@ -10,7 +13,7 @@ import {
|
|
|
10
13
|
findSolutionFile,
|
|
11
14
|
resolveLanguage,
|
|
12
15
|
resolveProblemContext
|
|
13
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-JPDN34C7.js";
|
|
14
17
|
import {
|
|
15
18
|
__decorateClass,
|
|
16
19
|
getSupportedLanguagesString
|
|
@@ -117,6 +120,14 @@ function useSubmit({
|
|
|
117
120
|
|
|
118
121
|
// src/commands/submit.tsx
|
|
119
122
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
123
|
+
var submitFlagsSchema = {
|
|
124
|
+
language: {
|
|
125
|
+
type: "string",
|
|
126
|
+
shortFlag: "l",
|
|
127
|
+
description: `\uC5B8\uC5B4 \uC120\uD0DD (\uC9C0\uC815 \uC2DC \uC790\uB3D9 \uAC10\uC9C0 \uBB34\uC2DC)
|
|
128
|
+
\uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}`
|
|
129
|
+
}
|
|
130
|
+
};
|
|
120
131
|
function SubmitView({
|
|
121
132
|
problemId,
|
|
122
133
|
language,
|
|
@@ -224,16 +235,7 @@ SubmitCommand = __decorateClass([
|
|
|
224
235
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
225
236
|
- \uC18C\uC2A4 \uCF54\uB4DC\uB97C \uD074\uB9BD\uBCF4\uB4DC\uC5D0 \uC790\uB3D9 \uBCF5\uC0AC
|
|
226
237
|
- \uC81C\uCD9C \uD398\uC774\uC9C0\uB97C \uBE0C\uB77C\uC6B0\uC800\uB85C \uC790\uB3D9 \uC5F4\uAE30`,
|
|
227
|
-
flags:
|
|
228
|
-
{
|
|
229
|
-
name: "language",
|
|
230
|
-
options: {
|
|
231
|
-
shortFlag: "l",
|
|
232
|
-
description: `\uC5B8\uC5B4 \uC120\uD0DD (\uC9C0\uC815 \uC2DC \uC790\uB3D9 \uAC10\uC9C0 \uBB34\uC2DC)
|
|
233
|
-
\uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}`
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
],
|
|
238
|
+
flags: defineFlags(submitFlagsSchema),
|
|
237
239
|
autoDetectProblemId: true,
|
|
238
240
|
autoDetectLanguage: true,
|
|
239
241
|
requireProblemId: true,
|
package/dist/commands/test.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
runSolution
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-VIHXBCOZ.js";
|
|
5
|
+
import {
|
|
6
|
+
defineFlags
|
|
7
|
+
} from "../chunk-PY6GW22W.js";
|
|
5
8
|
import {
|
|
6
9
|
Command,
|
|
7
10
|
CommandBuilder,
|
|
8
11
|
CommandDef,
|
|
9
12
|
resolveLanguage,
|
|
10
13
|
resolveProblemContext
|
|
11
|
-
} from "../chunk-
|
|
14
|
+
} from "../chunk-JPDN34C7.js";
|
|
12
15
|
import {
|
|
13
16
|
__decorateClass,
|
|
14
17
|
getSupportedLanguagesString
|
|
@@ -122,8 +125,14 @@ async function runAllTests({
|
|
|
122
125
|
language,
|
|
123
126
|
timeoutMs
|
|
124
127
|
}) {
|
|
125
|
-
const
|
|
126
|
-
|
|
128
|
+
const testcasesDir = join(problemDir, "testcases");
|
|
129
|
+
let caseDirs = [];
|
|
130
|
+
try {
|
|
131
|
+
const entries = await readdir(testcasesDir);
|
|
132
|
+
caseDirs = entries.filter((entry) => /^\d+$/.test(entry)).sort((a, b) => Number(a) - Number(b)).map((entry) => join(testcasesDir, entry));
|
|
133
|
+
} catch {
|
|
134
|
+
return { results: [], summary: buildSummary([]) };
|
|
135
|
+
}
|
|
127
136
|
const results = [];
|
|
128
137
|
let effectiveTimeout = timeoutMs;
|
|
129
138
|
if (effectiveTimeout == null) {
|
|
@@ -147,11 +156,10 @@ async function runAllTests({
|
|
|
147
156
|
if (effectiveTimeout == null) {
|
|
148
157
|
effectiveTimeout = 5e3;
|
|
149
158
|
}
|
|
150
|
-
for (const
|
|
151
|
-
const
|
|
152
|
-
const
|
|
153
|
-
const
|
|
154
|
-
const outputPath = join(problemDir, `output${caseId}.txt`);
|
|
159
|
+
for (const caseDir of caseDirs) {
|
|
160
|
+
const caseId = Number(join(caseDir).split("/").pop() || "0");
|
|
161
|
+
const inputPath = join(caseDir, "input.txt");
|
|
162
|
+
const outputPath = join(caseDir, "output.txt");
|
|
155
163
|
let expected;
|
|
156
164
|
try {
|
|
157
165
|
expected = await readFile(outputPath, "utf-8");
|
|
@@ -160,7 +168,7 @@ async function runAllTests({
|
|
|
160
168
|
caseId,
|
|
161
169
|
inputPath,
|
|
162
170
|
status: "error",
|
|
163
|
-
error: "\uAE30\uB300 \uCD9C\uB825(output
|
|
171
|
+
error: "\uAE30\uB300 \uCD9C\uB825(output.txt)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
|
164
172
|
});
|
|
165
173
|
continue;
|
|
166
174
|
}
|
|
@@ -246,8 +254,7 @@ function useTestRunner({
|
|
|
246
254
|
const watcher = chokidar.watch(
|
|
247
255
|
[
|
|
248
256
|
join2(problemDir, "solution.*"),
|
|
249
|
-
join2(problemDir, "
|
|
250
|
-
join2(problemDir, "output*.txt")
|
|
257
|
+
join2(problemDir, "testcases", "**", "*.txt")
|
|
251
258
|
],
|
|
252
259
|
{
|
|
253
260
|
ignoreInitial: true
|
|
@@ -277,6 +284,20 @@ function useTestRunner({
|
|
|
277
284
|
|
|
278
285
|
// src/commands/test.tsx
|
|
279
286
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
287
|
+
var testFlagsSchema = {
|
|
288
|
+
language: {
|
|
289
|
+
type: "string",
|
|
290
|
+
shortFlag: "l",
|
|
291
|
+
description: `\uC5B8\uC5B4 \uC120\uD0DD (\uC9C0\uC815 \uC2DC \uC790\uB3D9 \uAC10\uC9C0 \uBB34\uC2DC)
|
|
292
|
+
\uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}`
|
|
293
|
+
},
|
|
294
|
+
watch: {
|
|
295
|
+
type: "boolean",
|
|
296
|
+
shortFlag: "w",
|
|
297
|
+
description: `watch \uBAA8\uB4DC (\uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8)
|
|
298
|
+
solution.*, testcases/**/*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0`
|
|
299
|
+
}
|
|
300
|
+
};
|
|
280
301
|
function TestView({
|
|
281
302
|
problemDir,
|
|
282
303
|
language,
|
|
@@ -335,27 +356,10 @@ TestCommand = __decorateClass([
|
|
|
335
356
|
description: `\uC608\uC81C \uC785\uCD9C\uB825 \uAE30\uBC18\uC73C\uB85C \uB85C\uCEEC \uD14C\uC2A4\uD2B8\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.
|
|
336
357
|
- \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uD14C\uC2A4\uD2B8 \uC2E4\uD589
|
|
337
358
|
- solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
|
|
338
|
-
- input
|
|
359
|
+
- testcases/{\uBC88\uD638}/input.txt\uC640 testcases/{\uBC88\uD638}/output.txt \uD30C\uC77C\uC744 \uAE30\uBC18\uC73C\uB85C \uD14C\uC2A4\uD2B8
|
|
339
360
|
- \uBB38\uC81C\uC758 \uC2DC\uAC04 \uC81C\uD55C\uC744 \uC790\uB3D9\uC73C\uB85C \uC801\uC6A9
|
|
340
361
|
- --watch \uC635\uC158\uC73C\uB85C \uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8`,
|
|
341
|
-
flags:
|
|
342
|
-
{
|
|
343
|
-
name: "language",
|
|
344
|
-
options: {
|
|
345
|
-
shortFlag: "l",
|
|
346
|
-
description: `\uC5B8\uC5B4 \uC120\uD0DD (\uC9C0\uC815 \uC2DC \uC790\uB3D9 \uAC10\uC9C0 \uBB34\uC2DC)
|
|
347
|
-
\uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}`
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
name: "watch",
|
|
352
|
-
options: {
|
|
353
|
-
shortFlag: "w",
|
|
354
|
-
description: `watch \uBAA8\uB4DC (\uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8)
|
|
355
|
-
solution.*, input*.txt, output*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0`
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
],
|
|
362
|
+
flags: defineFlags(testFlagsSchema),
|
|
359
363
|
autoDetectProblemId: true,
|
|
360
364
|
autoDetectLanguage: true,
|
|
361
365
|
examples: [
|
package/dist/index.js
CHANGED
|
@@ -9471,7 +9471,8 @@ async function main() {
|
|
|
9471
9471
|
if (!commands) {
|
|
9472
9472
|
commands = await loadCommands();
|
|
9473
9473
|
}
|
|
9474
|
-
const [command, ...
|
|
9474
|
+
const [command, ...initialArgs] = cli.input;
|
|
9475
|
+
let rawArgs = initialArgs;
|
|
9475
9476
|
if (command === "help" || !command && cli.flags.help) {
|
|
9476
9477
|
const helpText = generateHelpText(commands);
|
|
9477
9478
|
console.log(helpText.trim());
|
|
@@ -9493,6 +9494,80 @@ async function main() {
|
|
|
9493
9494
|
process.exit(1);
|
|
9494
9495
|
return;
|
|
9495
9496
|
}
|
|
9497
|
+
let finalFlags = cli.flags;
|
|
9498
|
+
const commandIndex = process.argv.findIndex((arg) => arg === command);
|
|
9499
|
+
const commandArgs = commandIndex >= 0 ? process.argv.slice(commandIndex + 1) : process.argv.slice(2);
|
|
9500
|
+
if (commandDef.metadata?.flags) {
|
|
9501
|
+
const commandFlags = {};
|
|
9502
|
+
for (const flagDef of commandDef.metadata.flags) {
|
|
9503
|
+
const flagConfig = {
|
|
9504
|
+
type: flagDef.options?.type || "string"
|
|
9505
|
+
};
|
|
9506
|
+
if (flagDef.options?.shortFlag) {
|
|
9507
|
+
flagConfig.shortFlag = flagDef.options.shortFlag;
|
|
9508
|
+
}
|
|
9509
|
+
if (flagDef.options?.default !== void 0) {
|
|
9510
|
+
flagConfig.default = flagDef.options.default;
|
|
9511
|
+
}
|
|
9512
|
+
commandFlags[flagDef.name] = flagConfig;
|
|
9513
|
+
}
|
|
9514
|
+
const commandCli = meow("", {
|
|
9515
|
+
importMeta: import.meta,
|
|
9516
|
+
argv: commandArgs,
|
|
9517
|
+
autoHelp: false,
|
|
9518
|
+
// 기본 help 출력 비활성화 (우리가 직접 처리)
|
|
9519
|
+
flags: {
|
|
9520
|
+
help: {
|
|
9521
|
+
type: "boolean",
|
|
9522
|
+
shortFlag: "h",
|
|
9523
|
+
default: false
|
|
9524
|
+
},
|
|
9525
|
+
...commandFlags
|
|
9526
|
+
}
|
|
9527
|
+
});
|
|
9528
|
+
if (commandCli.flags.help) {
|
|
9529
|
+
if (commandDef.help && commandDef.help.trim()) {
|
|
9530
|
+
console.log(commandDef.help.trim());
|
|
9531
|
+
} else {
|
|
9532
|
+
console.log(`\uBA85\uB839\uC5B4: ${commandDef.name}`);
|
|
9533
|
+
if (commandDef.metadata?.description) {
|
|
9534
|
+
console.log(`\uC124\uBA85: ${commandDef.metadata.description}`);
|
|
9535
|
+
}
|
|
9536
|
+
}
|
|
9537
|
+
process.exit(0);
|
|
9538
|
+
return;
|
|
9539
|
+
}
|
|
9540
|
+
rawArgs = commandCli.input;
|
|
9541
|
+
finalFlags = { ...cli.flags, ...commandCli.flags };
|
|
9542
|
+
} else {
|
|
9543
|
+
const commandCli = meow("", {
|
|
9544
|
+
importMeta: import.meta,
|
|
9545
|
+
argv: commandArgs,
|
|
9546
|
+
autoHelp: false,
|
|
9547
|
+
// 기본 help 출력 비활성화 (우리가 직접 처리)
|
|
9548
|
+
flags: {
|
|
9549
|
+
help: {
|
|
9550
|
+
type: "boolean",
|
|
9551
|
+
shortFlag: "h",
|
|
9552
|
+
default: false
|
|
9553
|
+
}
|
|
9554
|
+
}
|
|
9555
|
+
});
|
|
9556
|
+
if (commandCli.flags.help) {
|
|
9557
|
+
if (commandDef.help && commandDef.help.trim()) {
|
|
9558
|
+
console.log(commandDef.help.trim());
|
|
9559
|
+
} else {
|
|
9560
|
+
console.log(`\uBA85\uB839\uC5B4: ${commandDef.name}`);
|
|
9561
|
+
if (commandDef.metadata?.description) {
|
|
9562
|
+
console.log(`\uC124\uBA85: ${commandDef.metadata.description}`);
|
|
9563
|
+
}
|
|
9564
|
+
}
|
|
9565
|
+
process.exit(0);
|
|
9566
|
+
return;
|
|
9567
|
+
}
|
|
9568
|
+
rawArgs = commandCli.input;
|
|
9569
|
+
finalFlags = { ...cli.flags, ...commandCli.flags };
|
|
9570
|
+
}
|
|
9496
9571
|
if (command !== "init") {
|
|
9497
9572
|
let currentDir = process.cwd();
|
|
9498
9573
|
let found = false;
|
|
@@ -9517,7 +9592,7 @@ async function main() {
|
|
|
9517
9592
|
return;
|
|
9518
9593
|
}
|
|
9519
9594
|
}
|
|
9520
|
-
await commandDef.execute(
|
|
9595
|
+
await commandDef.execute(rawArgs, finalFlags);
|
|
9521
9596
|
}
|
|
9522
9597
|
main().catch((error) => {
|
|
9523
9598
|
console.error("\uC624\uB958:", error.message);
|