@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
|
@@ -4,26 +4,26 @@ import {
|
|
|
4
4
|
CommandBuilder,
|
|
5
5
|
CommandDef,
|
|
6
6
|
findProjectRoot,
|
|
7
|
-
|
|
8
|
-
getProblemId,
|
|
7
|
+
getArchiveDirPath,
|
|
9
8
|
getSolvingDir,
|
|
10
|
-
getSolvingDirPath
|
|
11
|
-
|
|
9
|
+
getSolvingDirPath,
|
|
10
|
+
resolveProblemContext
|
|
11
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
12
12
|
import {
|
|
13
13
|
__decorateClass
|
|
14
14
|
} from "../chunk-7MQMPJ3X.js";
|
|
15
15
|
|
|
16
|
-
// src/commands/
|
|
16
|
+
// src/commands/archive.tsx
|
|
17
17
|
import { StatusMessage, Alert } from "@inkjs/ui";
|
|
18
18
|
import { Spinner } from "@inkjs/ui";
|
|
19
19
|
import { Box } from "ink";
|
|
20
20
|
|
|
21
|
-
// src/hooks/use-
|
|
21
|
+
// src/hooks/use-archive.ts
|
|
22
22
|
import { access, readFile, rename, mkdir, readdir, rmdir } from "fs/promises";
|
|
23
23
|
import { join, dirname } from "path";
|
|
24
24
|
import { execa } from "execa";
|
|
25
25
|
import { useEffect, useState } from "react";
|
|
26
|
-
function
|
|
26
|
+
function useArchive({
|
|
27
27
|
problemId,
|
|
28
28
|
onComplete
|
|
29
29
|
}) {
|
|
@@ -33,7 +33,7 @@ function useSolve({
|
|
|
33
33
|
const [message, setMessage] = useState("\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uC911...");
|
|
34
34
|
const [error, setError] = useState(null);
|
|
35
35
|
useEffect(() => {
|
|
36
|
-
async function
|
|
36
|
+
async function archive() {
|
|
37
37
|
try {
|
|
38
38
|
const projectRoot = findProjectRoot();
|
|
39
39
|
if (!projectRoot) {
|
|
@@ -71,22 +71,22 @@ function useSolve({
|
|
|
71
71
|
}
|
|
72
72
|
} catch {
|
|
73
73
|
}
|
|
74
|
-
const
|
|
74
|
+
const archiveDir = getArchiveDirPath(problemId, projectRoot, problem);
|
|
75
75
|
try {
|
|
76
|
-
await access(
|
|
76
|
+
await access(archiveDir);
|
|
77
77
|
throw new Error(
|
|
78
|
-
`
|
|
78
|
+
`archive \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC774\uBBF8 \uBB38\uC81C ${problemId}\uAC00 \uC874\uC7AC\uD569\uB2C8\uB2E4.`
|
|
79
79
|
);
|
|
80
80
|
} catch (err) {
|
|
81
81
|
if (err instanceof Error && err.message.includes("\uC774\uBBF8")) {
|
|
82
82
|
throw err;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
const
|
|
85
|
+
const archiveDirParent = dirname(archiveDir);
|
|
86
86
|
setMessage("\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC\uB97C \uC900\uBE44\uD558\uB294 \uC911...");
|
|
87
|
-
await mkdir(
|
|
88
|
-
setMessage("\uBB38\uC81C\uB97C
|
|
89
|
-
await rename(solvingDir,
|
|
87
|
+
await mkdir(archiveDirParent, { recursive: true });
|
|
88
|
+
setMessage("\uBB38\uC81C\uB97C archive \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9\uD558\uB294 \uC911...");
|
|
89
|
+
await rename(solvingDir, archiveDir);
|
|
90
90
|
setMessage("\uBE48 \uB514\uB809\uD1A0\uB9AC \uC815\uB9AC \uC911...");
|
|
91
91
|
try {
|
|
92
92
|
const solvingDirConfig = getSolvingDir();
|
|
@@ -111,7 +111,7 @@ function useSolve({
|
|
|
111
111
|
}
|
|
112
112
|
setMessage("Git \uCEE4\uBC0B\uC744 \uC2E4\uD589\uD558\uB294 \uC911...");
|
|
113
113
|
try {
|
|
114
|
-
await execa("git", ["add",
|
|
114
|
+
await execa("git", ["add", archiveDir], { cwd: projectRoot });
|
|
115
115
|
const commitMessage = `solve: ${problemId} - ${problemTitle}`;
|
|
116
116
|
await execa("git", ["commit", "-m", commitMessage], {
|
|
117
117
|
cwd: projectRoot
|
|
@@ -123,7 +123,7 @@ function useSolve({
|
|
|
123
123
|
);
|
|
124
124
|
}
|
|
125
125
|
setStatus("success");
|
|
126
|
-
setMessage(`\uBB38\uC81C ${problemId}\uB97C \uC544\uCE74\uC774\uBE0C\uD588\uC2B5\uB2C8\uB2E4: ${
|
|
126
|
+
setMessage(`\uBB38\uC81C ${problemId}\uB97C \uC544\uCE74\uC774\uBE0C\uD588\uC2B5\uB2C8\uB2E4: ${archiveDir}`);
|
|
127
127
|
setTimeout(() => {
|
|
128
128
|
onComplete?.();
|
|
129
129
|
}, 2e3);
|
|
@@ -135,7 +135,7 @@ function useSolve({
|
|
|
135
135
|
}, 2e3);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
void
|
|
138
|
+
void archive();
|
|
139
139
|
}, [problemId, onComplete]);
|
|
140
140
|
return {
|
|
141
141
|
status,
|
|
@@ -144,10 +144,10 @@ function useSolve({
|
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
// src/commands/
|
|
147
|
+
// src/commands/archive.tsx
|
|
148
148
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
149
|
-
function
|
|
150
|
-
const { status, message, error } =
|
|
149
|
+
function ArchiveView({ problemId, onComplete }) {
|
|
150
|
+
const { status, message, error } = useArchive({
|
|
151
151
|
problemId,
|
|
152
152
|
onComplete
|
|
153
153
|
});
|
|
@@ -162,40 +162,40 @@ function SolveView({ problemId, onComplete }) {
|
|
|
162
162
|
}
|
|
163
163
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: message }) });
|
|
164
164
|
}
|
|
165
|
-
var
|
|
165
|
+
var ArchiveCommand = class extends Command {
|
|
166
166
|
async execute(args, _) {
|
|
167
|
-
const
|
|
168
|
-
if (problemId === null) {
|
|
167
|
+
const context = await resolveProblemContext(args, { requireId: false });
|
|
168
|
+
if (context.problemId === null) {
|
|
169
169
|
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
170
|
-
console.error(`\uC0AC\uC6A9\uBC95: ps
|
|
171
|
-
console.error(`\uB3C4\uC6C0\uB9D0: ps
|
|
170
|
+
console.error(`\uC0AC\uC6A9\uBC95: ps archive <\uBB38\uC81C\uBC88\uD638>`);
|
|
171
|
+
console.error(`\uB3C4\uC6C0\uB9D0: ps archive --help`);
|
|
172
172
|
console.error(
|
|
173
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
174
|
);
|
|
175
175
|
process.exit(1);
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
|
-
await this.renderView(
|
|
179
|
-
problemId
|
|
178
|
+
await this.renderView(ArchiveView, {
|
|
179
|
+
problemId: context.problemId
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
};
|
|
183
|
-
|
|
183
|
+
ArchiveCommand = __decorateClass([
|
|
184
184
|
CommandDef({
|
|
185
|
-
name: "
|
|
185
|
+
name: "archive",
|
|
186
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
|
|
187
|
+
- solving \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C\uB97C \uCC3E\uC544 archive \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9
|
|
188
188
|
- Git add \uBC0F commit \uC2E4\uD589 (\uCEE4\uBC0B \uBA54\uC2DC\uC9C0: "solve: {\uBB38\uC81C\uBC88\uD638} - {\uBB38\uC81C\uC774\uB984}")`,
|
|
189
189
|
autoDetectProblemId: true,
|
|
190
190
|
requireProblemId: false,
|
|
191
191
|
examples: [
|
|
192
|
-
"
|
|
193
|
-
"
|
|
192
|
+
"archive 1000",
|
|
193
|
+
"archive # \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C \uBC88\uD638 \uC790\uB3D9 \uAC10\uC9C0"
|
|
194
194
|
]
|
|
195
195
|
})
|
|
196
|
-
],
|
|
197
|
-
var
|
|
196
|
+
], ArchiveCommand);
|
|
197
|
+
var archive_default = CommandBuilder.fromClass(ArchiveCommand);
|
|
198
198
|
export {
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
ArchiveCommand,
|
|
200
|
+
archive_default as default
|
|
201
201
|
};
|
package/dist/commands/config.js
CHANGED
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
Command,
|
|
4
4
|
CommandBuilder,
|
|
5
5
|
CommandDef,
|
|
6
|
+
getArchiveDir,
|
|
6
7
|
getArchiveStrategy,
|
|
7
8
|
getAutoOpenEditor,
|
|
8
9
|
getDefaultLanguage,
|
|
9
10
|
getEditor,
|
|
10
|
-
getProblemDir,
|
|
11
11
|
getSolvedAcHandle
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
13
13
|
import {
|
|
14
14
|
__decorateClass,
|
|
15
15
|
getSupportedLanguages,
|
|
@@ -102,8 +102,8 @@ function useConfig({
|
|
|
102
102
|
case "solved-ac-handle":
|
|
103
103
|
updatedConfig.solvedAcHandle = value;
|
|
104
104
|
break;
|
|
105
|
-
case "
|
|
106
|
-
updatedConfig.
|
|
105
|
+
case "archive-dir":
|
|
106
|
+
updatedConfig.archiveDir = value;
|
|
107
107
|
break;
|
|
108
108
|
case "archive-strategy": {
|
|
109
109
|
const validStrategies = ["flat", "by-range", "by-tier", "by-tag"];
|
|
@@ -159,7 +159,7 @@ function getConfigHelp() {
|
|
|
159
159
|
editor \uC5D0\uB514\uD130 \uBA85\uB839\uC5B4 (\uC608: code, vim, nano)
|
|
160
160
|
auto-open-editor fetch \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5D0\uB514\uD130 \uC5F4\uAE30 (true/false)
|
|
161
161
|
solved-ac-handle Solved.ac \uD578\uB4E4 (stats \uBA85\uB839\uC5B4\uC6A9)
|
|
162
|
-
|
|
162
|
+
archive-dir \uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8\uAC12: problems, "." \uB610\uB294 ""\uB294 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8)
|
|
163
163
|
archive-strategy \uC544\uCE74\uC774\uBE59 \uC804\uB7B5 (flat, by-range, by-tier, by-tag)
|
|
164
164
|
|
|
165
165
|
\uC635\uC158:
|
|
@@ -180,7 +180,7 @@ var CONFIG_KEYS = [
|
|
|
180
180
|
{ label: "editor", value: "editor" },
|
|
181
181
|
{ label: "auto-open-editor", value: "auto-open-editor" },
|
|
182
182
|
{ label: "solved-ac-handle", value: "solved-ac-handle" },
|
|
183
|
-
{ label: "
|
|
183
|
+
{ label: "archive-dir", value: "archive-dir" },
|
|
184
184
|
{ label: "archive-strategy", value: "archive-strategy" }
|
|
185
185
|
];
|
|
186
186
|
function ConfigView({
|
|
@@ -213,7 +213,7 @@ function ConfigView({
|
|
|
213
213
|
const editor = config?.editor ?? getEditor();
|
|
214
214
|
const autoOpen = config?.autoOpenEditor ?? getAutoOpenEditor();
|
|
215
215
|
const handle = config?.solvedAcHandle ?? getSolvedAcHandle();
|
|
216
|
-
const
|
|
216
|
+
const archiveDir = config?.archiveDir ?? getArchiveDir();
|
|
217
217
|
const archiveStrategy = config?.archiveStrategy ?? getArchiveStrategy();
|
|
218
218
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
219
219
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2699\uFE0F \uD604\uC7AC \uC124\uC815 (.ps-cli.json)" }) }),
|
|
@@ -239,9 +239,9 @@ function ConfigView({
|
|
|
239
239
|
/* @__PURE__ */ jsx(Text, { bold: true, color: handle ? "cyan" : "gray", children: handle || "\uC124\uC815 \uC548 \uB428" })
|
|
240
240
|
] }),
|
|
241
241
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
242
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", children: "
|
|
242
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "archive-dir:" }),
|
|
243
243
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
244
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children:
|
|
244
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: archiveDir })
|
|
245
245
|
] }),
|
|
246
246
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
247
247
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "archive-strategy:" }),
|
|
@@ -266,8 +266,8 @@ function ConfigView({
|
|
|
266
266
|
case "solved-ac-handle":
|
|
267
267
|
configValue = config?.solvedAcHandle ?? getSolvedAcHandle();
|
|
268
268
|
break;
|
|
269
|
-
case "
|
|
270
|
-
configValue = config?.
|
|
269
|
+
case "archive-dir":
|
|
270
|
+
configValue = config?.archiveDir ?? getArchiveDir();
|
|
271
271
|
break;
|
|
272
272
|
case "archive-strategy":
|
|
273
273
|
configValue = config?.archiveStrategy ?? getArchiveStrategy();
|
|
@@ -440,8 +440,8 @@ var ConfigCommand = class extends Command {
|
|
|
440
440
|
return "true \uB610\uB294 false \uC785\uB825";
|
|
441
441
|
case "solved-ac-handle":
|
|
442
442
|
return "Solved.ac \uD578\uB4E4 \uC785\uB825";
|
|
443
|
-
case "
|
|
444
|
-
return "\
|
|
443
|
+
case "archive-dir":
|
|
444
|
+
return "\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uC785\uB825";
|
|
445
445
|
case "archive-strategy":
|
|
446
446
|
return "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5 \uC785\uB825 (flat, by-range, by-tier, by-tag)";
|
|
447
447
|
default:
|
|
@@ -458,8 +458,8 @@ var ConfigCommand = class extends Command {
|
|
|
458
458
|
return "fetch \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5D0\uB514\uD130\uB97C \uC5F4\uC9C0 \uC5EC\uBD80";
|
|
459
459
|
case "solved-ac-handle":
|
|
460
460
|
return "Solved.ac \uC0AC\uC6A9\uC790 \uD578\uB4E4";
|
|
461
|
-
case "
|
|
462
|
-
return '\
|
|
461
|
+
case "archive-dir":
|
|
462
|
+
return '\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8\uAC12: "problems", \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8: ".")';
|
|
463
463
|
case "archive-strategy":
|
|
464
464
|
return "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5: flat (\uD3C9\uBA74), by-range (1000\uBC88\uB300 \uBB36\uAE30), by-tier (\uD2F0\uC5B4\uBCC4), by-tag (\uD0DC\uADF8\uBCC4)";
|
|
465
465
|
default:
|
|
@@ -474,7 +474,7 @@ var ConfigCommand = class extends Command {
|
|
|
474
474
|
return ["code", "cursor", "vim", "nano"];
|
|
475
475
|
case "auto-open-editor":
|
|
476
476
|
return ["true", "false"];
|
|
477
|
-
case "
|
|
477
|
+
case "archive-dir":
|
|
478
478
|
return ["problems", ".", ""];
|
|
479
479
|
case "archive-strategy":
|
|
480
480
|
return ["flat", "by-range", "by-tier", "by-tag"];
|
package/dist/commands/fetch.js
CHANGED
|
@@ -11,12 +11,12 @@ import {
|
|
|
11
11
|
CommandDef,
|
|
12
12
|
getAutoOpenEditor,
|
|
13
13
|
getEditor,
|
|
14
|
-
getProblemId,
|
|
15
14
|
getSolvingDirPath,
|
|
16
15
|
getTierColor,
|
|
17
16
|
getTierImageUrl,
|
|
18
|
-
getTierName
|
|
19
|
-
|
|
17
|
+
getTierName,
|
|
18
|
+
resolveProblemContext
|
|
19
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
20
20
|
import {
|
|
21
21
|
__decorateClass,
|
|
22
22
|
getLanguageConfig,
|
|
@@ -75,6 +75,27 @@ function parseTimeLimitToMs(timeLimit) {
|
|
|
75
75
|
if (Number.isNaN(seconds)) return void 0;
|
|
76
76
|
return Math.round(seconds * 1e3);
|
|
77
77
|
}
|
|
78
|
+
function ensureTrailingNewline(content) {
|
|
79
|
+
if (!content || content.trim().length === 0) {
|
|
80
|
+
return content;
|
|
81
|
+
}
|
|
82
|
+
const trimmed = content.trimEnd();
|
|
83
|
+
if (trimmed.length === 0) {
|
|
84
|
+
return content;
|
|
85
|
+
}
|
|
86
|
+
const lines = trimmed.split("\n");
|
|
87
|
+
const lastLine = lines[lines.length - 1];
|
|
88
|
+
const isListItem = /^[\s]*[-*]\s/.test(lastLine) || /^[\s]*\d+[.)]\s/.test(lastLine);
|
|
89
|
+
const isTableRow = /^\s*\|.+\|\s*$/.test(lastLine);
|
|
90
|
+
const isCodeBlock = trimmed.endsWith("```");
|
|
91
|
+
if (isListItem || isTableRow || isCodeBlock) {
|
|
92
|
+
return trimmed + "\n";
|
|
93
|
+
}
|
|
94
|
+
if (!content.endsWith("\n")) {
|
|
95
|
+
return content + "\n";
|
|
96
|
+
}
|
|
97
|
+
return content;
|
|
98
|
+
}
|
|
78
99
|
function getProjectRoot() {
|
|
79
100
|
const __filename = fileURLToPath(import.meta.url);
|
|
80
101
|
const __dirname = dirname(__filename);
|
|
@@ -101,10 +122,13 @@ async function generateProblemFiles(problem, language = "python") {
|
|
|
101
122
|
"utf-8"
|
|
102
123
|
);
|
|
103
124
|
}
|
|
125
|
+
const testcasesDir = join(problemDir, "testcases");
|
|
104
126
|
for (let i = 0; i < problem.testCases.length; i++) {
|
|
105
127
|
const testCase = problem.testCases[i];
|
|
106
|
-
const
|
|
107
|
-
|
|
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");
|
|
108
132
|
await writeFile(inputPath, testCase.input, "utf-8");
|
|
109
133
|
await writeFile(outputPath, testCase.output, "utf-8");
|
|
110
134
|
}
|
|
@@ -150,16 +174,19 @@ ${separatorRow}
|
|
|
150
174
|
${valueRow}
|
|
151
175
|
`;
|
|
152
176
|
}
|
|
177
|
+
const description = ensureTrailingNewline(problem.description || "\uC124\uBA85 \uC5C6\uC74C");
|
|
178
|
+
const inputFormat = ensureTrailingNewline(
|
|
179
|
+
problem.inputFormat || "\uC785\uB825 \uD615\uC2DD \uC5C6\uC74C"
|
|
180
|
+
);
|
|
181
|
+
const outputFormat = ensureTrailingNewline(
|
|
182
|
+
problem.outputFormat || "\uCD9C\uB825 \uD615\uC2DD \uC5C6\uC74C"
|
|
183
|
+
);
|
|
153
184
|
const readmeContent = `# [${problem.id}: ${problem.title}](https://www.acmicpc.net/problem/${problem.id})
|
|
154
185
|
|
|
155
186
|
${infoTable}## \uBB38\uC81C \uC124\uBA85
|
|
156
|
-
${
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
${problem.inputFormat || "\uC785\uB825 \uD615\uC2DD \uC5C6\uC74C"}
|
|
160
|
-
|
|
161
|
-
## \uCD9C\uB825
|
|
162
|
-
${problem.outputFormat || "\uCD9C\uB825 \uD615\uC2DD \uC5C6\uC74C"}
|
|
187
|
+
${description}## \uC785\uB825
|
|
188
|
+
${inputFormat}## \uCD9C\uB825
|
|
189
|
+
${outputFormat}
|
|
163
190
|
|
|
164
191
|
## \uC608\uC81C
|
|
165
192
|
${problem.testCases.map(
|
|
@@ -317,8 +344,8 @@ function FetchView({
|
|
|
317
344
|
}
|
|
318
345
|
var FetchCommand = class extends Command {
|
|
319
346
|
async execute(args, flags) {
|
|
320
|
-
const
|
|
321
|
-
if (problemId === null) {
|
|
347
|
+
const context = await resolveProblemContext(args, { requireId: true });
|
|
348
|
+
if (context.problemId === null) {
|
|
322
349
|
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
323
350
|
console.error(`\uC0AC\uC6A9\uBC95: ps fetch <\uBB38\uC81C\uBC88\uD638> [\uC635\uC158]`);
|
|
324
351
|
console.error(`\uB3C4\uC6C0\uB9D0: ps fetch --help`);
|
|
@@ -338,7 +365,7 @@ var FetchCommand = class extends Command {
|
|
|
338
365
|
return;
|
|
339
366
|
}
|
|
340
367
|
await this.renderView(FetchView, {
|
|
341
|
-
problemId,
|
|
368
|
+
problemId: context.problemId,
|
|
342
369
|
language: language || "python"
|
|
343
370
|
});
|
|
344
371
|
}
|
package/dist/commands/init.js
CHANGED
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
Command,
|
|
4
4
|
CommandBuilder,
|
|
5
5
|
CommandDef,
|
|
6
|
+
getArchiveDir,
|
|
6
7
|
getArchiveStrategy,
|
|
7
8
|
getAutoOpenEditor,
|
|
8
9
|
getDefaultLanguage,
|
|
9
10
|
getEditor,
|
|
10
|
-
getProblemDir,
|
|
11
11
|
getSolvedAcHandle,
|
|
12
12
|
getSolvingDir
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
14
14
|
import {
|
|
15
15
|
__decorateClass,
|
|
16
16
|
getSupportedLanguages
|
|
@@ -32,11 +32,11 @@ import { join } from "path";
|
|
|
32
32
|
import { execaCommand, execa } from "execa";
|
|
33
33
|
import { useEffect, useState, useCallback } from "react";
|
|
34
34
|
function useInit({ onComplete }) {
|
|
35
|
-
const [currentStep, setCurrentStep] = useState("
|
|
35
|
+
const [currentStep, setCurrentStep] = useState("archive-dir");
|
|
36
36
|
const [completedSteps, setCompletedSteps] = useState([]);
|
|
37
37
|
const [confirmExit, setConfirmExit] = useState(false);
|
|
38
38
|
const [initialized, setInitialized] = useState(false);
|
|
39
|
-
const [
|
|
39
|
+
const [archiveDir, setArchiveDirValue] = useState(getArchiveDir());
|
|
40
40
|
const [solvingDir, setSolvingDirValue] = useState(getSolvingDir());
|
|
41
41
|
const [archiveStrategy, setArchiveStrategy] = useState(getArchiveStrategy());
|
|
42
42
|
const [language, setLanguage] = useState(getDefaultLanguage());
|
|
@@ -71,8 +71,8 @@ function useInit({ onComplete }) {
|
|
|
71
71
|
await access(projectConfigPath);
|
|
72
72
|
const configContent = await readFile(projectConfigPath, "utf-8");
|
|
73
73
|
const projectConfig = JSON.parse(configContent);
|
|
74
|
-
if (projectConfig.
|
|
75
|
-
|
|
74
|
+
if (projectConfig.archiveDir)
|
|
75
|
+
setArchiveDirValue(projectConfig.archiveDir);
|
|
76
76
|
if (projectConfig.solvingDir)
|
|
77
77
|
setSolvingDirValue(projectConfig.solvingDir);
|
|
78
78
|
if (projectConfig.archiveStrategy)
|
|
@@ -93,8 +93,8 @@ function useInit({ onComplete }) {
|
|
|
93
93
|
}, []);
|
|
94
94
|
const getStepLabel = useCallback((step) => {
|
|
95
95
|
switch (step) {
|
|
96
|
-
case "
|
|
97
|
-
return "\
|
|
96
|
+
case "archive-dir":
|
|
97
|
+
return "\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uC544\uCE74\uC774\uBE0C\uB41C \uBB38\uC81C)";
|
|
98
98
|
case "solving-dir":
|
|
99
99
|
return "Solving \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uD478\uB294 \uC911\uC778 \uBB38\uC81C)";
|
|
100
100
|
case "archive-strategy":
|
|
@@ -114,8 +114,8 @@ function useInit({ onComplete }) {
|
|
|
114
114
|
const getStepValue = useCallback(
|
|
115
115
|
(step) => {
|
|
116
116
|
switch (step) {
|
|
117
|
-
case "
|
|
118
|
-
return
|
|
117
|
+
case "archive-dir":
|
|
118
|
+
return archiveDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : archiveDir;
|
|
119
119
|
case "solving-dir":
|
|
120
120
|
return solvingDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : solvingDir;
|
|
121
121
|
case "archive-strategy": {
|
|
@@ -140,13 +140,13 @@ function useInit({ onComplete }) {
|
|
|
140
140
|
}
|
|
141
141
|
},
|
|
142
142
|
[
|
|
143
|
-
|
|
143
|
+
archiveDir,
|
|
144
144
|
solvingDir,
|
|
145
|
-
archiveStrategy,
|
|
146
145
|
language,
|
|
147
146
|
editor,
|
|
148
147
|
autoOpen,
|
|
149
|
-
handle
|
|
148
|
+
handle,
|
|
149
|
+
archiveStrategy
|
|
150
150
|
]
|
|
151
151
|
);
|
|
152
152
|
const executeInit = useCallback(
|
|
@@ -155,7 +155,7 @@ function useInit({ onComplete }) {
|
|
|
155
155
|
const cwd = process.cwd();
|
|
156
156
|
const projectConfigPath = join(cwd, ".ps-cli.json");
|
|
157
157
|
const projectConfig = {
|
|
158
|
-
|
|
158
|
+
archiveDir,
|
|
159
159
|
solvingDir,
|
|
160
160
|
archiveStrategy,
|
|
161
161
|
defaultLanguage: language,
|
|
@@ -172,11 +172,11 @@ function useInit({ onComplete }) {
|
|
|
172
172
|
"utf-8"
|
|
173
173
|
);
|
|
174
174
|
setCreated((prev) => [...prev, ".ps-cli.json"]);
|
|
175
|
-
if (
|
|
176
|
-
const
|
|
175
|
+
if (archiveDir !== "." && archiveDir !== "") {
|
|
176
|
+
const archiveDirPath = join(cwd, archiveDir);
|
|
177
177
|
try {
|
|
178
|
-
await mkdir(
|
|
179
|
-
setCreated((prev) => [...prev, `${
|
|
178
|
+
await mkdir(archiveDirPath, { recursive: true });
|
|
179
|
+
setCreated((prev) => [...prev, `${archiveDir}/`]);
|
|
180
180
|
} catch (err) {
|
|
181
181
|
const error = err;
|
|
182
182
|
if (error.code !== "EEXIST") {
|
|
@@ -280,7 +280,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
280
280
|
}
|
|
281
281
|
},
|
|
282
282
|
[
|
|
283
|
-
|
|
283
|
+
archiveDir,
|
|
284
284
|
solvingDir,
|
|
285
285
|
archiveStrategy,
|
|
286
286
|
language,
|
|
@@ -300,7 +300,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
300
300
|
setHandle(handleValue);
|
|
301
301
|
}
|
|
302
302
|
const stepOrder = [
|
|
303
|
-
"
|
|
303
|
+
"archive-dir",
|
|
304
304
|
"solving-dir",
|
|
305
305
|
"archive-strategy",
|
|
306
306
|
"language",
|
|
@@ -322,24 +322,14 @@ ${gitignorePatterns.join("\n")}
|
|
|
322
322
|
}
|
|
323
323
|
}
|
|
324
324
|
},
|
|
325
|
-
[
|
|
326
|
-
currentStep,
|
|
327
|
-
executeInit,
|
|
328
|
-
problemDir,
|
|
329
|
-
solvingDir,
|
|
330
|
-
archiveStrategy,
|
|
331
|
-
language,
|
|
332
|
-
editor,
|
|
333
|
-
autoOpen,
|
|
334
|
-
onComplete
|
|
335
|
-
]
|
|
325
|
+
[currentStep, executeInit]
|
|
336
326
|
);
|
|
337
327
|
return {
|
|
338
328
|
currentStep,
|
|
339
329
|
completedSteps,
|
|
340
330
|
confirmExit,
|
|
341
331
|
initialized,
|
|
342
|
-
|
|
332
|
+
archiveDir,
|
|
343
333
|
solvingDir,
|
|
344
334
|
archiveStrategy,
|
|
345
335
|
language,
|
|
@@ -349,7 +339,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
349
339
|
handleInputMode,
|
|
350
340
|
created,
|
|
351
341
|
cancelled,
|
|
352
|
-
|
|
342
|
+
setArchiveDirValue,
|
|
353
343
|
setSolvingDirValue,
|
|
354
344
|
setArchiveStrategy,
|
|
355
345
|
setLanguage,
|
|
@@ -366,6 +356,22 @@ ${gitignorePatterns.join("\n")}
|
|
|
366
356
|
};
|
|
367
357
|
}
|
|
368
358
|
|
|
359
|
+
// src/utils/version.ts
|
|
360
|
+
import { readFileSync } from "fs";
|
|
361
|
+
import { join as join2, dirname } from "path";
|
|
362
|
+
import { fileURLToPath } from "url";
|
|
363
|
+
function getVersion() {
|
|
364
|
+
try {
|
|
365
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
366
|
+
const __dirname = dirname(__filename);
|
|
367
|
+
const packageJsonPath = join2(__dirname, "../../package.json");
|
|
368
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
369
|
+
return packageJson.version;
|
|
370
|
+
} catch {
|
|
371
|
+
return "";
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
369
375
|
// src/commands/init.tsx
|
|
370
376
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
371
377
|
function InitView({ onComplete }) {
|
|
@@ -377,7 +383,7 @@ function InitView({ onComplete }) {
|
|
|
377
383
|
handleInputMode,
|
|
378
384
|
created,
|
|
379
385
|
cancelled,
|
|
380
|
-
|
|
386
|
+
setArchiveDirValue,
|
|
381
387
|
setSolvingDirValue,
|
|
382
388
|
setArchiveStrategy,
|
|
383
389
|
setLanguage,
|
|
@@ -424,7 +430,7 @@ function InitView({ onComplete }) {
|
|
|
424
430
|
] });
|
|
425
431
|
}
|
|
426
432
|
switch (currentStep) {
|
|
427
|
-
case "
|
|
433
|
+
case "archive-dir": {
|
|
428
434
|
const options = [
|
|
429
435
|
{ label: "problems", value: "problems" },
|
|
430
436
|
{ label: ". (\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8)", value: "." }
|
|
@@ -436,7 +442,7 @@ function InitView({ onComplete }) {
|
|
|
436
442
|
{
|
|
437
443
|
options,
|
|
438
444
|
onChange: (value) => {
|
|
439
|
-
|
|
445
|
+
setArchiveDirValue(value);
|
|
440
446
|
const displayValue = value === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : value;
|
|
441
447
|
moveToNextStep(displayValue, getStepLabel(currentStep));
|
|
442
448
|
}
|
|
@@ -626,8 +632,16 @@ ${created.map((item) => `\u2022 ${item}`).join("\n")}` : "";
|
|
|
626
632
|
if (!initialized) {
|
|
627
633
|
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "\uB85C\uB529 \uC911..." }) });
|
|
628
634
|
}
|
|
635
|
+
const version = getVersion();
|
|
629
636
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
630
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ jsxs(Box, { marginBottom: completedSteps.length > 0 ? 1 : 0, children: [
|
|
638
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u{1F680} ps-cli \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654" }),
|
|
639
|
+
version && /* @__PURE__ */ jsxs(Text, { color: "gray", dimColor: true, children: [
|
|
640
|
+
" ",
|
|
641
|
+
"v",
|
|
642
|
+
version
|
|
643
|
+
] })
|
|
644
|
+
] }),
|
|
631
645
|
completedSteps.length > 0 && /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: completedSteps.map((step, idx) => /* @__PURE__ */ jsxs(StatusMessage, { variant: "success", children: [
|
|
632
646
|
step.label,
|
|
633
647
|
": ",
|
package/dist/commands/open.js
CHANGED
|
@@ -7,9 +7,8 @@ import {
|
|
|
7
7
|
Command,
|
|
8
8
|
CommandBuilder,
|
|
9
9
|
CommandDef,
|
|
10
|
-
getProblemId,
|
|
11
10
|
resolveProblemContext
|
|
12
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-F4LZ6ENP.js";
|
|
13
12
|
import {
|
|
14
13
|
__decorateClass
|
|
15
14
|
} from "../chunk-7MQMPJ3X.js";
|
|
@@ -63,11 +62,7 @@ function OpenView({ problemId, onComplete }) {
|
|
|
63
62
|
}
|
|
64
63
|
var OpenCommand = class extends Command {
|
|
65
64
|
async execute(args, _flags) {
|
|
66
|
-
const
|
|
67
|
-
const context = await resolveProblemContext(
|
|
68
|
-
problemId !== null ? [problemId.toString()] : [],
|
|
69
|
-
{ requireId: true }
|
|
70
|
-
);
|
|
65
|
+
const context = await resolveProblemContext(args, { requireId: true });
|
|
71
66
|
if (context.problemId === null) {
|
|
72
67
|
console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
73
68
|
console.error(`\uC0AC\uC6A9\uBC95: ps open <\uBB38\uC81C\uBC88\uD638>`);
|