@rhseung/ps-cli 1.5.0 → 1.7.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/dist/{chunk-HDNNR5OY.js → chunk-ASMT3CRD.js} +1 -202
- package/dist/{chunk-7SVCS23X.js → chunk-TNGUME4H.js} +376 -27
- package/dist/commands/config.js +32 -2
- package/dist/commands/fetch.js +13 -15
- package/dist/commands/init.js +247 -100
- package/dist/commands/open.js +1 -1
- package/dist/commands/run.js +1 -1
- package/dist/commands/search.js +367 -103
- package/dist/commands/solve.js +201 -0
- package/dist/commands/stats.js +9 -9
- package/dist/commands/submit.js +1 -1
- package/dist/commands/test.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
Command,
|
|
4
|
+
CommandBuilder,
|
|
5
|
+
CommandDef,
|
|
6
|
+
findProjectRoot,
|
|
7
|
+
getProblemDirPath,
|
|
8
|
+
getProblemId,
|
|
9
|
+
getSolvingDir,
|
|
10
|
+
getSolvingDirPath
|
|
11
|
+
} from "../chunk-TNGUME4H.js";
|
|
12
|
+
import {
|
|
13
|
+
__decorateClass
|
|
14
|
+
} from "../chunk-7MQMPJ3X.js";
|
|
15
|
+
|
|
16
|
+
// src/commands/solve.tsx
|
|
17
|
+
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
18
|
+
import { Spinner } from "@inkjs/ui";
|
|
19
|
+
import { Box } from "ink";
|
|
20
|
+
|
|
21
|
+
// src/hooks/use-solve.ts
|
|
22
|
+
import { access, readFile, rename, mkdir, readdir, rmdir } from "fs/promises";
|
|
23
|
+
import { join, dirname } from "path";
|
|
24
|
+
import { execa } from "execa";
|
|
25
|
+
import { useEffect, useState } from "react";
|
|
26
|
+
function useSolve({
|
|
27
|
+
problemId,
|
|
28
|
+
onComplete
|
|
29
|
+
}) {
|
|
30
|
+
const [status, setStatus] = useState(
|
|
31
|
+
"loading"
|
|
32
|
+
);
|
|
33
|
+
const [message, setMessage] = useState("\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uC911...");
|
|
34
|
+
const [error, setError] = useState(null);
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
async function solve() {
|
|
37
|
+
try {
|
|
38
|
+
const projectRoot = findProjectRoot();
|
|
39
|
+
if (!projectRoot) {
|
|
40
|
+
throw new Error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
41
|
+
}
|
|
42
|
+
const solvingDir = getSolvingDirPath(problemId, projectRoot);
|
|
43
|
+
setMessage("solving \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C\uB97C \uD655\uC778\uD558\uB294 \uC911...");
|
|
44
|
+
try {
|
|
45
|
+
await access(solvingDir);
|
|
46
|
+
} catch {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`solving \uB514\uB809\uD1A0\uB9AC\uC5D0 \uBB38\uC81C ${problemId}\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
setMessage("\uBB38\uC81C \uC815\uBCF4\uB97C \uC77D\uB294 \uC911...");
|
|
52
|
+
const metaPath = join(solvingDir, "meta.json");
|
|
53
|
+
let problemTitle = `\uBB38\uC81C ${problemId}`;
|
|
54
|
+
let problem;
|
|
55
|
+
try {
|
|
56
|
+
const metaContent = await readFile(metaPath, "utf-8");
|
|
57
|
+
const meta = JSON.parse(metaContent);
|
|
58
|
+
if (meta.title) {
|
|
59
|
+
problemTitle = meta.title;
|
|
60
|
+
}
|
|
61
|
+
if (meta.id && meta.level !== void 0) {
|
|
62
|
+
problem = {
|
|
63
|
+
id: meta.id,
|
|
64
|
+
title: meta.title || `\uBB38\uC81C ${meta.id}`,
|
|
65
|
+
level: meta.level,
|
|
66
|
+
tier: "",
|
|
67
|
+
// tier는 level에서 계산되므로 빈 문자열로 충분
|
|
68
|
+
tags: meta.tags || [],
|
|
69
|
+
testCases: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
const problemDir = getProblemDirPath(problemId, projectRoot, problem);
|
|
75
|
+
try {
|
|
76
|
+
await access(problemDir);
|
|
77
|
+
throw new Error(
|
|
78
|
+
`problem \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC774\uBBF8 \uBB38\uC81C ${problemId}\uAC00 \uC874\uC7AC\uD569\uB2C8\uB2E4.`
|
|
79
|
+
);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (err instanceof Error && err.message.includes("\uC774\uBBF8")) {
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const problemDirParent = dirname(problemDir);
|
|
86
|
+
setMessage("\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC\uB97C \uC900\uBE44\uD558\uB294 \uC911...");
|
|
87
|
+
await mkdir(problemDirParent, { recursive: true });
|
|
88
|
+
setMessage("\uBB38\uC81C\uB97C problem \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9\uD558\uB294 \uC911...");
|
|
89
|
+
await rename(solvingDir, problemDir);
|
|
90
|
+
setMessage("\uBE48 \uB514\uB809\uD1A0\uB9AC \uC815\uB9AC \uC911...");
|
|
91
|
+
try {
|
|
92
|
+
const solvingDirConfig = getSolvingDir();
|
|
93
|
+
if (solvingDirConfig && solvingDirConfig !== "." && solvingDirConfig !== "") {
|
|
94
|
+
let currentParentDir = dirname(solvingDir);
|
|
95
|
+
const solvingBaseDir = join(projectRoot, solvingDirConfig);
|
|
96
|
+
while (currentParentDir !== solvingBaseDir && currentParentDir !== projectRoot) {
|
|
97
|
+
try {
|
|
98
|
+
const entries = await readdir(currentParentDir);
|
|
99
|
+
if (entries.length === 0) {
|
|
100
|
+
await rmdir(currentParentDir);
|
|
101
|
+
currentParentDir = dirname(currentParentDir);
|
|
102
|
+
} else {
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
} catch {
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
}
|
|
112
|
+
setMessage("Git \uCEE4\uBC0B\uC744 \uC2E4\uD589\uD558\uB294 \uC911...");
|
|
113
|
+
try {
|
|
114
|
+
await execa("git", ["add", problemDir], { cwd: projectRoot });
|
|
115
|
+
const commitMessage = `solve: ${problemId} - ${problemTitle}`;
|
|
116
|
+
await execa("git", ["commit", "-m", commitMessage], {
|
|
117
|
+
cwd: projectRoot
|
|
118
|
+
});
|
|
119
|
+
} catch (gitError) {
|
|
120
|
+
console.warn(
|
|
121
|
+
"Git \uCEE4\uBC0B \uC2E4\uD328:",
|
|
122
|
+
gitError instanceof Error ? gitError.message : String(gitError)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
setStatus("success");
|
|
126
|
+
setMessage(`\uBB38\uC81C ${problemId}\uB97C \uC544\uCE74\uC774\uBE0C\uD588\uC2B5\uB2C8\uB2E4: ${problemDir}`);
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
onComplete?.();
|
|
129
|
+
}, 2e3);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
setStatus("error");
|
|
132
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
133
|
+
setTimeout(() => {
|
|
134
|
+
onComplete?.();
|
|
135
|
+
}, 2e3);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
void solve();
|
|
139
|
+
}, [problemId, onComplete]);
|
|
140
|
+
return {
|
|
141
|
+
status,
|
|
142
|
+
message,
|
|
143
|
+
error
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/commands/solve.tsx
|
|
148
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
149
|
+
function SolveView({ problemId, onComplete }) {
|
|
150
|
+
const { status, message, error } = useSolve({
|
|
151
|
+
problemId,
|
|
152
|
+
onComplete
|
|
153
|
+
});
|
|
154
|
+
if (status === "loading") {
|
|
155
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: message }) });
|
|
156
|
+
}
|
|
157
|
+
if (status === "error") {
|
|
158
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsxs(Alert, { variant: "error", children: [
|
|
159
|
+
"\uC624\uB958 \uBC1C\uC0DD: ",
|
|
160
|
+
error
|
|
161
|
+
] }) });
|
|
162
|
+
}
|
|
163
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: message }) });
|
|
164
|
+
}
|
|
165
|
+
var SolveCommand = class extends Command {
|
|
166
|
+
async execute(args, _) {
|
|
167
|
+
const problemId = getProblemId(args);
|
|
168
|
+
if (problemId === null) {
|
|
169
|
+
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
170
|
+
console.error(`\uC0AC\uC6A9\uBC95: ps solve <\uBB38\uC81C\uBC88\uD638>`);
|
|
171
|
+
console.error(`\uB3C4\uC6C0\uB9D0: ps solve --help`);
|
|
172
|
+
console.error(
|
|
173
|
+
`\uD78C\uD2B8: solving/{\uBB38\uC81C\uBC88\uD638} \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uBB38\uC81C \uBC88\uD638\uB97C \uCD94\uB860\uD569\uB2C8\uB2E4.`
|
|
174
|
+
);
|
|
175
|
+
process.exit(1);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
await this.renderView(SolveView, {
|
|
179
|
+
problemId
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
SolveCommand = __decorateClass([
|
|
184
|
+
CommandDef({
|
|
185
|
+
name: "solve",
|
|
186
|
+
description: `\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD558\uACE0 Git \uCEE4\uBC0B\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.
|
|
187
|
+
- solving \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C\uB97C \uCC3E\uC544 problem \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9
|
|
188
|
+
- Git add \uBC0F commit \uC2E4\uD589 (\uCEE4\uBC0B \uBA54\uC2DC\uC9C0: "solve: {\uBB38\uC81C\uBC88\uD638} - {\uBB38\uC81C\uC774\uB984}")`,
|
|
189
|
+
autoDetectProblemId: true,
|
|
190
|
+
requireProblemId: false,
|
|
191
|
+
examples: [
|
|
192
|
+
"solve 1000",
|
|
193
|
+
"solve # \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C \uBC88\uD638 \uC790\uB3D9 \uAC10\uC9C0"
|
|
194
|
+
]
|
|
195
|
+
})
|
|
196
|
+
], SolveCommand);
|
|
197
|
+
var solve_default = CommandBuilder.fromClass(SolveCommand);
|
|
198
|
+
export {
|
|
199
|
+
SolveCommand,
|
|
200
|
+
solve_default as default
|
|
201
|
+
};
|
package/dist/commands/stats.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
source_default
|
|
4
|
+
} from "../chunk-ASMT3CRD.js";
|
|
2
5
|
import {
|
|
3
6
|
getUserStats
|
|
4
7
|
} from "../chunk-A6STXEAE.js";
|
|
5
|
-
import {
|
|
6
|
-
calculateTierProgress,
|
|
7
|
-
getNextTierMinRating,
|
|
8
|
-
getTierColor,
|
|
9
|
-
getTierName,
|
|
10
|
-
source_default
|
|
11
|
-
} from "../chunk-HDNNR5OY.js";
|
|
12
8
|
import {
|
|
13
9
|
Command,
|
|
14
10
|
CommandBuilder,
|
|
15
11
|
CommandDef,
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
calculateTierProgress,
|
|
13
|
+
getNextTierMinRating,
|
|
14
|
+
getSolvedAcHandle,
|
|
15
|
+
getTierColor,
|
|
16
|
+
getTierName
|
|
17
|
+
} from "../chunk-TNGUME4H.js";
|
|
18
18
|
import {
|
|
19
19
|
__decorateClass
|
|
20
20
|
} from "../chunk-7MQMPJ3X.js";
|
package/dist/commands/submit.js
CHANGED
package/dist/commands/test.js
CHANGED