swallowkit 1.1.0 → 1.1.1
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/dist/core/operations/migration-generator.d.ts.map +1 -1
- package/dist/core/operations/migration-generator.js +14 -6
- package/dist/core/operations/migration-generator.js.map +1 -1
- package/dist/core/operations/scaffold-plan.d.ts.map +1 -1
- package/dist/core/operations/scaffold-plan.js +13 -1
- package/dist/core/operations/scaffold-plan.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/plan-apply.test.ts +132 -0
- package/src/core/operations/migration-generator.ts +25 -7
- package/src/core/operations/scaffold-plan.ts +17 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-generator.d.ts","sourceRoot":"","sources":["../../../src/core/operations/migration-generator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"migration-generator.d.ts","sourceRoot":"","sources":["../../../src/core/operations/migration-generator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EACL,uBAAuB,EAEvB,iBAAiB,EAKlB,MAAM,uBAAuB,CAAC;AAqE/B,wBAAgB,0BAA0B,CAAC,WAAW,GAAE,MAAsB,GAAG,iBAAiB,CAEjG;AAED,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,iBAAiB,CAErF;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,GAAE,MAAsB,GAAG,uBAAuB,CA+BrH;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAC7C,OAAO,GAAE,oBAAyD,GACjE,uBAAuB,CA+EzB"}
|
|
@@ -41,6 +41,7 @@ const fs = __importStar(require("fs"));
|
|
|
41
41
|
const path = __importStar(require("path"));
|
|
42
42
|
const errors_1 = require("../../machine/errors");
|
|
43
43
|
const file_session_1 = require("./file-session");
|
|
44
|
+
const artifacts_1 = require("../project/artifacts");
|
|
44
45
|
const migrations_1 = require("../project/migrations");
|
|
45
46
|
const GENERATOR = "infrastructure-migration";
|
|
46
47
|
function normalizeSlug(value) {
|
|
@@ -66,6 +67,10 @@ function readManifestForSession(session) {
|
|
|
66
67
|
try {
|
|
67
68
|
const manifest = JSON.parse(session.readFile(manifestPath));
|
|
68
69
|
(0, migrations_1.validateMigrationManifest)(manifest, session.rootDirectory);
|
|
70
|
+
const baselineDrift = (0, migrations_1.findBaselineDrift)(manifest, session.rootDirectory);
|
|
71
|
+
if (baselineDrift.length > 0) {
|
|
72
|
+
throw new errors_1.MachineCommandError("baseline-drift", "Baseline infrastructure files changed after migration tracking was initialized. Create an explicit migration or reconcile the baseline first.", { changedFiles: baselineDrift }, "blocked");
|
|
73
|
+
}
|
|
69
74
|
return manifest;
|
|
70
75
|
}
|
|
71
76
|
catch (error) {
|
|
@@ -80,15 +85,18 @@ function appendMigration(manifest, migration) {
|
|
|
80
85
|
migrations: [...manifest.migrations, migration].sort((left, right) => left.version - right.version),
|
|
81
86
|
};
|
|
82
87
|
}
|
|
83
|
-
function
|
|
84
|
-
const manifest = (0, migrations_1.createMigrationManifest)(projectRoot, { legacy
|
|
85
|
-
|
|
88
|
+
function initializeMigrations(projectRoot, legacy) {
|
|
89
|
+
const manifest = (0, migrations_1.createMigrationManifest)(projectRoot, { legacy });
|
|
90
|
+
const session = new file_session_1.FileOperationSession("commit", projectRoot);
|
|
91
|
+
session.writeFile(path.join(projectRoot, migrations_1.MIGRATION_MANIFEST_PATH), `${JSON.stringify(manifest, null, 2)}\n`, { ownership: "metadata", generator: GENERATOR });
|
|
92
|
+
(0, artifacts_1.recordSessionOperations)(session.operations, {}, projectRoot);
|
|
86
93
|
return manifest;
|
|
87
94
|
}
|
|
95
|
+
function initializeLegacyMigrations(projectRoot = process.cwd()) {
|
|
96
|
+
return initializeMigrations(projectRoot, true);
|
|
97
|
+
}
|
|
88
98
|
function initializeNewProjectMigrations(projectRoot) {
|
|
89
|
-
|
|
90
|
-
(0, migrations_1.saveMigrationManifest)(manifest, projectRoot);
|
|
91
|
-
return manifest;
|
|
99
|
+
return initializeMigrations(projectRoot, false);
|
|
92
100
|
}
|
|
93
101
|
function createCustomMigration(slugValue, projectRoot = process.cwd()) {
|
|
94
102
|
const manifest = (0, migrations_1.loadMigrationManifest)(projectRoot);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-generator.js","sourceRoot":"","sources":["../../../src/core/operations/migration-generator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"migration-generator.js","sourceRoot":"","sources":["../../../src/core/operations/migration-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-plan.d.ts","sourceRoot":"","sources":["../../../src/core/operations/scaffold-plan.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"scaffold-plan.d.ts","sourceRoot":"","sources":["../../../src/core/operations/scaffold-plan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EACL,iBAAiB,EAEjB,sBAAsB,EAGvB,MAAM,gBAAgB,CAAC;AAQxB,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAYlG,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,UAAU,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QACP,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,sBAAsB,CAAC;IACvC,SAAS,EAAE,qBAAqB,EAAE,CAAC;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4GAA4G;IAC5G,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;CAC7C;AAgDD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0GnG;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,gBAAgB,EACtB,WAAW,GAAE,MAAsB,GAClC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAS5C"}
|
|
@@ -44,9 +44,15 @@ const path = __importStar(require("path"));
|
|
|
44
44
|
const scaffold_1 = require("../../cli/commands/scaffold");
|
|
45
45
|
const version_1 = require("../../version");
|
|
46
46
|
const artifacts_1 = require("../project/artifacts");
|
|
47
|
+
const migrations_1 = require("../project/migrations");
|
|
47
48
|
const state_1 = require("../project/state");
|
|
48
49
|
const file_session_1 = require("./file-session");
|
|
49
50
|
const runtime_1 = require("./runtime");
|
|
51
|
+
function isValidatedMigrationManifestUpdate(operation) {
|
|
52
|
+
return operation.path === migrations_1.MIGRATION_MANIFEST_PATH.replace(/\\/g, "/") &&
|
|
53
|
+
operation.ownership === "metadata" &&
|
|
54
|
+
operation.generator === "infrastructure-migration";
|
|
55
|
+
}
|
|
50
56
|
function deriveScaffoldErrorMessage(messages) {
|
|
51
57
|
return (0, runtime_1.deriveCapturedErrorMessage)(messages, "Scaffold plan failed.");
|
|
52
58
|
}
|
|
@@ -121,7 +127,13 @@ async function planScaffoldOperation(options) {
|
|
|
121
127
|
break;
|
|
122
128
|
case "modify": {
|
|
123
129
|
const record = ledger ? (0, artifacts_1.findArtifactRecord)(ledger, op.path) : undefined;
|
|
124
|
-
if (
|
|
130
|
+
if (isValidatedMigrationManifestUpdate(op)) {
|
|
131
|
+
// migration generator validates the existing manifest before producing
|
|
132
|
+
// an append-only metadata update. This also supports manifests created
|
|
133
|
+
// by older CLI versions that were not registered in the artifact ledger.
|
|
134
|
+
action = "update";
|
|
135
|
+
}
|
|
136
|
+
else if (record && record.contentHash === op.previousHash) {
|
|
125
137
|
// 生成後に変更されていない managed ファイルの再生成 — 安全
|
|
126
138
|
action = "update";
|
|
127
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold-plan.js","sourceRoot":"","sources":["../../../src/core/operations/scaffold-plan.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"scaffold-plan.js","sourceRoot":"","sources":["../../../src/core/operations/scaffold-plan.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqHH,sDA0GC;AAED,wDAYC;AA3OD,+CAAiC;AACjC,2CAA6B;AAC7B,0DAA8D;AAC9D,2CAAqD;AACrD,oDAA8E;AAC9E,sDAAgE;AAChE,4CAAiD;AACjD,iDAMwB;AACxB,uCAKmB;AAWnB,SAAS,kCAAkC,CAAC,SAI3C;IACC,OAAO,SAAS,CAAC,IAAI,KAAK,oCAAuB,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACnE,SAAS,CAAC,SAAS,KAAK,UAAU;QAClC,SAAS,CAAC,SAAS,KAAK,0BAA0B,CAAC;AACvD,CAAC;AA+BD,SAAS,0BAA0B,CAAC,QAAkE;IACpG,OAAO,IAAA,oCAA0B,EAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,yBAAyB,CAAC,OAA4B;IACnE,MAAM,OAAO,GAAG,IAAI,mCAAoB,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,qBAAqB,GAAG,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,GAAG,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,IAAA,yCAA+B,EAAC,KAAK,IAAI,EAAE;YAChE,MAAM,IAAA,8BAAoB,EAAC,KAAK,IAAI,EAAE;gBACpC,MAAM,IAAA,iCAAkB,EAAC,OAAO,EAAE,KAAK,IAAI,EAAE;oBAC3C,MAAM,IAAA,0BAAe,EAAC;wBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,YAAY,EAAE,OAAO,CAAC,YAAY;wBAClC,MAAM,EAAE,OAAO,CAAC,MAAM;wBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;qBACzB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,QAAQ,CAAC,KAAK,YAAY,mCAAyB,EAAE,CAAC;gBACxD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;YACjE,CAAC;YACD,IAAI,QAAQ,CAAC,KAAK,YAAY,KAAK,EAAE,CAAC;gBACpC,MAAM,QAAQ,CAAC,KAAK,CAAC;YACvB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,qBAAqB,CAAC;QAChE,CAAC;IACH,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,qBAAqB,CAAC,OAA4B;IACtE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,IAAA,8BAAkB,EAAC,WAAW,CAAC,CAAC;IAE/C,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,MAAM,YAAY,GAAkC,EAAE,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IACrF,MAAM,QAAQ,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAC9C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,KAAK,MAAM,EAAE,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACpC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC;QAExC,IAAI,MAA0B,CAAC;QAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,cAAkC,CAAC;QAEvC,QAAQ,EAAE,CAAC,MAAM,EAAE,CAAC;YAClB,KAAK,QAAQ;gBACX,MAAM,GAAG,QAAQ,CAAC;gBAClB,MAAM;YACR,KAAK,MAAM;gBACT,MAAM,GAAG,MAAM,CAAC;gBAChB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,GAAG,QAAQ,CAAC;gBAClB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,GAAG,QAAQ,CAAC;gBAClB,MAAM;YACR,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAA,8BAAkB,EAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxE,IAAI,kCAAkC,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC3C,uEAAuE;oBACvE,uEAAuE;oBACvE,yEAAyE;oBACzE,MAAM,GAAG,QAAQ,CAAC;gBACpB,CAAC;qBAAM,IAAI,MAAM,IAAI,MAAM,CAAC,WAAW,KAAK,EAAE,CAAC,YAAY,EAAE,CAAC;oBAC5D,qCAAqC;oBACrC,MAAM,GAAG,QAAQ,CAAC;gBACpB,CAAC;qBAAM,IAAI,MAAM,EAAE,CAAC;oBAClB,MAAM,GAAG,WAAW,CAAC;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,cAAc,GAAG,2BAA2B,CAAC;gBAC/C,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,WAAW,CAAC;oBACrB,QAAQ,GAAG,IAAI,CAAC;oBAChB,cAAc,GAAG,oBAAoB,CAAC;oBACtC,QAAQ,CAAC,IAAI,CACX,uBAAuB,EAAE,CAAC,IAAI,2FAA2F,CAC1H,CAAC;gBACJ,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;QAED,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,MAAM;YACN,SAAS,EAAE,EAAE,CAAC,SAAS;YACvB,QAAQ;YACR,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9C,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IAEzD,MAAM,MAAM,GAAG,MAAM;SAClB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CACL,IAAI,CAAC,SAAS,CAAC;QACb,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;QACjG,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;QAC1E,YAAY;QACZ,cAAc;KACf,CAAC,CACH;SACA,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,MAAM,IAAI,GAAqB;QAC7B,MAAM;QACN,QAAQ,EAAE,UAAU;QACpB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE;YACP,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvE;QACD,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,iBAAiB,EAAE,IAAA,8BAAoB,GAAE;QACzC,UAAU;QACV,QAAQ;QACR,WAAW,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,OAAO,EAAE,CAAC;QAC3E,cAAc;QACd,SAAS;QACT,gBAAgB,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC;QACtC,YAAY;KACb,CAAC;IAEF,IAAA,qBAAa,EAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,sBAAsB,CACpC,IAAsB,EACtB,cAAsB,OAAO,CAAC,GAAG,EAAE;IAEnC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,YAAY,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7E,MAAM,WAAW,GAAG,IAAA,+BAAgB,EAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QAC3E,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC;YACjC,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;AAC5D,CAAC"}
|
package/package.json
CHANGED
|
@@ -5,6 +5,13 @@ import * as childProcess from "child_process";
|
|
|
5
5
|
import { EventEmitter } from "events";
|
|
6
6
|
import { runMachineCli } from "../machine";
|
|
7
7
|
import { getCSharpSchemaModelPath } from "../core/scaffold/native-schema-generator";
|
|
8
|
+
import { initializeLegacyMigrations } from "../core/operations/migration-generator";
|
|
9
|
+
import {
|
|
10
|
+
MIGRATION_MANIFEST_PATH,
|
|
11
|
+
createMigrationManifest,
|
|
12
|
+
loadMigrationManifest,
|
|
13
|
+
saveMigrationManifest,
|
|
14
|
+
} from "../core/project/migrations";
|
|
8
15
|
|
|
9
16
|
jest.mock("child_process", () => {
|
|
10
17
|
const actual = jest.requireActual<typeof import("child_process")>("child_process");
|
|
@@ -67,6 +74,15 @@ function createProjectFixture(rootDir: string): void {
|
|
|
67
74
|
);
|
|
68
75
|
}
|
|
69
76
|
|
|
77
|
+
function createInfrastructureFixture(rootDir: string): void {
|
|
78
|
+
writeFile(path.join(rootDir, "infra", "main.bicep"), "targetScope = 'resourceGroup'\n");
|
|
79
|
+
writeFile(
|
|
80
|
+
path.join(rootDir, "infra", "main.parameters.json"),
|
|
81
|
+
JSON.stringify({ parameters: { projectName: { value: "sample-app" } } }, null, 2)
|
|
82
|
+
);
|
|
83
|
+
writeFile(path.join(rootDir, "infra", "modules", "cosmosdb.bicep"), "// baseline cosmos\n");
|
|
84
|
+
}
|
|
85
|
+
|
|
70
86
|
function createNativeBackendFixture(rootDir: string, backendLanguage: "csharp" | "python"): void {
|
|
71
87
|
createProjectFixture(rootDir);
|
|
72
88
|
writeFile(
|
|
@@ -192,6 +208,122 @@ describe("plan / apply / drift / verify machine commands", () => {
|
|
|
192
208
|
).toBe(true);
|
|
193
209
|
});
|
|
194
210
|
|
|
211
|
+
it("updates a ledger-unregistered legacy manifest without approval and preserves baseline identity", async () => {
|
|
212
|
+
createProjectFixture(tempDir);
|
|
213
|
+
createInfrastructureFixture(tempDir);
|
|
214
|
+
const original = initializeLegacyMigrations(tempDir);
|
|
215
|
+
fs.rmSync(path.join(tempDir, ".swallowkit", "artifacts.json"));
|
|
216
|
+
expect(fs.existsSync(path.join(tempDir, ".swallowkit", "artifacts.json"))).toBe(false);
|
|
217
|
+
|
|
218
|
+
const plan = await runMachine(machineArgs("plan", "scaffold", "todo", "--api-only"));
|
|
219
|
+
|
|
220
|
+
expect(plan.exitCode).toBe(0);
|
|
221
|
+
expect(plan.response.ok).toBe(true);
|
|
222
|
+
expect(plan.response.status).toBe("complete");
|
|
223
|
+
expect(plan.response.data.requiresApproval).toBe(false);
|
|
224
|
+
expect(plan.response.data.conflicts).toEqual([]);
|
|
225
|
+
expect(plan.response.data.operations).toEqual(expect.arrayContaining([
|
|
226
|
+
expect.objectContaining({
|
|
227
|
+
path: MIGRATION_MANIFEST_PATH.replace(/\\/g, "/"),
|
|
228
|
+
action: "update",
|
|
229
|
+
ownership: "metadata",
|
|
230
|
+
conflict: false,
|
|
231
|
+
}),
|
|
232
|
+
expect.objectContaining({
|
|
233
|
+
path: "infra/migrations/0001-create-todo-container/main.bicep",
|
|
234
|
+
action: "create",
|
|
235
|
+
conflict: false,
|
|
236
|
+
}),
|
|
237
|
+
]));
|
|
238
|
+
|
|
239
|
+
const apply = await runMachine(machineArgs("apply", "scaffold", "--plan", plan.response.data.planId));
|
|
240
|
+
expect(apply.exitCode).toBe(0);
|
|
241
|
+
expect(apply.response.ok).toBe(true);
|
|
242
|
+
|
|
243
|
+
const updated = loadMigrationManifest(tempDir);
|
|
244
|
+
expect(updated.projectId).toBe(original.projectId);
|
|
245
|
+
expect(updated.baseline).toEqual(original.baseline);
|
|
246
|
+
expect(updated.migrations).toEqual([
|
|
247
|
+
expect.objectContaining({
|
|
248
|
+
version: 1,
|
|
249
|
+
slug: "create-todo-container",
|
|
250
|
+
source: "model",
|
|
251
|
+
sourceModel: "Todo",
|
|
252
|
+
template: "infra/migrations/0001-create-todo-container/main.bicep",
|
|
253
|
+
}),
|
|
254
|
+
]);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it("uses the same approval-free manifest update for a non-legacy project", async () => {
|
|
258
|
+
createProjectFixture(tempDir);
|
|
259
|
+
createInfrastructureFixture(tempDir);
|
|
260
|
+
const original = createMigrationManifest(tempDir, { legacy: false, projectId: "new-project" });
|
|
261
|
+
saveMigrationManifest(original, tempDir);
|
|
262
|
+
|
|
263
|
+
const plan = await runMachine(machineArgs("plan", "scaffold", "todo", "--api-only"));
|
|
264
|
+
|
|
265
|
+
expect(plan.exitCode).toBe(0);
|
|
266
|
+
expect(plan.response.data.requiresApproval).toBe(false);
|
|
267
|
+
expect(plan.response.data.operations).toContainEqual(expect.objectContaining({
|
|
268
|
+
path: MIGRATION_MANIFEST_PATH.replace(/\\/g, "/"),
|
|
269
|
+
action: "update",
|
|
270
|
+
conflict: false,
|
|
271
|
+
}));
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it.each([
|
|
275
|
+
{
|
|
276
|
+
name: "invalid manifest",
|
|
277
|
+
arrange: (rootDir: string) => writeFile(path.join(rootDir, MIGRATION_MANIFEST_PATH), "{ invalid json\n"),
|
|
278
|
+
code: "invalid-migration-manifest",
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
name: "baseline drift",
|
|
282
|
+
arrange: (rootDir: string) => {
|
|
283
|
+
initializeLegacyMigrations(rootDir);
|
|
284
|
+
writeFile(path.join(rootDir, "infra", "main.bicep"), "// changed after baseline\n");
|
|
285
|
+
},
|
|
286
|
+
code: "baseline-drift",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "missing migration template",
|
|
290
|
+
arrange: (rootDir: string) => {
|
|
291
|
+
const manifest = createMigrationManifest(rootDir, { legacy: true, projectId: "legacy-project" });
|
|
292
|
+
manifest.migrations.push({
|
|
293
|
+
version: 1,
|
|
294
|
+
slug: "missing-template",
|
|
295
|
+
template: "infra/migrations/0001-missing-template/main.bicep",
|
|
296
|
+
source: "custom",
|
|
297
|
+
});
|
|
298
|
+
saveMigrationManifest(manifest, rootDir);
|
|
299
|
+
},
|
|
300
|
+
code: "migration-file-not-found",
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: "discontinuous migration versions",
|
|
304
|
+
arrange: (rootDir: string) => {
|
|
305
|
+
const manifest = createMigrationManifest(rootDir, { legacy: true, projectId: "legacy-project" });
|
|
306
|
+
const template = "infra/migrations/0002-version-gap/main.bicep";
|
|
307
|
+
writeFile(path.join(rootDir, template), "targetScope = 'resourceGroup'\n");
|
|
308
|
+
manifest.migrations.push({ version: 2, slug: "version-gap", template, source: "custom" });
|
|
309
|
+
saveMigrationManifest(manifest, rootDir);
|
|
310
|
+
},
|
|
311
|
+
code: "invalid-migration-manifest",
|
|
312
|
+
},
|
|
313
|
+
])("fails closed for $name before planning scaffold writes", async ({ arrange, code }) => {
|
|
314
|
+
createProjectFixture(tempDir);
|
|
315
|
+
createInfrastructureFixture(tempDir);
|
|
316
|
+
arrange(tempDir);
|
|
317
|
+
|
|
318
|
+
const plan = await runMachine(machineArgs("plan", "scaffold", "todo", "--api-only"));
|
|
319
|
+
|
|
320
|
+
expect(plan.exitCode).toBe(1);
|
|
321
|
+
expect(plan.response.ok).toBe(false);
|
|
322
|
+
expect(plan.response.status).toBe("blocked");
|
|
323
|
+
expect(plan.response.error.code).toBe(code);
|
|
324
|
+
expect(fs.existsSync(path.join(tempDir, "infra", "migrations", "0002-create-todo-container"))).toBe(false);
|
|
325
|
+
});
|
|
326
|
+
|
|
195
327
|
it("plans and applies multiple models in one command (scaffold batch)", async () => {
|
|
196
328
|
createProjectFixture(tempDir);
|
|
197
329
|
writeFile(path.join(tempDir, "shared", "models", "note.ts"), createModelSource("Note"));
|
|
@@ -2,13 +2,14 @@ import * as fs from "fs";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import { MachineCommandError } from "../../machine/errors";
|
|
4
4
|
import { FileOperationSession } from "./file-session";
|
|
5
|
+
import { recordSessionOperations } from "../project/artifacts";
|
|
5
6
|
import {
|
|
6
7
|
InfrastructureMigration,
|
|
7
8
|
MIGRATION_MANIFEST_PATH,
|
|
8
9
|
MigrationManifest,
|
|
9
10
|
createMigrationManifest,
|
|
11
|
+
findBaselineDrift,
|
|
10
12
|
loadMigrationManifest,
|
|
11
|
-
saveMigrationManifest,
|
|
12
13
|
validateMigrationManifest,
|
|
13
14
|
} from "../project/migrations";
|
|
14
15
|
|
|
@@ -44,6 +45,15 @@ function readManifestForSession(session: FileOperationSession): MigrationManifes
|
|
|
44
45
|
try {
|
|
45
46
|
const manifest = JSON.parse(session.readFile(manifestPath)) as MigrationManifest;
|
|
46
47
|
validateMigrationManifest(manifest, session.rootDirectory);
|
|
48
|
+
const baselineDrift = findBaselineDrift(manifest, session.rootDirectory);
|
|
49
|
+
if (baselineDrift.length > 0) {
|
|
50
|
+
throw new MachineCommandError(
|
|
51
|
+
"baseline-drift",
|
|
52
|
+
"Baseline infrastructure files changed after migration tracking was initialized. Create an explicit migration or reconcile the baseline first.",
|
|
53
|
+
{ changedFiles: baselineDrift },
|
|
54
|
+
"blocked"
|
|
55
|
+
);
|
|
56
|
+
}
|
|
47
57
|
return manifest;
|
|
48
58
|
} catch (error) {
|
|
49
59
|
if (error instanceof MachineCommandError) throw error;
|
|
@@ -58,16 +68,24 @@ function appendMigration(manifest: MigrationManifest, migration: InfrastructureM
|
|
|
58
68
|
};
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
const manifest = createMigrationManifest(projectRoot, { legacy
|
|
63
|
-
|
|
71
|
+
function initializeMigrations(projectRoot: string, legacy: boolean): MigrationManifest {
|
|
72
|
+
const manifest = createMigrationManifest(projectRoot, { legacy });
|
|
73
|
+
const session = new FileOperationSession("commit", projectRoot);
|
|
74
|
+
session.writeFile(
|
|
75
|
+
path.join(projectRoot, MIGRATION_MANIFEST_PATH),
|
|
76
|
+
`${JSON.stringify(manifest, null, 2)}\n`,
|
|
77
|
+
{ ownership: "metadata", generator: GENERATOR }
|
|
78
|
+
);
|
|
79
|
+
recordSessionOperations(session.operations, {}, projectRoot);
|
|
64
80
|
return manifest;
|
|
65
81
|
}
|
|
66
82
|
|
|
83
|
+
export function initializeLegacyMigrations(projectRoot: string = process.cwd()): MigrationManifest {
|
|
84
|
+
return initializeMigrations(projectRoot, true);
|
|
85
|
+
}
|
|
86
|
+
|
|
67
87
|
export function initializeNewProjectMigrations(projectRoot: string): MigrationManifest {
|
|
68
|
-
|
|
69
|
-
saveMigrationManifest(manifest, projectRoot);
|
|
70
|
-
return manifest;
|
|
88
|
+
return initializeMigrations(projectRoot, false);
|
|
71
89
|
}
|
|
72
90
|
|
|
73
91
|
export function createCustomMigration(slugValue: string, projectRoot: string = process.cwd()): InfrastructureMigration {
|
|
@@ -8,6 +8,7 @@ import * as path from "path";
|
|
|
8
8
|
import { scaffoldCommand } from "../../cli/commands/scaffold";
|
|
9
9
|
import { getSwallowKitVersion } from "../../version";
|
|
10
10
|
import { findArtifactRecord, loadArtifactLedger } from "../project/artifacts";
|
|
11
|
+
import { MIGRATION_MANIFEST_PATH } from "../project/migrations";
|
|
11
12
|
import { savePlanState } from "../project/state";
|
|
12
13
|
import {
|
|
13
14
|
ArtifactOwnership,
|
|
@@ -32,6 +33,16 @@ export interface PlanScaffoldOptions {
|
|
|
32
33
|
|
|
33
34
|
export type ScaffoldPlanAction = "create" | "update" | "overwrite" | "append" | "delete" | "skip";
|
|
34
35
|
|
|
36
|
+
function isValidatedMigrationManifestUpdate(operation: {
|
|
37
|
+
path: string;
|
|
38
|
+
ownership: ArtifactOwnership;
|
|
39
|
+
generator: string;
|
|
40
|
+
}): boolean {
|
|
41
|
+
return operation.path === MIGRATION_MANIFEST_PATH.replace(/\\/g, "/") &&
|
|
42
|
+
operation.ownership === "metadata" &&
|
|
43
|
+
operation.generator === "infrastructure-migration";
|
|
44
|
+
}
|
|
45
|
+
|
|
35
46
|
export interface ScaffoldPlanOperation {
|
|
36
47
|
path: string;
|
|
37
48
|
action: ScaffoldPlanAction;
|
|
@@ -142,7 +153,12 @@ export async function planScaffoldOperation(options: PlanScaffoldOptions): Promi
|
|
|
142
153
|
break;
|
|
143
154
|
case "modify": {
|
|
144
155
|
const record = ledger ? findArtifactRecord(ledger, op.path) : undefined;
|
|
145
|
-
if (
|
|
156
|
+
if (isValidatedMigrationManifestUpdate(op)) {
|
|
157
|
+
// migration generator validates the existing manifest before producing
|
|
158
|
+
// an append-only metadata update. This also supports manifests created
|
|
159
|
+
// by older CLI versions that were not registered in the artifact ledger.
|
|
160
|
+
action = "update";
|
|
161
|
+
} else if (record && record.contentHash === op.previousHash) {
|
|
146
162
|
// 生成後に変更されていない managed ファイルの再生成 — 安全
|
|
147
163
|
action = "update";
|
|
148
164
|
} else if (record) {
|