@rhseung/ps-cli 1.9.8 → 1.10.2
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 +21 -21
- package/dist/{chunk-AHVAVNFM.js → chunk-7DZDLCGW.js} +2 -2
- package/dist/{chunk-Q5NECGFA.js → chunk-AHE4QHJD.js} +196 -146
- package/dist/{chunk-2YSOO6AM.js → chunk-CUSSKX2F.js} +2 -2
- package/dist/{chunk-YZUGYJA4.js → chunk-GV265WOR.js} +3 -3
- package/dist/{chunk-457JZK3K.js → chunk-HCUVCES6.js} +1 -1
- package/dist/{chunk-3H74PQRX.js → chunk-NYMNFORB.js} +1 -1
- package/dist/{chunk-YCFY6UCA.js → chunk-S7IL7OXF.js} +1 -1
- package/dist/{chunk-M4LNYKJF.js → chunk-XUDGIZ2U.js} +33 -12
- package/dist/commands/archive.js +2 -2
- package/dist/commands/config.js +187 -119
- package/dist/commands/fetch.js +3 -3
- package/dist/commands/init.js +206 -156
- package/dist/commands/open.js +2 -2
- package/dist/commands/run.js +2 -2
- package/dist/commands/search.js +8 -8
- package/dist/commands/stats.js +2 -2
- package/dist/commands/submit.js +2 -2
- package/dist/commands/test.js +3 -3
- package/dist/index.js +4 -18
- package/package.json +3 -2
package/dist/commands/init.js
CHANGED
|
@@ -7,14 +7,16 @@ import {
|
|
|
7
7
|
getArchiveDir,
|
|
8
8
|
getArchiveStrategy,
|
|
9
9
|
getAutoOpenEditor,
|
|
10
|
+
getConfigMetadata,
|
|
10
11
|
getDefaultLanguage,
|
|
11
12
|
getEditor,
|
|
12
13
|
getIncludeTag,
|
|
13
14
|
getSolvedAcHandle,
|
|
14
15
|
getSolvingDir,
|
|
15
16
|
getSupportedLanguages,
|
|
17
|
+
getVersion,
|
|
16
18
|
icons
|
|
17
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-AHE4QHJD.js";
|
|
18
20
|
|
|
19
21
|
// src/commands/init.tsx
|
|
20
22
|
import {
|
|
@@ -27,23 +29,118 @@ import {
|
|
|
27
29
|
import { Text, Box } from "ink";
|
|
28
30
|
|
|
29
31
|
// src/hooks/use-init.ts
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
+
import { existsSync } from "fs";
|
|
33
|
+
import {
|
|
34
|
+
mkdir,
|
|
35
|
+
readFile,
|
|
36
|
+
writeFile,
|
|
37
|
+
access,
|
|
38
|
+
copyFile,
|
|
39
|
+
readdir
|
|
40
|
+
} from "fs/promises";
|
|
41
|
+
import { join, dirname } from "path";
|
|
42
|
+
import { fileURLToPath } from "url";
|
|
32
43
|
import { execaCommand, execa } from "execa";
|
|
33
44
|
import { useEffect, useState, useCallback } from "react";
|
|
45
|
+
function getCliRoot() {
|
|
46
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
47
|
+
const __dirname = dirname(__filename);
|
|
48
|
+
let current = __dirname;
|
|
49
|
+
while (current !== dirname(current)) {
|
|
50
|
+
const templatesDir = join(current, "templates");
|
|
51
|
+
try {
|
|
52
|
+
const stats = existsSync(templatesDir);
|
|
53
|
+
if (stats) return current;
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
current = dirname(current);
|
|
57
|
+
}
|
|
58
|
+
return join(__dirname, "../..");
|
|
59
|
+
}
|
|
60
|
+
function buildDefaultConfigYaml({
|
|
61
|
+
language,
|
|
62
|
+
editor,
|
|
63
|
+
autoOpen,
|
|
64
|
+
solvingDir,
|
|
65
|
+
archiveDir,
|
|
66
|
+
archiveStrategy,
|
|
67
|
+
includeTag,
|
|
68
|
+
handle
|
|
69
|
+
}) {
|
|
70
|
+
return `
|
|
71
|
+
# ps-cli \uC124\uC815 \uD30C\uC77C
|
|
72
|
+
# \uB354 \uC790\uC138\uD55C \uC815\uBCF4\uB294 \uB2E4\uC74C\uC744 \uCC38\uACE0\uD558\uC138\uC694: https://github.com/rhseung/ps-cli
|
|
73
|
+
|
|
74
|
+
general:
|
|
75
|
+
# \uC0C8\uB85C\uC6B4 \uBB38\uC81C\uB97C \uAC00\uC838\uC62C \uB54C \uC0AC\uC6A9\uD560 \uAE30\uBCF8 \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4\uC785\uB2C8\uB2E4.
|
|
76
|
+
default_language: ${language}
|
|
77
|
+
# \uD1B5\uACC4 \uC870\uD68C\uB97C \uC704\uD55C Solved.ac \uD578\uB4E4(\uB2C9\uB124\uC784)\uC785\uB2C8\uB2E4.
|
|
78
|
+
solved_ac_handle: "${handle}"
|
|
79
|
+
|
|
80
|
+
editor:
|
|
81
|
+
# \uC5D0\uB514\uD130\uB97C \uC5F4 \uB54C \uC0AC\uC6A9\uD560 \uBA85\uB839\uC5B4\uC785\uB2C8\uB2E4 (\uC608: code, cursor, vim).
|
|
82
|
+
command: ${editor}
|
|
83
|
+
# \uBB38\uC81C\uB97C \uAC00\uC838\uC628 \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5D0\uB514\uD130\uB97C \uC5F4\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.
|
|
84
|
+
auto_open: ${autoOpen}
|
|
85
|
+
|
|
86
|
+
paths:
|
|
87
|
+
# \uD604\uC7AC \uD480\uACE0 \uC788\uB294 \uBB38\uC81C\uB4E4\uC744 \uB2F4\uC744 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\uC785\uB2C8\uB2E4.
|
|
88
|
+
solving: ${solvingDir}
|
|
89
|
+
# \uD574\uACB0\uD55C \uBB38\uC81C\uB97C \uBCF4\uAD00\uD560 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\uC785\uB2C8\uB2E4.
|
|
90
|
+
archive: ${archiveDir}
|
|
91
|
+
# \uC544\uCE74\uC774\uBE59 \uC804\uB7B5\uC785\uB2C8\uB2E4 (flat, by-range, by-tier, by-tag).
|
|
92
|
+
archive_strategy: ${archiveStrategy}
|
|
93
|
+
|
|
94
|
+
archive:
|
|
95
|
+
# \uC544\uCE74\uC774\uBE0C \uC2DC \uC790\uB3D9\uC73C\uB85C Git \uCEE4\uBC0B\uC744 \uC218\uD589\uD560\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.
|
|
96
|
+
auto_commit: true
|
|
97
|
+
# Git \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uD15C\uD50C\uB9BF\uC785\uB2C8\uB2E4 ({id}, {title} \uC0AC\uC6A9 \uAC00\uB2A5).
|
|
98
|
+
commit_message: "feat: solve {id} {title}"
|
|
99
|
+
|
|
100
|
+
markdown:
|
|
101
|
+
# \uBB38\uC81C README\uC5D0 \uC54C\uACE0\uB9AC\uC998 \uBD84\uB958(\uD0DC\uADF8)\uB97C \uD3EC\uD568\uD560\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.
|
|
102
|
+
include_tag: ${includeTag}
|
|
103
|
+
|
|
104
|
+
# \uC5B8\uC5B4\uBCC4 \uC124\uC815
|
|
105
|
+
# \uC774\uACF3\uC5D0\uC11C \uCEF4\uD30C\uC77C/\uC2E4\uD589 \uBA85\uB839\uC5B4\uB098 \uD15C\uD50C\uB9BF \uD30C\uC77C\uBA85\uC744 \uC218\uC815\uD558\uAC70\uB098 \uC0C8\uB85C\uC6B4 \uC5B8\uC5B4\uB97C \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.
|
|
106
|
+
languages:
|
|
107
|
+
python:
|
|
108
|
+
extension: py
|
|
109
|
+
# \uD15C\uD50C\uB9BF \uD30C\uC77C\uBA85 (\uC635\uC158, \uAE30\uBCF8\uAC12: solution.py)
|
|
110
|
+
template_file: "solution.py"
|
|
111
|
+
# \uC2E4\uD589 \uBA85\uB839\uC5B4 (\uD544\uC218)
|
|
112
|
+
run: python3
|
|
113
|
+
cpp:
|
|
114
|
+
extension: cpp
|
|
115
|
+
# \uD15C\uD50C\uB9BF \uD30C\uC77C\uBA85 (\uC635\uC158, \uAE30\uBCF8\uAC12: solution.cpp)
|
|
116
|
+
template_file: "solution.cpp"
|
|
117
|
+
# \uCEF4\uD30C\uC77C \uBA85\uB839\uC5B4 (\uC635\uC158)
|
|
118
|
+
compile: "g++ -fdiagnostics-absolute-paths -o solution solution.cpp"
|
|
119
|
+
# \uC2E4\uD589 \uBA85\uB839\uC5B4 (\uD544\uC218)
|
|
120
|
+
run: "./solution"
|
|
121
|
+
# rust:
|
|
122
|
+
# extension: rs
|
|
123
|
+
# # \uD15C\uD50C\uB9BF \uD30C\uC77C\uBA85\uC744 \uC9C1\uC811 \uC9C0\uC815\uD558\uB824\uBA74 template_file\uC744 \uC0AC\uC6A9\uD558\uC138\uC694 (\uAE30\uBCF8: solution.{extension})
|
|
124
|
+
# template_file: "solution.rs"
|
|
125
|
+
# compile: "rustc {file}"
|
|
126
|
+
# run: "./{file_no_ext}"
|
|
127
|
+
`.trim();
|
|
128
|
+
}
|
|
34
129
|
function useInit({ onComplete }) {
|
|
35
130
|
const [currentStep, setCurrentStep] = useState("archive-dir");
|
|
36
131
|
const [completedSteps, setCompletedSteps] = useState([]);
|
|
37
132
|
const [confirmExit, setConfirmExit] = useState(false);
|
|
38
133
|
const [initialized, setInitialized] = useState(false);
|
|
39
|
-
const [
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
134
|
+
const [form, setForm] = useState({
|
|
135
|
+
archiveDir: getArchiveDir(),
|
|
136
|
+
solvingDir: getSolvingDir(),
|
|
137
|
+
archiveStrategy: getArchiveStrategy(),
|
|
138
|
+
language: getDefaultLanguage(),
|
|
139
|
+
editor: getEditor(),
|
|
140
|
+
autoOpen: getAutoOpenEditor(),
|
|
141
|
+
includeTag: getIncludeTag(),
|
|
142
|
+
handle: getSolvedAcHandle() || ""
|
|
143
|
+
});
|
|
47
144
|
const [handleInputMode, setHandleInputMode] = useState(false);
|
|
48
145
|
const [created, setCreated] = useState([]);
|
|
49
146
|
const [cancelled, setCancelled] = useState(false);
|
|
@@ -72,21 +169,17 @@ function useInit({ onComplete }) {
|
|
|
72
169
|
await access(projectConfigPath);
|
|
73
170
|
const configContent = await readFile(projectConfigPath, "utf-8");
|
|
74
171
|
const projectConfig = JSON.parse(configContent);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (projectConfig.includeTag !== void 0)
|
|
87
|
-
setIncludeTag(projectConfig.includeTag);
|
|
88
|
-
if (projectConfig.solvedAcHandle)
|
|
89
|
-
setHandle(projectConfig.solvedAcHandle);
|
|
172
|
+
setForm((prev) => ({
|
|
173
|
+
...prev,
|
|
174
|
+
archiveDir: projectConfig.archiveDir ?? prev.archiveDir,
|
|
175
|
+
solvingDir: projectConfig.solvingDir ?? prev.solvingDir,
|
|
176
|
+
archiveStrategy: projectConfig.archiveStrategy ?? prev.archiveStrategy,
|
|
177
|
+
language: projectConfig.defaultLanguage ?? prev.language,
|
|
178
|
+
editor: projectConfig.editor ?? prev.editor,
|
|
179
|
+
autoOpen: projectConfig.autoOpenEditor !== void 0 ? projectConfig.autoOpenEditor : prev.autoOpen,
|
|
180
|
+
includeTag: projectConfig.includeTag !== void 0 ? projectConfig.includeTag : prev.includeTag,
|
|
181
|
+
handle: projectConfig.solvedAcHandle ?? prev.handle
|
|
182
|
+
}));
|
|
90
183
|
} catch {
|
|
91
184
|
} finally {
|
|
92
185
|
setInitialized(true);
|
|
@@ -95,34 +188,28 @@ function useInit({ onComplete }) {
|
|
|
95
188
|
void loadProjectConfig();
|
|
96
189
|
}, []);
|
|
97
190
|
const getStepLabel = useCallback((step) => {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return "README\uC5D0 \uC54C\uACE0\uB9AC\uC998 \uBD84\uB958 \uD3EC\uD568";
|
|
113
|
-
case "handle":
|
|
114
|
-
return "Solved.ac \uD578\uB4E4 (\uC120\uD0DD)";
|
|
115
|
-
default:
|
|
116
|
-
return "";
|
|
117
|
-
}
|
|
191
|
+
const stepToConfigKey = {
|
|
192
|
+
"archive-dir": "paths.archive",
|
|
193
|
+
"solving-dir": "paths.solving",
|
|
194
|
+
"archive-strategy": "paths.archive-strategy",
|
|
195
|
+
language: "general.default-language",
|
|
196
|
+
editor: "editor.command",
|
|
197
|
+
"auto-open": "editor.auto-open",
|
|
198
|
+
"include-tag": "markdown.include-tag",
|
|
199
|
+
handle: "general.solved-ac-handle"
|
|
200
|
+
};
|
|
201
|
+
const configKey = stepToConfigKey[step];
|
|
202
|
+
if (!configKey) return "";
|
|
203
|
+
const meta = getConfigMetadata().find((m) => m.key === configKey);
|
|
204
|
+
return meta?.label ?? "";
|
|
118
205
|
}, []);
|
|
119
206
|
const getStepValue = useCallback(
|
|
120
207
|
(step) => {
|
|
121
208
|
switch (step) {
|
|
122
209
|
case "archive-dir":
|
|
123
|
-
return archiveDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : archiveDir;
|
|
210
|
+
return form.archiveDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : form.archiveDir;
|
|
124
211
|
case "solving-dir":
|
|
125
|
-
return solvingDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : solvingDir;
|
|
212
|
+
return form.solvingDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : form.solvingDir;
|
|
126
213
|
case "archive-strategy": {
|
|
127
214
|
const strategyLabels = {
|
|
128
215
|
flat: "\uD3C9\uBA74 (\uC804\uBD80 \uB098\uC5F4)",
|
|
@@ -130,62 +217,66 @@ function useInit({ onComplete }) {
|
|
|
130
217
|
"by-tier": "\uD2F0\uC5B4\uBCC4",
|
|
131
218
|
"by-tag": "\uD0DC\uADF8\uBCC4"
|
|
132
219
|
};
|
|
133
|
-
return strategyLabels[archiveStrategy] || archiveStrategy;
|
|
220
|
+
return strategyLabels[form.archiveStrategy] || form.archiveStrategy;
|
|
134
221
|
}
|
|
135
222
|
case "language":
|
|
136
|
-
return language;
|
|
223
|
+
return form.language;
|
|
137
224
|
case "editor":
|
|
138
|
-
return editor;
|
|
225
|
+
return form.editor;
|
|
139
226
|
case "auto-open":
|
|
140
|
-
return autoOpen ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
227
|
+
return form.autoOpen ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
141
228
|
case "include-tag":
|
|
142
|
-
return includeTag ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
229
|
+
return form.includeTag ? "\uC608" : "\uC544\uB2C8\uC624";
|
|
143
230
|
case "handle":
|
|
144
|
-
return handle || "(\uC2A4\uD0B5)";
|
|
231
|
+
return form.handle || "(\uC2A4\uD0B5)";
|
|
145
232
|
default:
|
|
146
233
|
return "";
|
|
147
234
|
}
|
|
148
235
|
},
|
|
149
|
-
[
|
|
150
|
-
archiveDir,
|
|
151
|
-
solvingDir,
|
|
152
|
-
language,
|
|
153
|
-
editor,
|
|
154
|
-
autoOpen,
|
|
155
|
-
includeTag,
|
|
156
|
-
handle,
|
|
157
|
-
archiveStrategy
|
|
158
|
-
]
|
|
236
|
+
[form]
|
|
159
237
|
);
|
|
160
238
|
const executeInit = useCallback(
|
|
161
239
|
async (overrideHandle) => {
|
|
162
240
|
try {
|
|
163
241
|
const cwd = process.cwd();
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
242
|
+
const cliRoot = getCliRoot();
|
|
243
|
+
const psCliDir = join(cwd, ".ps-cli");
|
|
244
|
+
const templatesDir = join(psCliDir, "templates");
|
|
245
|
+
await mkdir(psCliDir, { recursive: true });
|
|
246
|
+
await mkdir(templatesDir, { recursive: true });
|
|
247
|
+
setCreated((prev) => [...prev, ".ps-cli/"]);
|
|
248
|
+
const handleToUse = (overrideHandle ?? form.handle)?.trim() || "";
|
|
249
|
+
const configYaml = buildDefaultConfigYaml({
|
|
250
|
+
language: form.language,
|
|
251
|
+
editor: form.editor,
|
|
252
|
+
autoOpen: form.autoOpen,
|
|
253
|
+
solvingDir: form.solvingDir,
|
|
254
|
+
archiveDir: form.archiveDir,
|
|
255
|
+
archiveStrategy: form.archiveStrategy,
|
|
256
|
+
includeTag: form.includeTag,
|
|
257
|
+
handle: handleToUse
|
|
258
|
+
});
|
|
259
|
+
await writeFile(join(psCliDir, "config.yaml"), configYaml, "utf-8");
|
|
260
|
+
setCreated((prev) => [...prev, ".ps-cli/config.yaml"]);
|
|
261
|
+
const defaultTemplatesDir = join(cliRoot, "templates");
|
|
262
|
+
if (existsSync(defaultTemplatesDir)) {
|
|
263
|
+
const files = await readdir(defaultTemplatesDir);
|
|
264
|
+
for (const file of files) {
|
|
265
|
+
await copyFile(
|
|
266
|
+
join(defaultTemplatesDir, file),
|
|
267
|
+
join(templatesDir, file)
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
setCreated((prev) => [
|
|
271
|
+
...prev,
|
|
272
|
+
".ps-cli/templates/ (\uAE30\uBCF8 \uD15C\uD50C\uB9BF \uBCF5\uC0AC)"
|
|
273
|
+
]);
|
|
177
274
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
JSON.stringify(projectConfig, null, 2),
|
|
181
|
-
"utf-8"
|
|
182
|
-
);
|
|
183
|
-
setCreated((prev) => [...prev, ".ps-cli.json"]);
|
|
184
|
-
if (archiveDir !== "." && archiveDir !== "") {
|
|
185
|
-
const archiveDirPath = join(cwd, archiveDir);
|
|
275
|
+
if (form.archiveDir !== "." && form.archiveDir !== "") {
|
|
276
|
+
const archiveDirPath = join(cwd, form.archiveDir);
|
|
186
277
|
try {
|
|
187
278
|
await mkdir(archiveDirPath, { recursive: true });
|
|
188
|
-
setCreated((prev) => [...prev, `${archiveDir}/`]);
|
|
279
|
+
setCreated((prev) => [...prev, `${form.archiveDir}/`]);
|
|
189
280
|
} catch (err) {
|
|
190
281
|
const error = err;
|
|
191
282
|
if (error.code !== "EEXIST") {
|
|
@@ -193,11 +284,11 @@ function useInit({ onComplete }) {
|
|
|
193
284
|
}
|
|
194
285
|
}
|
|
195
286
|
}
|
|
196
|
-
if (solvingDir !== "." && solvingDir !== "") {
|
|
197
|
-
const solvingDirPath = join(cwd, solvingDir);
|
|
287
|
+
if (form.solvingDir !== "." && form.solvingDir !== "") {
|
|
288
|
+
const solvingDirPath = join(cwd, form.solvingDir);
|
|
198
289
|
try {
|
|
199
290
|
await mkdir(solvingDirPath, { recursive: true });
|
|
200
|
-
setCreated((prev) => [...prev, `${solvingDir}/`]);
|
|
291
|
+
setCreated((prev) => [...prev, `${form.solvingDir}/`]);
|
|
201
292
|
} catch (err) {
|
|
202
293
|
const error = err;
|
|
203
294
|
if (error.code !== "EEXIST") {
|
|
@@ -207,8 +298,8 @@ function useInit({ onComplete }) {
|
|
|
207
298
|
}
|
|
208
299
|
const gitignorePath = join(cwd, ".gitignore");
|
|
209
300
|
const gitignorePatterns = [];
|
|
210
|
-
if (solvingDir !== "." && solvingDir !== "") {
|
|
211
|
-
gitignorePatterns.push(`${solvingDir}/`);
|
|
301
|
+
if (form.solvingDir !== "." && form.solvingDir !== "") {
|
|
302
|
+
gitignorePatterns.push(`${form.solvingDir}/`);
|
|
212
303
|
}
|
|
213
304
|
if (gitignorePatterns.length > 0) {
|
|
214
305
|
try {
|
|
@@ -217,7 +308,8 @@ function useInit({ onComplete }) {
|
|
|
217
308
|
let hasChanges = false;
|
|
218
309
|
for (const pattern of gitignorePatterns) {
|
|
219
310
|
if (!gitignoreContent.includes(pattern)) {
|
|
220
|
-
updatedContent += (updatedContent ? "\n" : "") +
|
|
311
|
+
updatedContent += (updatedContent ? "\n" : "") + `
|
|
312
|
+
# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
|
|
221
313
|
${pattern}`;
|
|
222
314
|
hasChanges = true;
|
|
223
315
|
}
|
|
@@ -251,10 +343,9 @@ ${gitignorePatterns.join("\n")}
|
|
|
251
343
|
await execaCommand("git init", { cwd });
|
|
252
344
|
setCreated((prev) => [...prev, "Git \uC800\uC7A5\uC18C \uCD08\uAE30\uD654"]);
|
|
253
345
|
}
|
|
254
|
-
const filesToAdd = [".ps-cli
|
|
255
|
-
const gitignorePath2 = join(cwd, ".gitignore");
|
|
346
|
+
const filesToAdd = [".ps-cli"];
|
|
256
347
|
try {
|
|
257
|
-
await access(
|
|
348
|
+
await access(gitignorePath);
|
|
258
349
|
filesToAdd.push(".gitignore");
|
|
259
350
|
} catch {
|
|
260
351
|
}
|
|
@@ -288,17 +379,7 @@ ${gitignorePatterns.join("\n")}
|
|
|
288
379
|
}, 2e3);
|
|
289
380
|
}
|
|
290
381
|
},
|
|
291
|
-
[
|
|
292
|
-
archiveDir,
|
|
293
|
-
solvingDir,
|
|
294
|
-
archiveStrategy,
|
|
295
|
-
language,
|
|
296
|
-
editor,
|
|
297
|
-
autoOpen,
|
|
298
|
-
includeTag,
|
|
299
|
-
handle,
|
|
300
|
-
onComplete
|
|
301
|
-
]
|
|
382
|
+
[form, onComplete]
|
|
302
383
|
);
|
|
303
384
|
const moveToNextStep = useCallback(
|
|
304
385
|
(selectedValue, stepLabel, handleValue) => {
|
|
@@ -307,7 +388,10 @@ ${gitignorePatterns.join("\n")}
|
|
|
307
388
|
{ label: stepLabel, value: selectedValue }
|
|
308
389
|
]);
|
|
309
390
|
if (currentStep === "handle" && handleValue !== void 0) {
|
|
310
|
-
|
|
391
|
+
setForm((prev) => ({
|
|
392
|
+
...prev,
|
|
393
|
+
handle: handleValue
|
|
394
|
+
}));
|
|
311
395
|
}
|
|
312
396
|
const stepOrder = [
|
|
313
397
|
"archive-dir",
|
|
@@ -340,25 +424,11 @@ ${gitignorePatterns.join("\n")}
|
|
|
340
424
|
completedSteps,
|
|
341
425
|
confirmExit,
|
|
342
426
|
initialized,
|
|
343
|
-
|
|
344
|
-
solvingDir,
|
|
345
|
-
archiveStrategy,
|
|
346
|
-
language,
|
|
347
|
-
editor,
|
|
348
|
-
autoOpen,
|
|
349
|
-
includeTag,
|
|
350
|
-
handle,
|
|
427
|
+
form,
|
|
351
428
|
handleInputMode,
|
|
352
429
|
created,
|
|
353
430
|
cancelled,
|
|
354
|
-
|
|
355
|
-
setSolvingDirValue,
|
|
356
|
-
setArchiveStrategy,
|
|
357
|
-
setLanguage,
|
|
358
|
-
setEditorValue,
|
|
359
|
-
setAutoOpen,
|
|
360
|
-
setIncludeTag,
|
|
361
|
-
setHandle,
|
|
431
|
+
setForm,
|
|
362
432
|
setHandleInputMode,
|
|
363
433
|
setConfirmExit,
|
|
364
434
|
setCurrentStep,
|
|
@@ -369,22 +439,6 @@ ${gitignorePatterns.join("\n")}
|
|
|
369
439
|
};
|
|
370
440
|
}
|
|
371
441
|
|
|
372
|
-
// src/utils/version.ts
|
|
373
|
-
import { readFileSync } from "fs";
|
|
374
|
-
import { join as join2, dirname } from "path";
|
|
375
|
-
import { fileURLToPath } from "url";
|
|
376
|
-
function getVersion() {
|
|
377
|
-
try {
|
|
378
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
379
|
-
const __dirname = dirname(__filename);
|
|
380
|
-
const packageJsonPath = join2(__dirname, "../../package.json");
|
|
381
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
382
|
-
return packageJson.version;
|
|
383
|
-
} catch {
|
|
384
|
-
return "";
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
442
|
// src/commands/init.tsx
|
|
389
443
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
390
444
|
function InitView({ onComplete }) {
|
|
@@ -393,17 +447,13 @@ function InitView({ onComplete }) {
|
|
|
393
447
|
completedSteps,
|
|
394
448
|
confirmExit,
|
|
395
449
|
initialized,
|
|
450
|
+
// form은 현재 단계 값 표시 등 확장용으로 남겨두되
|
|
451
|
+
// 아직 직접 사용하지 않으므로 린트 예외 패턴에 맞춰 _ 접두사를 사용한다.
|
|
452
|
+
form: _form,
|
|
396
453
|
handleInputMode,
|
|
397
454
|
created,
|
|
398
455
|
cancelled,
|
|
399
|
-
|
|
400
|
-
setSolvingDirValue,
|
|
401
|
-
setArchiveStrategy,
|
|
402
|
-
setLanguage,
|
|
403
|
-
setEditorValue,
|
|
404
|
-
setAutoOpen,
|
|
405
|
-
setIncludeTag,
|
|
406
|
-
setHandle,
|
|
456
|
+
setForm,
|
|
407
457
|
setHandleInputMode,
|
|
408
458
|
setConfirmExit,
|
|
409
459
|
setCurrentStep,
|
|
@@ -456,7 +506,7 @@ function InitView({ onComplete }) {
|
|
|
456
506
|
{
|
|
457
507
|
options,
|
|
458
508
|
onChange: (value) => {
|
|
459
|
-
|
|
509
|
+
setForm((prev) => ({ ...prev, archiveDir: value }));
|
|
460
510
|
const displayValue = value === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : value;
|
|
461
511
|
moveToNextStep(displayValue, getStepLabel(currentStep));
|
|
462
512
|
}
|
|
@@ -476,7 +526,7 @@ function InitView({ onComplete }) {
|
|
|
476
526
|
{
|
|
477
527
|
options,
|
|
478
528
|
onChange: (value) => {
|
|
479
|
-
|
|
529
|
+
setForm((prev) => ({ ...prev, solvingDir: value }));
|
|
480
530
|
const displayValue = value === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : value;
|
|
481
531
|
moveToNextStep(displayValue, getStepLabel(currentStep));
|
|
482
532
|
}
|
|
@@ -498,7 +548,7 @@ function InitView({ onComplete }) {
|
|
|
498
548
|
{
|
|
499
549
|
options,
|
|
500
550
|
onChange: (value) => {
|
|
501
|
-
|
|
551
|
+
setForm((prev) => ({ ...prev, archiveStrategy: value }));
|
|
502
552
|
const strategyLabels = {
|
|
503
553
|
flat: "\uD3C9\uBA74 (\uC804\uBD80 \uB098\uC5F4)",
|
|
504
554
|
"by-range": "1000\uBC88\uB300 \uBB36\uAE30",
|
|
@@ -527,7 +577,7 @@ function InitView({ onComplete }) {
|
|
|
527
577
|
{
|
|
528
578
|
options,
|
|
529
579
|
onChange: (value) => {
|
|
530
|
-
|
|
580
|
+
setForm((prev) => ({ ...prev, language: value }));
|
|
531
581
|
moveToNextStep(value, getStepLabel(currentStep));
|
|
532
582
|
}
|
|
533
583
|
}
|
|
@@ -548,7 +598,7 @@ function InitView({ onComplete }) {
|
|
|
548
598
|
{
|
|
549
599
|
options,
|
|
550
600
|
onChange: (value) => {
|
|
551
|
-
|
|
601
|
+
setForm((prev) => ({ ...prev, editor: value }));
|
|
552
602
|
moveToNextStep(value, getStepLabel(currentStep));
|
|
553
603
|
}
|
|
554
604
|
}
|
|
@@ -567,7 +617,7 @@ function InitView({ onComplete }) {
|
|
|
567
617
|
{
|
|
568
618
|
options,
|
|
569
619
|
onChange: (value) => {
|
|
570
|
-
|
|
620
|
+
setForm((prev) => ({ ...prev, autoOpen: value === "true" }));
|
|
571
621
|
moveToNextStep(
|
|
572
622
|
value === "true" ? "\uC608" : "\uC544\uB2C8\uC624",
|
|
573
623
|
getStepLabel(currentStep)
|
|
@@ -589,7 +639,7 @@ function InitView({ onComplete }) {
|
|
|
589
639
|
{
|
|
590
640
|
options,
|
|
591
641
|
onChange: (value) => {
|
|
592
|
-
|
|
642
|
+
setForm((prev) => ({ ...prev, includeTag: value === "true" }));
|
|
593
643
|
moveToNextStep(
|
|
594
644
|
value === "true" ? "\uC608" : "\uC544\uB2C8\uC624",
|
|
595
645
|
getStepLabel(currentStep)
|
|
@@ -609,7 +659,7 @@ function InitView({ onComplete }) {
|
|
|
609
659
|
placeholder: "\uD578\uB4E4 \uC785\uB825",
|
|
610
660
|
onSubmit: (value) => {
|
|
611
661
|
const handleValue = value.trim();
|
|
612
|
-
|
|
662
|
+
setForm((prev) => ({ ...prev, handle: handleValue }));
|
|
613
663
|
setHandleInputMode(false);
|
|
614
664
|
moveToNextStep(
|
|
615
665
|
handleValue || "(\uC2A4\uD0B5)",
|
|
@@ -633,7 +683,7 @@ function InitView({ onComplete }) {
|
|
|
633
683
|
options,
|
|
634
684
|
onChange: (value) => {
|
|
635
685
|
if (value === "skip") {
|
|
636
|
-
|
|
686
|
+
setForm((prev) => ({ ...prev, handle: "" }));
|
|
637
687
|
moveToNextStep("(\uC2A4\uD0B5)", getStepLabel(currentStep));
|
|
638
688
|
} else {
|
|
639
689
|
setHandleInputMode(true);
|
package/dist/commands/open.js
CHANGED
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-GV265WOR.js";
|
|
5
5
|
import {
|
|
6
6
|
Command,
|
|
7
7
|
CommandBuilder,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
icons,
|
|
14
14
|
resolveLanguage,
|
|
15
15
|
resolveProblemContext
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-AHE4QHJD.js";
|
|
17
17
|
|
|
18
18
|
// src/commands/run.tsx
|
|
19
19
|
import { join } from "path";
|
package/dist/commands/search.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SubmitView
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-NYMNFORB.js";
|
|
5
5
|
import {
|
|
6
6
|
TestView
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-CUSSKX2F.js";
|
|
8
8
|
import {
|
|
9
9
|
ArchiveView
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-HCUVCES6.js";
|
|
11
11
|
import {
|
|
12
12
|
FetchView
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-XUDGIZ2U.js";
|
|
14
14
|
import {
|
|
15
15
|
fetchWithRetry,
|
|
16
16
|
getProblem,
|
|
17
17
|
searchProblems
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-S7IL7OXF.js";
|
|
19
19
|
import {
|
|
20
20
|
OpenView
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-7DZDLCGW.js";
|
|
22
22
|
import "../chunk-QGMWUOJ3.js";
|
|
23
|
-
import "../chunk-
|
|
23
|
+
import "../chunk-GV265WOR.js";
|
|
24
24
|
import {
|
|
25
25
|
Command,
|
|
26
26
|
CommandBuilder,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
logger,
|
|
38
38
|
resolveLanguage,
|
|
39
39
|
source_default
|
|
40
|
-
} from "../chunk-
|
|
40
|
+
} from "../chunk-AHE4QHJD.js";
|
|
41
41
|
|
|
42
42
|
// src/commands/search.tsx
|
|
43
43
|
import { existsSync } from "fs";
|
package/dist/commands/stats.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getUserTagRatings,
|
|
6
6
|
getUserTop100,
|
|
7
7
|
scrapeUserStats
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-S7IL7OXF.js";
|
|
9
9
|
import {
|
|
10
10
|
Command,
|
|
11
11
|
CommandBuilder,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
icons,
|
|
26
26
|
logger,
|
|
27
27
|
source_default
|
|
28
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-AHE4QHJD.js";
|
|
29
29
|
|
|
30
30
|
// src/commands/stats.tsx
|
|
31
31
|
import { Alert, Spinner } from "@inkjs/ui";
|
package/dist/commands/submit.js
CHANGED
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
SubmitCommand,
|
|
4
4
|
SubmitView,
|
|
5
5
|
submit_default
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-NYMNFORB.js";
|
|
7
7
|
import "../chunk-QGMWUOJ3.js";
|
|
8
|
-
import "../chunk-
|
|
8
|
+
import "../chunk-AHE4QHJD.js";
|
|
9
9
|
export {
|
|
10
10
|
SubmitCommand,
|
|
11
11
|
SubmitView,
|