project-auto-wizard 0.1.9 → 0.1.10
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 +1 -1
- package/package.json +1 -1
- package/src/commands/full.js +10 -5
- package/src/commands/interactive.js +1 -0
- package/src/commands/purge.js +1 -1
- package/src/commands/version.js +3 -4
- package/src/core/copy/gitignore.js +14 -7
- package/src/core/copy/workflows.js +4 -3
- package/src/index.js +1 -0
- package/src/ui/summary.js +2 -3
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ npx project-auto-wizard
|
|
|
16
16
|
[](package.json)
|
|
17
17
|
|
|
18
18
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
19
|
-
## 최신 버전 : v0.1.
|
|
19
|
+
## 최신 버전 : v0.1.10 (2026-08-02)
|
|
20
20
|
|
|
21
21
|
[전체 버전 기록 보기](CHANGELOG.md)
|
|
22
22
|
|
package/package.json
CHANGED
package/src/commands/full.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// full 모드 오케스트레이터 (.sh execute_integration full case 등가).
|
|
2
|
-
// 복사 순서: workflows(+env 치환) → version.yml → readme → scripts → coderabbit → gitignore
|
|
2
|
+
// 복사 순서: workflows(+env 치환) → version.yml → readme → scripts → coderabbit → gitignore(조건부)
|
|
3
|
+
// gitignore는 충돌 백업 부산물(.bak/.template.yaml)이 이번 실행에서 실제로 생겼을 때만 갱신한다 — issue #7.
|
|
3
4
|
// (원본의 util/issue/discussion/setup-guide/config 설치는 project-auto-wizard 스코프에서 제외 — DESIGN-SPEC §2)
|
|
4
5
|
import { join } from "node:path";
|
|
5
6
|
import { writeText } from "../core/fsutil.js";
|
|
@@ -46,9 +47,13 @@ export function runFull(context, payloadRoot, targetRoot = ".", hooks = {}) {
|
|
|
46
47
|
// 4. scripts (payload/scripts/*.py → .github/scripts/)
|
|
47
48
|
copyScripts(payloadRoot, targetRoot);
|
|
48
49
|
|
|
49
|
-
// 5. coderabbit (opt-in true일 때만 — DESIGN-SPEC §4 질문②)
|
|
50
|
-
|
|
51
|
-
ensureGitignore(targetRoot);
|
|
50
|
+
// 5. coderabbit (opt-in true일 때만 — DESIGN-SPEC §4 질문②)
|
|
51
|
+
const coderabbitResult = includeCodeRabbit === true ? copyCoderabbit(payloadRoot, { force }, targetRoot) : null;
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
// 6. gitignore — 워크플로우/coderabbit 충돌 처리가 .bak나 .template.yaml을 실제로 만든 경우에만 갱신한다.
|
|
54
|
+
// 충돌 없는 설치(대부분의 최초 설치)는 .gitignore를 전혀 건드리지 않는다 — issue #7.
|
|
55
|
+
const gitignoreUpdated = wfCounters.backupAdded > 0 || wfCounters.templateAdded > 0 || coderabbitResult === "overwritten-backup";
|
|
56
|
+
if (gitignoreUpdated) ensureGitignore(targetRoot);
|
|
57
|
+
|
|
58
|
+
return { workflows: wfCounters, gitignoreUpdated };
|
|
54
59
|
}
|
|
@@ -249,6 +249,7 @@ export async function runInteractive(baseCtx, { cwd = process.cwd(), payloadRoot
|
|
|
249
249
|
io.summary?.({
|
|
250
250
|
mode, types, version, branches, includeCodeRabbit,
|
|
251
251
|
counters: { workflows: result?.workflows?.copied ?? 0 },
|
|
252
|
+
gitignoreUpdated: result?.gitignoreUpdated === true,
|
|
252
253
|
}, cwd);
|
|
253
254
|
io.outro?.(`통합 완료 — ${mode} 모드로 설치했습니다.`);
|
|
254
255
|
return 0;
|
package/src/commands/purge.js
CHANGED
|
@@ -80,7 +80,7 @@ export function printPurgeResult(result) {
|
|
|
80
80
|
if (result.versionYml) lines.push("파일: version.yml");
|
|
81
81
|
if (result.readmeSection) lines.push("README.md: AUTO-VERSION-SECTION 블록");
|
|
82
82
|
for (const f of result.changelog) lines.push(`파일: ${f}`);
|
|
83
|
-
lines.push("(.gitignore
|
|
83
|
+
lines.push("(.gitignore에 추가된 백업 파일 제외 항목(*.bak/*.template.yaml)은 purge 대상에서 제외되어 그대로 보존됩니다)");
|
|
84
84
|
lines.push("");
|
|
85
85
|
console.log(lines.join("\n"));
|
|
86
86
|
}
|
package/src/commands/version.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// version 모드 (.sh execute_integration version case 등가).
|
|
2
|
-
// 순서: version.yml → readme → scripts
|
|
3
|
-
// (
|
|
2
|
+
// 순서: version.yml → readme → scripts.
|
|
3
|
+
// (워크플로우/coderabbit을 복사하지 않으므로 충돌 백업 부산물이 생길 수 없다 — gitignore 갱신 대상 없음, issue #7.
|
|
4
|
+
// util·issue·coderabbit·setup-guide는 스코프 제외.)
|
|
4
5
|
import { join } from "node:path";
|
|
5
6
|
import { writeText } from "../core/fsutil.js";
|
|
6
7
|
import { PATHS } from "../core/paths.js";
|
|
@@ -9,7 +10,6 @@ import { readVersionYmlTemplate } from "../core/assets.js";
|
|
|
9
10
|
import { markerForType } from "../core/detect.js";
|
|
10
11
|
import { addVersionSectionToReadme } from "../core/copy/readme.js";
|
|
11
12
|
import { copyScripts } from "../core/copy/simple.js";
|
|
12
|
-
import { ensureGitignore } from "../core/copy/gitignore.js";
|
|
13
13
|
|
|
14
14
|
export function runVersion(context, payloadRoot, targetRoot = ".") {
|
|
15
15
|
const { version, types = [], paths = new Map(), branch = "main", versionCode = 1,
|
|
@@ -28,5 +28,4 @@ export function runVersion(context, payloadRoot, targetRoot = ".") {
|
|
|
28
28
|
}));
|
|
29
29
|
addVersionSectionToReadme(version, targetRoot);
|
|
30
30
|
copyScripts(payloadRoot, targetRoot);
|
|
31
|
-
ensureGitignore(targetRoot);
|
|
32
31
|
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
// .gitignore 보장
|
|
1
|
+
// .gitignore 보장 — 마법사 자신이 만드는 충돌 백업 부산물(*.bak, *.template.yaml)만 대상으로 한다.
|
|
2
|
+
// 마법사가 설치하는 것과 무관한 개인 개발환경 설정(IDE 등)은 마법사 책임 범위 밖 — issue #7.
|
|
3
|
+
// 주의(의도된 트레이드오프): 이 변경 이전 버전으로 설치해 /.idea·/.claude/settings.local.json이 이미
|
|
4
|
+
// 배너 블록에 남아있는 레포에서 removeAutoAddedEntriesFromGitignore()를 실행하면, 배너는 제거되지만
|
|
5
|
+
// REQUIRED_ENTRIES가 더 이상 옛 항목과 일치하지 않아 그 두 줄은 지워지지 않고 배너 표시 없이 남는다.
|
|
6
|
+
// 이슈 #7이 "이미 설치된 레포의 .gitignore는 소급 처리하지 않고 사용자 판단에 맡긴다"고 명시하므로
|
|
7
|
+
// 별도 마이그레이션 로직을 추가하지 않는다 — 남은 항목은 무해하며 필요하면 사용자가 직접 지운다.
|
|
2
8
|
import { join } from "node:path";
|
|
3
9
|
import { existsSync, readFileSync, writeFileSync, rmSync } from "node:fs";
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
// issue #7: 마법사가 설치하는 것과 무관한 개인 개발환경 항목(/.idea 등)은 마법사 책임 밖이므로 제거.
|
|
12
|
+
// 대신 마법사 자신의 충돌 처리(workflows.js backup/template 결정, coderabbit.js 덮어쓰기 백업)가
|
|
13
|
+
// 실제로 만들어내는 부산물만 gitignore 대상으로 삼는다.
|
|
14
|
+
const REQUIRED_ENTRIES = ["*.bak", "*.template.yaml"];
|
|
6
15
|
|
|
7
16
|
// .sh normalize_gitignore_entry: 주석 제거·트림·앞 / 제거·앞 ./ 제거·뒤 / 제거. 빈값이면 원본.
|
|
8
17
|
export function normalizeGitignoreEntry(entry) {
|
|
@@ -26,11 +35,9 @@ function entryExists(target, content) {
|
|
|
26
35
|
}
|
|
27
36
|
|
|
28
37
|
const NEW_FILE_CONTENT =
|
|
29
|
-
"#
|
|
30
|
-
"
|
|
31
|
-
"\n"
|
|
32
|
-
"# Claude AI Settings\n" +
|
|
33
|
-
"/.claude/settings.local.json\n";
|
|
38
|
+
"# project-auto-wizard: 충돌 처리 시 생성되는 백업 파일 (안전하게 무시해도 됩니다)\n" +
|
|
39
|
+
"*.bak\n" +
|
|
40
|
+
"*.template.yaml\n";
|
|
34
41
|
|
|
35
42
|
// 반환: {created, added:[...]}
|
|
36
43
|
export function ensureGitignore(targetRoot = ".") {
|
|
@@ -58,7 +58,7 @@ function classify(srcDir, workflowsDir, envOpts, srcText) {
|
|
|
58
58
|
// envValues?:Map<key,value>, envUseDefaults?:boolean } ← env 계획(promptEnvPlan) 결과 주입점
|
|
59
59
|
// hooks: { decisions?: Map<filename, 'skip'|'backup'|'template'> } — 기존 파일(changed) 충돌 결정.
|
|
60
60
|
// 미지정 파일은 'skip'(현행 force 동작 100% 유지). 대화형 수집은 copyWorkflowsInteractive 참조.
|
|
61
|
-
// 반환: {copied, skipped, templateAdded, optionalCopied}
|
|
61
|
+
// 반환: {copied, skipped, templateAdded, optionalCopied, backupAdded}
|
|
62
62
|
export function copyWorkflows(context, payloadRoot, targetRoot = ".", hooks = {}) {
|
|
63
63
|
const { types = [], paths = new Map(), includeNexus = false, includeSecretBackup = false, repoName = "", resolvers = {}, envValues = new Map(), envUseDefaults = true } = context;
|
|
64
64
|
const decisions = hooks.decisions instanceof Map ? hooks.decisions : new Map();
|
|
@@ -66,7 +66,7 @@ export function copyWorkflows(context, payloadRoot, targetRoot = ".", hooks = {}
|
|
|
66
66
|
const projectTypesDir = join(payloadRoot, PAYLOAD.workflowsDir);
|
|
67
67
|
if (!exists(projectTypesDir)) throw new Error("패키지 구조 오류 — payload/workflows 폴더를 찾지 못했습니다.");
|
|
68
68
|
|
|
69
|
-
const counters = { copied: 0, skipped: 0, templateAdded: 0, optionalCopied: 0 };
|
|
69
|
+
const counters = { copied: 0, skipped: 0, templateAdded: 0, optionalCopied: 0, backupAdded: 0 };
|
|
70
70
|
const deployValues = new Map(); // Map<type, Map<key,value>> — deploy 블록용 ask 값
|
|
71
71
|
counters.deployValues = deployValues;
|
|
72
72
|
const srcText = makeSrcText(context.branches || null);
|
|
@@ -124,6 +124,7 @@ function applyDecision(decision, srcDir, workflowsDir, filename, counters, srcTe
|
|
|
124
124
|
renameSync(dst, dst + ".bak");
|
|
125
125
|
writeText(dst, srcText(src));
|
|
126
126
|
counters.copied++;
|
|
127
|
+
counters.backupAdded++;
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
129
130
|
if (decision === "template") {
|
|
@@ -213,7 +214,7 @@ function copyWorkflowsForType(type, projectTypesDir, workflowsDir, ctx, counters
|
|
|
213
214
|
counters.skipped++;
|
|
214
215
|
continue;
|
|
215
216
|
}
|
|
216
|
-
if (existsSync(dst)) renameSync(dst, dst + ".bak");
|
|
217
|
+
if (existsSync(dst)) { renameSync(dst, dst + ".bak"); counters.backupAdded++; }
|
|
217
218
|
writeText(dst, body);
|
|
218
219
|
counters.optionalCopied++;
|
|
219
220
|
counters.copied++;
|
package/src/index.js
CHANGED
|
@@ -311,6 +311,7 @@ export async function run(argv, {
|
|
|
311
311
|
mode: opts.mode, types, version, branches,
|
|
312
312
|
includeCodeRabbit: context.includeCodeRabbit === true,
|
|
313
313
|
counters: { workflows: result?.workflows?.copied ?? 0 },
|
|
314
|
+
gitignoreUpdated: result?.gitignoreUpdated === true,
|
|
314
315
|
}, cwd);
|
|
315
316
|
return 0;
|
|
316
317
|
}
|
package/src/ui/summary.js
CHANGED
|
@@ -8,7 +8,7 @@ import { listYamlFiles } from "../core/fsutil.js";
|
|
|
8
8
|
const SEPARATOR = "────────────────────────────────────────";
|
|
9
9
|
|
|
10
10
|
export function printSummary(ctx, targetRoot = ".") {
|
|
11
|
-
const { mode, types = [], version = "", counters = {}, branches = null, includeCodeRabbit = false } = ctx || {};
|
|
11
|
+
const { mode, types = [], version = "", counters = {}, branches = null, includeCodeRabbit = false, gitignoreUpdated = false } = ctx || {};
|
|
12
12
|
const err = (s = "") => process.stderr.write(`${s}\n`);
|
|
13
13
|
// 색상은 TTY일 때만 (.sh YELLOW/CYAN/NC 등가)
|
|
14
14
|
const isTty = !!process.stderr.isTTY;
|
|
@@ -32,12 +32,11 @@ export function printSummary(ctx, targetRoot = ".") {
|
|
|
32
32
|
err(" ✅ 버전 관리 시스템 (version.yml)");
|
|
33
33
|
err(" ✅ README.md 자동 버전 업데이트");
|
|
34
34
|
err(" ✅ GitHub Actions 워크플로우 (AI 릴리스 자동화 포함)");
|
|
35
|
-
err(" ✅ .gitignore
|
|
35
|
+
if (gitignoreUpdated) err(" ✅ .gitignore 백업 파일 제외 항목 (*.bak/*.template.yaml)");
|
|
36
36
|
break;
|
|
37
37
|
case "version":
|
|
38
38
|
err(" ✅ 버전 관리 시스템 (version.yml)");
|
|
39
39
|
err(" ✅ README.md 자동 버전 업데이트");
|
|
40
|
-
err(" ✅ .gitignore 필수 항목");
|
|
41
40
|
break;
|
|
42
41
|
case "workflows":
|
|
43
42
|
err(" ✅ GitHub Actions 워크플로우 (AI 릴리스 자동화 포함)");
|