@rhseung/ps-cli 1.4.0 → 1.6.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.
@@ -7,8 +7,9 @@ import {
7
7
  getDefaultLanguage,
8
8
  getEditor,
9
9
  getProblemDir,
10
- getSolvedAcHandle
11
- } from "../chunk-7SVCS23X.js";
10
+ getSolvedAcHandle,
11
+ getSolvingDir
12
+ } from "../chunk-RVD22OUQ.js";
12
13
  import {
13
14
  __decorateClass,
14
15
  getSupportedLanguages
@@ -35,6 +36,7 @@ function useInit({ onComplete }) {
35
36
  const [confirmExit, setConfirmExit] = useState(false);
36
37
  const [initialized, setInitialized] = useState(false);
37
38
  const [problemDir, setProblemDirValue] = useState(getProblemDir());
39
+ const [solvingDir, setSolvingDirValue] = useState(getSolvingDir());
38
40
  const [language, setLanguage] = useState(getDefaultLanguage());
39
41
  const [editor, setEditorValue] = useState(getEditor());
40
42
  const [autoOpen, setAutoOpen] = useState(getAutoOpenEditor());
@@ -69,6 +71,8 @@ function useInit({ onComplete }) {
69
71
  const projectConfig = JSON.parse(configContent);
70
72
  if (projectConfig.problemDir)
71
73
  setProblemDirValue(projectConfig.problemDir);
74
+ if (projectConfig.solvingDir)
75
+ setSolvingDirValue(projectConfig.solvingDir);
72
76
  if (projectConfig.defaultLanguage)
73
77
  setLanguage(projectConfig.defaultLanguage);
74
78
  if (projectConfig.editor) setEditorValue(projectConfig.editor);
@@ -86,7 +90,9 @@ function useInit({ onComplete }) {
86
90
  const getStepLabel = useCallback((step) => {
87
91
  switch (step) {
88
92
  case "problem-dir":
89
- return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uC124\uC815";
93
+ return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uC544\uCE74\uC774\uBE0C\uB41C \uBB38\uC81C)";
94
+ case "solving-dir":
95
+ return "Solving \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uD478\uB294 \uC911\uC778 \uBB38\uC81C)";
90
96
  case "language":
91
97
  return "\uAE30\uBCF8 \uC5B8\uC5B4 \uC124\uC815";
92
98
  case "editor":
@@ -104,6 +110,8 @@ function useInit({ onComplete }) {
104
110
  switch (step) {
105
111
  case "problem-dir":
106
112
  return problemDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : problemDir;
113
+ case "solving-dir":
114
+ return solvingDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : solvingDir;
107
115
  case "language":
108
116
  return language;
109
117
  case "editor":
@@ -116,7 +124,7 @@ function useInit({ onComplete }) {
116
124
  return "";
117
125
  }
118
126
  },
119
- [problemDir, language, editor, autoOpen, handle]
127
+ [problemDir, solvingDir, language, editor, autoOpen, handle]
120
128
  );
121
129
  const executeInit = useCallback(async () => {
122
130
  try {
@@ -124,6 +132,7 @@ function useInit({ onComplete }) {
124
132
  const projectConfigPath = join(cwd, ".ps-cli.json");
125
133
  const projectConfig = {
126
134
  problemDir,
135
+ solvingDir,
127
136
  defaultLanguage: language,
128
137
  editor,
129
138
  autoOpenEditor: autoOpen,
@@ -146,28 +155,50 @@ function useInit({ onComplete }) {
146
155
  throw err;
147
156
  }
148
157
  }
149
- const gitignorePath = join(cwd, ".gitignore");
150
- const gitignorePattern = `${problemDir}/`;
158
+ }
159
+ if (solvingDir !== "." && solvingDir !== "") {
160
+ const solvingDirPath = join(cwd, solvingDir);
161
+ try {
162
+ await mkdir(solvingDirPath, { recursive: true });
163
+ setCreated((prev) => [...prev, `${solvingDir}/`]);
164
+ } catch (err) {
165
+ const error = err;
166
+ if (error.code !== "EEXIST") {
167
+ throw err;
168
+ }
169
+ }
170
+ }
171
+ const gitignorePath = join(cwd, ".gitignore");
172
+ const gitignorePatterns = [];
173
+ if (problemDir !== "." && problemDir !== "") {
174
+ gitignorePatterns.push(`${problemDir}/`);
175
+ }
176
+ if (solvingDir !== "." && solvingDir !== "") {
177
+ gitignorePatterns.push(`${solvingDir}/`);
178
+ }
179
+ if (gitignorePatterns.length > 0) {
151
180
  try {
152
181
  const gitignoreContent = await readFile(gitignorePath, "utf-8");
153
- if (!gitignoreContent.includes(gitignorePattern)) {
154
- const updatedContent = gitignoreContent.trim() + (gitignoreContent.trim() ? "\n" : "") + `
155
- # ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
156
- ${gitignorePattern}
157
- `;
158
- await writeFile(gitignorePath, updatedContent, "utf-8");
182
+ let updatedContent = gitignoreContent.trim();
183
+ let hasChanges = false;
184
+ for (const pattern of gitignorePatterns) {
185
+ if (!gitignoreContent.includes(pattern)) {
186
+ updatedContent += (updatedContent ? "\n" : "") + `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
187
+ ${pattern}`;
188
+ hasChanges = true;
189
+ }
190
+ }
191
+ if (hasChanges) {
192
+ await writeFile(gitignorePath, updatedContent + "\n", "utf-8");
159
193
  setCreated((prev) => [...prev, ".gitignore \uC5C5\uB370\uC774\uD2B8"]);
160
194
  }
161
195
  } catch (err) {
162
196
  const error = err;
163
197
  if (error.code === "ENOENT") {
164
- await writeFile(
165
- gitignorePath,
166
- `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
167
- ${gitignorePattern}
168
- `,
169
- "utf-8"
170
- );
198
+ const content = `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
199
+ ${gitignorePatterns.join("\n")}
200
+ `;
201
+ await writeFile(gitignorePath, content, "utf-8");
171
202
  setCreated((prev) => [...prev, ".gitignore \uC0DD\uC131"]);
172
203
  } else {
173
204
  console.warn(".gitignore \uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328:", error.message);
@@ -187,9 +218,9 @@ ${gitignorePattern}
187
218
  setCreated((prev) => [...prev, "Git \uC800\uC7A5\uC18C \uCD08\uAE30\uD654"]);
188
219
  }
189
220
  const filesToAdd = [".ps-cli.json"];
190
- const gitignorePath = join(cwd, ".gitignore");
221
+ const gitignorePath2 = join(cwd, ".gitignore");
191
222
  try {
192
- await access(gitignorePath);
223
+ await access(gitignorePath2);
193
224
  filesToAdd.push(".gitignore");
194
225
  } catch {
195
226
  }
@@ -222,7 +253,7 @@ ${gitignorePattern}
222
253
  onComplete();
223
254
  }, 2e3);
224
255
  }
225
- }, [problemDir, language, editor, autoOpen, handle, onComplete]);
256
+ }, [problemDir, solvingDir, language, editor, autoOpen, handle, onComplete]);
226
257
  const moveToNextStep = useCallback(
227
258
  (selectedValue, stepLabel) => {
228
259
  setCompletedSteps((prev) => [
@@ -231,6 +262,7 @@ ${gitignorePattern}
231
262
  ]);
232
263
  const stepOrder = [
233
264
  "problem-dir",
265
+ "solving-dir",
234
266
  "language",
235
267
  "editor",
236
268
  "auto-open",
@@ -254,6 +286,7 @@ ${gitignorePattern}
254
286
  confirmExit,
255
287
  initialized,
256
288
  problemDir,
289
+ solvingDir,
257
290
  language,
258
291
  editor,
259
292
  autoOpen,
@@ -262,6 +295,7 @@ ${gitignorePattern}
262
295
  created,
263
296
  cancelled,
264
297
  setProblemDirValue,
298
+ setSolvingDirValue,
265
299
  setLanguage,
266
300
  setEditorValue,
267
301
  setAutoOpen,
@@ -288,6 +322,7 @@ function InitView({ onComplete }) {
288
322
  created,
289
323
  cancelled,
290
324
  setProblemDirValue,
325
+ setSolvingDirValue,
291
326
  setLanguage,
292
327
  setEditorValue,
293
328
  setAutoOpen,
@@ -352,6 +387,26 @@ function InitView({ onComplete }) {
352
387
  )
353
388
  );
354
389
  }
390
+ case "solving-dir": {
391
+ const options = [
392
+ { label: "solving", value: "solving" },
393
+ { label: ". (\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8)", value: "." }
394
+ ];
395
+ return renderQuestionCard(
396
+ getStepLabel(currentStep),
397
+ /* @__PURE__ */ jsx(
398
+ Select,
399
+ {
400
+ options,
401
+ onChange: (value) => {
402
+ setSolvingDirValue(value);
403
+ const displayValue = value === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : value;
404
+ moveToNextStep(displayValue, getStepLabel(currentStep));
405
+ }
406
+ }
407
+ )
408
+ );
409
+ }
355
410
  case "language": {
356
411
  const supportedLanguages = getSupportedLanguages();
357
412
  const options = supportedLanguages.map((lang) => ({
@@ -1,14 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- openBrowser
4
- } from "../chunk-QGMWUOJ3.js";
3
+ useOpenBrowser
4
+ } from "../chunk-GCOFFYJ3.js";
5
+ import "../chunk-QGMWUOJ3.js";
5
6
  import {
6
7
  Command,
7
8
  CommandBuilder,
8
9
  CommandDef,
9
10
  getProblemId,
10
11
  resolveProblemContext
11
- } from "../chunk-7SVCS23X.js";
12
+ } from "../chunk-RVD22OUQ.js";
12
13
  import {
13
14
  __decorateClass
14
15
  } from "../chunk-7MQMPJ3X.js";
@@ -17,47 +18,6 @@ import {
17
18
  import { StatusMessage, Alert } from "@inkjs/ui";
18
19
  import { Spinner } from "@inkjs/ui";
19
20
  import { Text, Box } from "ink";
20
-
21
- // src/hooks/use-open-browser.ts
22
- import { useEffect, useState } from "react";
23
- var BOJ_BASE_URL = "https://www.acmicpc.net";
24
- function useOpenBrowser({
25
- problemId,
26
- onComplete
27
- }) {
28
- const [status, setStatus] = useState(
29
- "loading"
30
- );
31
- const [error, setError] = useState(null);
32
- const [url, setUrl] = useState("");
33
- useEffect(() => {
34
- async function handleOpenBrowser() {
35
- try {
36
- const problemUrl = `${BOJ_BASE_URL}/problem/${problemId}`;
37
- setUrl(problemUrl);
38
- await openBrowser(problemUrl);
39
- setStatus("success");
40
- setTimeout(() => {
41
- onComplete?.();
42
- }, 1500);
43
- } catch (err) {
44
- setStatus("error");
45
- setError(err instanceof Error ? err.message : String(err));
46
- setTimeout(() => {
47
- onComplete?.();
48
- }, 2e3);
49
- }
50
- }
51
- void handleOpenBrowser();
52
- }, [problemId, onComplete]);
53
- return {
54
- status,
55
- error,
56
- url
57
- };
58
- }
59
-
60
- // src/commands/open.tsx
61
21
  import { jsx, jsxs } from "react/jsx-runtime";
62
22
  function OpenView({ problemId, onComplete }) {
63
23
  const { status, error, url } = useOpenBrowser({
@@ -9,7 +9,7 @@ import {
9
9
  getProblemId,
10
10
  resolveLanguage,
11
11
  resolveProblemContext
12
- } from "../chunk-7SVCS23X.js";
12
+ } from "../chunk-RVD22OUQ.js";
13
13
  import {
14
14
  __decorateClass,
15
15
  getSupportedLanguagesString