projectops 4.89.3 → 4.90.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/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
**Status: actively maintained.** npm `latest` is exactly what is on the `main` branch; work in progress on `develop` is never published. Versions can still ship several times a day. Note that `npx projectops@<version>` pins the installer only (workflow templates always come from the current `main`) ([releases](https://github.com/Cassiiopeia/projectops/releases)).
|
|
12
12
|
|
|
13
13
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
14
|
-
## Latest version : v4.
|
|
14
|
+
## Latest version : v4.90.0 (2026-11-07)
|
|
15
15
|
|
|
16
16
|
[View full version history](CHANGELOG.md)
|
|
17
17
|
|
package/package.json
CHANGED
|
@@ -50,6 +50,16 @@ export function applySafeMigrations(targetRoot, entries) {
|
|
|
50
50
|
// log - 한 줄 출력 함수 (기본 console.log)
|
|
51
51
|
// removeLegacy - true면 confirm 티어(구세대 배포 워크플로우)도 .bak 무해화 (--remove-legacy, #809)
|
|
52
52
|
// 반환: { applied: [결과], confirmPending: [entry], askPending: [entry] }
|
|
53
|
+
// 폐기 워크플로에서 옮긴 설정 > 화면과 실행 기록용 줄 (사용자가 설정이 옮겨졌는지 확인, #1060)
|
|
54
|
+
export function describeCarriedSettings(results) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
for (const result of results) {
|
|
57
|
+
if (result.carried?.length) lines.push(t("migrate.safe.carried", { file: result.from, keys: result.carried.join(", ") }));
|
|
58
|
+
if (result.carryFailed) lines.push(t("migrate.safe.carryFailed", { file: result.from, error: result.carryFailed }));
|
|
59
|
+
}
|
|
60
|
+
return lines;
|
|
61
|
+
}
|
|
62
|
+
|
|
53
63
|
export async function runMigrations({ targetRoot = ".", askYesNo = null, log = console.log, removeLegacy = false } = {}) {
|
|
54
64
|
const { safe, confirm, ask } = detectMigrations(targetRoot);
|
|
55
65
|
if (safe.length === 0 && confirm.length === 0 && ask.length === 0) {
|
|
@@ -73,6 +83,7 @@ export async function runMigrations({ targetRoot = ".", askYesNo = null, log = c
|
|
|
73
83
|
const failed = applied.filter((r) => r.action === "error");
|
|
74
84
|
log(t("migrate.safe.done", { n: ok.length, failed: failed.length ? t("migrate.safe.failed", { n: failed.length }) : "" }));
|
|
75
85
|
for (const f of failed) log(` ⚠️ ${f.from}: ${f.error}`);
|
|
86
|
+
for (const line of describeCarriedSettings(ok)) log(line);
|
|
76
87
|
} else {
|
|
77
88
|
log(t("migrate.safe.skip"));
|
|
78
89
|
}
|
|
@@ -23,9 +23,10 @@ export function detect(targetRoot, entry) {
|
|
|
23
23
|
export function apply(targetRoot, entry) {
|
|
24
24
|
// 무해화 전 설정 이관 (실패해도 무해화는 진행 — 부분 실패 허용 원칙)
|
|
25
25
|
let carried = [];
|
|
26
|
+
let carryFailed = null;
|
|
26
27
|
if (entry.settingsExtractor && EXTRACTORS[entry.settingsExtractor]) {
|
|
27
28
|
try { carried = EXTRACTORS[entry.settingsExtractor](targetRoot, entry).carried; }
|
|
28
|
-
catch { carried = []; }
|
|
29
|
+
catch (error) { carried = []; carryFailed = error?.message || String(error); }
|
|
29
30
|
}
|
|
30
31
|
const src = target(targetRoot, entry);
|
|
31
32
|
const bak = `${src}.bak`;
|
|
@@ -33,5 +34,6 @@ export function apply(targetRoot, entry) {
|
|
|
33
34
|
renameSync(src, bak);
|
|
34
35
|
const result = { action: "bak", from: entry.file, to: `${entry.file}.bak` };
|
|
35
36
|
if (carried.length > 0) result.carried = carried;
|
|
37
|
+
if (carryFailed) result.carryFailed = carryFailed;
|
|
36
38
|
return result;
|
|
37
39
|
}
|
package/src/i18n/migrate.en.js
CHANGED
|
@@ -48,6 +48,8 @@ export default {
|
|
|
48
48
|
"migrate.safe.ask": "Clean up the {n} file(s) above? (workflows are neutralized as .bak and can be restored)",
|
|
49
49
|
"migrate.safe.done": "Legacy cleanup done: {n}{failed}",
|
|
50
50
|
"migrate.safe.failed": " ({n} failed)",
|
|
51
|
+
"migrate.safe.carried": " Settings moved to version.yml from {file}: {keys}",
|
|
52
|
+
"migrate.safe.carryFailed": " ⚠️ Could not move settings from {file}: {error}. Copy them to version.yml by hand; the old file is kept as .bak",
|
|
51
53
|
"migrate.safe.skip": "Skipping legacy cleanup (you will be asked again on the next update)",
|
|
52
54
|
"migrate.dir.found": "Found {n} output folder(s) with an old name. They contain your documents, so they are moved only after confirmation:",
|
|
53
55
|
"migrate.dir.ask": "Move the folders above to the new name? (no files are lost, the original is kept on conflict)",
|
package/src/i18n/migrate.ko.js
CHANGED
|
@@ -48,6 +48,8 @@ export default {
|
|
|
48
48
|
"migrate.safe.ask": "위 {n}개를 정리할까요? (워크플로우는 .bak 무해화 — 복원 가능)",
|
|
49
49
|
"migrate.safe.done": "✅ 레거시 정리 완료: {n}개{failed}",
|
|
50
50
|
"migrate.safe.failed": " (실패 {n}개)",
|
|
51
|
+
"migrate.safe.carried": " {file}의 설정을 version.yml로 옮겼습니다: {keys}",
|
|
52
|
+
"migrate.safe.carryFailed": " ⚠️ {file}의 설정을 옮기지 못했습니다: {error}. version.yml에 직접 옮겨 주세요. 옛 파일은 .bak으로 남아 있습니다",
|
|
51
53
|
"migrate.safe.skip": "→ 레거시 정리를 건너뜁니다 (다음 업데이트 때 다시 안내)",
|
|
52
54
|
"migrate.dir.found": "📁 구명칭 산출물 폴더 {n}개 감지 — 사용자 문서가 들어 있어 확인 후 이동합니다:",
|
|
53
55
|
"migrate.dir.ask": "위 폴더를 새 이름으로 이동할까요? (파일 손실 없음 — 충돌 시 원본 유지)",
|