@metaobjectsdev/cli 1.0.0-rc.1 → 1.0.0-rc.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.
|
@@ -16,7 +16,22 @@ export interface EjectResult {
|
|
|
16
16
|
packageName: string;
|
|
17
17
|
/** Advisory lines about packages the ejected file imports but the project lacks. */
|
|
18
18
|
dependencyNotes: string[];
|
|
19
|
-
status: "created" | "preserved";
|
|
19
|
+
status: "created" | "preserved" | "replaced";
|
|
20
|
+
/**
|
|
21
|
+
* How the file ALREADY on disk compares to the reference template this CLI ships.
|
|
22
|
+
* `undefined` when there was no file.
|
|
23
|
+
*
|
|
24
|
+
* An owned copy is the one artifact ADR-0034 hands an adopter and then never speaks
|
|
25
|
+
* about again. It can sit any number of releases behind the engine it runs against —
|
|
26
|
+
* on the public reference app three of them were ~five minor lines stale, carrying a
|
|
27
|
+
* bare `ts-poet` import (the 0.21.6 split-tree defect), the pre-#248 subtype
|
|
28
|
+
* persistability check and a missing `isWriteThrough` branch — and every gate was
|
|
29
|
+
* green, because nothing compares an owned copy to anything. Reporting this is the
|
|
30
|
+
* cheapest thing that makes that condition observable.
|
|
31
|
+
*/
|
|
32
|
+
local?: "identical" | "differs" | undefined;
|
|
33
|
+
/** Lines of the previous file that the reference does not have. Set only when it differs. */
|
|
34
|
+
changedLines?: number | undefined;
|
|
20
35
|
}
|
|
21
36
|
/**
|
|
22
37
|
* An ejected file is ordinary source in the adopter's repo, so its imports must be
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eject.d.ts","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"AA4DA,sFAAsF;AACtF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AA2CD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;sFACkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,SAAS,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"eject.d.ts","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"AA4DA,sFAAsF;AACtF,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AA2CD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb;sFACkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IAC7C;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C,6FAA6F;IAC7F,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AA0BD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBvG;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA2C7E;AAuDD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4F/E"}
|
|
@@ -87,6 +87,11 @@ async function fileExists(p) {
|
|
|
87
87
|
return false;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
/** Lines present in `a` and not in `b` — a cheap "how far apart" for a report line. */
|
|
91
|
+
function changedLineCount(a, b) {
|
|
92
|
+
const other = new Set(b.split("\n"));
|
|
93
|
+
return a.split("\n").filter((l) => l.trim() !== "" && !other.has(l)).length;
|
|
94
|
+
}
|
|
90
95
|
/** The `@metaobjectsdev/*` packages an ejected template imports, read from the file
|
|
91
96
|
* itself rather than from a per-name table — the template is the only thing that
|
|
92
97
|
* knows, and a table would drift from it the moment a template gains an import. */
|
|
@@ -157,20 +162,68 @@ export async function ejectGenerator(opts) {
|
|
|
157
162
|
packageName: source.packageName,
|
|
158
163
|
dependencyNotes: notes,
|
|
159
164
|
};
|
|
160
|
-
|
|
161
|
-
|
|
165
|
+
const existing = (await fileExists(abs)) ? await readFile(abs, "utf8") : undefined;
|
|
166
|
+
const local = existing === undefined ? undefined : existing === templateSource ? "identical" : "differs";
|
|
167
|
+
const changedLines = local === "differs" && existing !== undefined
|
|
168
|
+
? changedLineCount(existing, templateSource)
|
|
169
|
+
: undefined;
|
|
170
|
+
if (!opts.force && existing !== undefined) {
|
|
171
|
+
return { ...common, status: "preserved", local, changedLines };
|
|
162
172
|
}
|
|
163
173
|
await mkdir(join(opts.cwd, OWNED_GENERATORS_DIR), { recursive: true });
|
|
164
174
|
await writeFile(abs, templateSource, "utf8");
|
|
165
|
-
return {
|
|
175
|
+
return {
|
|
176
|
+
...common,
|
|
177
|
+
status: existing === undefined ? "created" : "replaced",
|
|
178
|
+
local,
|
|
179
|
+
changedLines,
|
|
180
|
+
};
|
|
166
181
|
}
|
|
167
|
-
|
|
182
|
+
/**
|
|
183
|
+
* `--list` doubles as the staleness report for what this project ALREADY owns.
|
|
184
|
+
*
|
|
185
|
+
* A listing of names you could eject is the less useful half. The half nobody had is
|
|
186
|
+
* "which of the copies I own have fallen behind" — the condition that let a reference
|
|
187
|
+
* app run generators ~five minor lines old, carrying three retired patterns, with every
|
|
188
|
+
* gate green. Marking each owned copy `identical` / `differs` makes it a one-command
|
|
189
|
+
* answer instead of a diff nobody thinks to run.
|
|
190
|
+
*/
|
|
191
|
+
async function listOutput(cwd) {
|
|
168
192
|
const lines = [];
|
|
169
193
|
lines.push("Ejectable generators (copy any of these into codegen/generators/ and own it):");
|
|
170
194
|
lines.push("");
|
|
195
|
+
let anyStale = false;
|
|
171
196
|
for (const source of SOURCES) {
|
|
172
197
|
lines.push(`${source.packageName}:`);
|
|
173
|
-
|
|
198
|
+
for (const name of source.names) {
|
|
199
|
+
const abs = join(cwd, OWNED_GENERATORS_DIR, `${name}.ts`);
|
|
200
|
+
if (!(await fileExists(abs))) {
|
|
201
|
+
lines.push(` ${name}`);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
let ref;
|
|
205
|
+
try {
|
|
206
|
+
ref = await readFile(join(source.root(), `${name}.ts`), "utf8");
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
lines.push(` ${name} [owned]`);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
const owned = await readFile(abs, "utf8");
|
|
213
|
+
if (owned === ref) {
|
|
214
|
+
lines.push(` ${name} [owned — identical to the reference]`);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
anyStale = true;
|
|
218
|
+
lines.push(` ${name} [owned — DIFFERS from the reference by ` +
|
|
219
|
+
`${changedLineCount(owned, ref)} line(s)]`);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
lines.push("");
|
|
223
|
+
}
|
|
224
|
+
if (anyStale) {
|
|
225
|
+
lines.push("A copy that DIFFERS is either your customization or upstream having moved on — " +
|
|
226
|
+
"`meta eject <name>` prints the diff command that tells you which.");
|
|
174
227
|
lines.push("");
|
|
175
228
|
}
|
|
176
229
|
lines.push("Run: meta eject <name>");
|
|
@@ -186,7 +239,7 @@ export async function ejectCommand(args, cwd) {
|
|
|
186
239
|
return 2;
|
|
187
240
|
}
|
|
188
241
|
if (flags.list) {
|
|
189
|
-
log.info(listOutput());
|
|
242
|
+
log.info(await listOutput(cwd));
|
|
190
243
|
return 0;
|
|
191
244
|
}
|
|
192
245
|
if (flags.name === undefined) {
|
|
@@ -196,7 +249,33 @@ export async function ejectCommand(args, cwd) {
|
|
|
196
249
|
try {
|
|
197
250
|
const result = await ejectGenerator({ cwd, name: flags.name, force: flags.force });
|
|
198
251
|
if (result.status === "preserved") {
|
|
199
|
-
|
|
252
|
+
// "already exists — left untouched" was the whole message, and it answered the
|
|
253
|
+
// question nobody has. What an owner needs to know is whether their copy still
|
|
254
|
+
// matches what this CLI ships — the only way an owned generator's staleness is
|
|
255
|
+
// ever observable, since no gate compares the two.
|
|
256
|
+
if (result.local === "identical") {
|
|
257
|
+
log.info(`${result.path} already exists and is IDENTICAL to the ${result.packageName} ` +
|
|
258
|
+
"reference template — nothing to do.");
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
log.info(`${result.path} already exists and DIFFERS from the ${result.packageName} ` +
|
|
262
|
+
`reference template (${result.changedLines} line(s) not in the reference) — left untouched.`);
|
|
263
|
+
log.info(" That difference is either YOUR customization or upstream having moved on. " +
|
|
264
|
+
"See which, before deciding:");
|
|
265
|
+
log.info(` diff -u node_modules/${result.packageName}/src/reference/${flags.name}.ts ${result.path}`);
|
|
266
|
+
log.info(" To take upstream changes AND keep your customization, three-way merge them — " +
|
|
267
|
+
"`git merge-file --diff3 <your copy> <the reference you ejected from> <the reference above>`. " +
|
|
268
|
+
"`--force` does NOT merge: it replaces the file and your customization with it.");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else if (result.status === "replaced") {
|
|
272
|
+
// Never let a --force over a modified file be silent: this is the step that
|
|
273
|
+
// destroys an adopter's customization, and the file's own header is often the
|
|
274
|
+
// only record that the customization was deliberate.
|
|
275
|
+
log.info(`Ejected "${flags.name}" -> ${result.path}, REPLACING the file that was there` +
|
|
276
|
+
(result.local === "differs"
|
|
277
|
+
? ` and DISCARDING ${result.changedLines} line(s) it had that the reference does not.`
|
|
278
|
+
: " (it was already identical to the reference)."));
|
|
200
279
|
}
|
|
201
280
|
else {
|
|
202
281
|
log.info(`Ejected "${flags.name}" -> ${result.path}. You own it now (ADR-0034 scaffold-and-own).`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eject.js","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"eject.js","sourceRoot":"","sources":["../../../src/commands/eject.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/cli",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.2",
|
|
4
4
|
"description": "CLI for MetaObjects: scaffold, codegen, migrate, and drift-detection commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@libsql/kysely-libsql": "^0.4.0",
|
|
52
|
-
"@metaobjectsdev/codegen-ts": "1.0.0-rc.
|
|
53
|
-
"@metaobjectsdev/codegen-ts-react": "1.0.0-rc.
|
|
54
|
-
"@metaobjectsdev/codegen-ts-tanstack": "1.0.0-rc.
|
|
55
|
-
"@metaobjectsdev/docs-site": "1.0.0-rc.
|
|
56
|
-
"@metaobjectsdev/metadata": "1.0.0-rc.
|
|
57
|
-
"@metaobjectsdev/migrate-ts": "1.0.0-rc.
|
|
58
|
-
"@metaobjectsdev/render": "1.0.0-rc.
|
|
59
|
-
"@metaobjectsdev/runtime-ts": "1.0.0-rc.
|
|
60
|
-
"@metaobjectsdev/sdk": "1.0.0-rc.
|
|
52
|
+
"@metaobjectsdev/codegen-ts": "1.0.0-rc.2",
|
|
53
|
+
"@metaobjectsdev/codegen-ts-react": "1.0.0-rc.2",
|
|
54
|
+
"@metaobjectsdev/codegen-ts-tanstack": "1.0.0-rc.2",
|
|
55
|
+
"@metaobjectsdev/docs-site": "1.0.0-rc.2",
|
|
56
|
+
"@metaobjectsdev/metadata": "1.0.0-rc.2",
|
|
57
|
+
"@metaobjectsdev/migrate-ts": "1.0.0-rc.2",
|
|
58
|
+
"@metaobjectsdev/render": "1.0.0-rc.2",
|
|
59
|
+
"@metaobjectsdev/runtime-ts": "1.0.0-rc.2",
|
|
60
|
+
"@metaobjectsdev/sdk": "1.0.0-rc.2",
|
|
61
61
|
"@toon-format/toon": "^2.3.0",
|
|
62
62
|
"jiti": "^2.4.0"
|
|
63
63
|
},
|
package/src/commands/eject.ts
CHANGED
|
@@ -121,7 +121,28 @@ export interface EjectResult {
|
|
|
121
121
|
packageName: string;
|
|
122
122
|
/** Advisory lines about packages the ejected file imports but the project lacks. */
|
|
123
123
|
dependencyNotes: string[];
|
|
124
|
-
status: "created" | "preserved";
|
|
124
|
+
status: "created" | "preserved" | "replaced";
|
|
125
|
+
/**
|
|
126
|
+
* How the file ALREADY on disk compares to the reference template this CLI ships.
|
|
127
|
+
* `undefined` when there was no file.
|
|
128
|
+
*
|
|
129
|
+
* An owned copy is the one artifact ADR-0034 hands an adopter and then never speaks
|
|
130
|
+
* about again. It can sit any number of releases behind the engine it runs against —
|
|
131
|
+
* on the public reference app three of them were ~five minor lines stale, carrying a
|
|
132
|
+
* bare `ts-poet` import (the 0.21.6 split-tree defect), the pre-#248 subtype
|
|
133
|
+
* persistability check and a missing `isWriteThrough` branch — and every gate was
|
|
134
|
+
* green, because nothing compares an owned copy to anything. Reporting this is the
|
|
135
|
+
* cheapest thing that makes that condition observable.
|
|
136
|
+
*/
|
|
137
|
+
local?: "identical" | "differs" | undefined;
|
|
138
|
+
/** Lines of the previous file that the reference does not have. Set only when it differs. */
|
|
139
|
+
changedLines?: number | undefined;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Lines present in `a` and not in `b` — a cheap "how far apart" for a report line. */
|
|
143
|
+
function changedLineCount(a: string, b: string): number {
|
|
144
|
+
const other = new Set(b.split("\n"));
|
|
145
|
+
return a.split("\n").filter((l) => l.trim() !== "" && !other.has(l)).length;
|
|
125
146
|
}
|
|
126
147
|
|
|
127
148
|
/** The `@metaobjectsdev/*` packages an ejected template imports, read from the file
|
|
@@ -199,22 +220,75 @@ export async function ejectGenerator(opts: EjectOptions): Promise<EjectResult> {
|
|
|
199
220
|
dependencyNotes: notes,
|
|
200
221
|
};
|
|
201
222
|
|
|
202
|
-
|
|
203
|
-
|
|
223
|
+
const existing = (await fileExists(abs)) ? await readFile(abs, "utf8") : undefined;
|
|
224
|
+
const local =
|
|
225
|
+
existing === undefined ? undefined : existing === templateSource ? "identical" : "differs";
|
|
226
|
+
const changedLines =
|
|
227
|
+
local === "differs" && existing !== undefined
|
|
228
|
+
? changedLineCount(existing, templateSource)
|
|
229
|
+
: undefined;
|
|
230
|
+
|
|
231
|
+
if (!opts.force && existing !== undefined) {
|
|
232
|
+
return { ...common, status: "preserved", local, changedLines };
|
|
204
233
|
}
|
|
205
234
|
|
|
206
235
|
await mkdir(join(opts.cwd, OWNED_GENERATORS_DIR), { recursive: true });
|
|
207
236
|
await writeFile(abs, templateSource, "utf8");
|
|
208
|
-
return {
|
|
237
|
+
return {
|
|
238
|
+
...common,
|
|
239
|
+
status: existing === undefined ? "created" : "replaced",
|
|
240
|
+
local,
|
|
241
|
+
changedLines,
|
|
242
|
+
};
|
|
209
243
|
}
|
|
210
244
|
|
|
211
|
-
|
|
245
|
+
/**
|
|
246
|
+
* `--list` doubles as the staleness report for what this project ALREADY owns.
|
|
247
|
+
*
|
|
248
|
+
* A listing of names you could eject is the less useful half. The half nobody had is
|
|
249
|
+
* "which of the copies I own have fallen behind" — the condition that let a reference
|
|
250
|
+
* app run generators ~five minor lines old, carrying three retired patterns, with every
|
|
251
|
+
* gate green. Marking each owned copy `identical` / `differs` makes it a one-command
|
|
252
|
+
* answer instead of a diff nobody thinks to run.
|
|
253
|
+
*/
|
|
254
|
+
async function listOutput(cwd: string): Promise<string> {
|
|
212
255
|
const lines: string[] = [];
|
|
213
256
|
lines.push("Ejectable generators (copy any of these into codegen/generators/ and own it):");
|
|
214
257
|
lines.push("");
|
|
258
|
+
let anyStale = false;
|
|
215
259
|
for (const source of SOURCES) {
|
|
216
260
|
lines.push(`${source.packageName}:`);
|
|
217
|
-
|
|
261
|
+
for (const name of source.names) {
|
|
262
|
+
const abs = join(cwd, OWNED_GENERATORS_DIR, `${name}.ts`);
|
|
263
|
+
if (!(await fileExists(abs))) {
|
|
264
|
+
lines.push(` ${name}`);
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
let ref: string;
|
|
268
|
+
try {
|
|
269
|
+
ref = await readFile(join(source.root(), `${name}.ts`), "utf8");
|
|
270
|
+
} catch {
|
|
271
|
+
lines.push(` ${name} [owned]`);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const owned = await readFile(abs, "utf8");
|
|
275
|
+
if (owned === ref) {
|
|
276
|
+
lines.push(` ${name} [owned — identical to the reference]`);
|
|
277
|
+
} else {
|
|
278
|
+
anyStale = true;
|
|
279
|
+
lines.push(
|
|
280
|
+
` ${name} [owned — DIFFERS from the reference by ` +
|
|
281
|
+
`${changedLineCount(owned, ref)} line(s)]`,
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
lines.push("");
|
|
286
|
+
}
|
|
287
|
+
if (anyStale) {
|
|
288
|
+
lines.push(
|
|
289
|
+
"A copy that DIFFERS is either your customization or upstream having moved on — " +
|
|
290
|
+
"`meta eject <name>` prints the diff command that tells you which.",
|
|
291
|
+
);
|
|
218
292
|
lines.push("");
|
|
219
293
|
}
|
|
220
294
|
lines.push("Run: meta eject <name>");
|
|
@@ -231,7 +305,7 @@ export async function ejectCommand(args: string[], cwd: string): Promise<number>
|
|
|
231
305
|
}
|
|
232
306
|
|
|
233
307
|
if (flags.list) {
|
|
234
|
-
log.info(listOutput());
|
|
308
|
+
log.info(await listOutput(cwd));
|
|
235
309
|
return 0;
|
|
236
310
|
}
|
|
237
311
|
|
|
@@ -243,7 +317,41 @@ export async function ejectCommand(args: string[], cwd: string): Promise<number>
|
|
|
243
317
|
try {
|
|
244
318
|
const result = await ejectGenerator({ cwd, name: flags.name, force: flags.force });
|
|
245
319
|
if (result.status === "preserved") {
|
|
246
|
-
|
|
320
|
+
// "already exists — left untouched" was the whole message, and it answered the
|
|
321
|
+
// question nobody has. What an owner needs to know is whether their copy still
|
|
322
|
+
// matches what this CLI ships — the only way an owned generator's staleness is
|
|
323
|
+
// ever observable, since no gate compares the two.
|
|
324
|
+
if (result.local === "identical") {
|
|
325
|
+
log.info(
|
|
326
|
+
`${result.path} already exists and is IDENTICAL to the ${result.packageName} ` +
|
|
327
|
+
"reference template — nothing to do.",
|
|
328
|
+
);
|
|
329
|
+
} else {
|
|
330
|
+
log.info(
|
|
331
|
+
`${result.path} already exists and DIFFERS from the ${result.packageName} ` +
|
|
332
|
+
`reference template (${result.changedLines} line(s) not in the reference) — left untouched.`,
|
|
333
|
+
);
|
|
334
|
+
log.info(
|
|
335
|
+
" That difference is either YOUR customization or upstream having moved on. " +
|
|
336
|
+
"See which, before deciding:",
|
|
337
|
+
);
|
|
338
|
+
log.info(` diff -u node_modules/${result.packageName}/src/reference/${flags.name}.ts ${result.path}`);
|
|
339
|
+
log.info(
|
|
340
|
+
" To take upstream changes AND keep your customization, three-way merge them — " +
|
|
341
|
+
"`git merge-file --diff3 <your copy> <the reference you ejected from> <the reference above>`. " +
|
|
342
|
+
"`--force` does NOT merge: it replaces the file and your customization with it.",
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
} else if (result.status === "replaced") {
|
|
346
|
+
// Never let a --force over a modified file be silent: this is the step that
|
|
347
|
+
// destroys an adopter's customization, and the file's own header is often the
|
|
348
|
+
// only record that the customization was deliberate.
|
|
349
|
+
log.info(
|
|
350
|
+
`Ejected "${flags.name}" -> ${result.path}, REPLACING the file that was there` +
|
|
351
|
+
(result.local === "differs"
|
|
352
|
+
? ` and DISCARDING ${result.changedLines} line(s) it had that the reference does not.`
|
|
353
|
+
: " (it was already identical to the reference)."),
|
|
354
|
+
);
|
|
247
355
|
} else {
|
|
248
356
|
log.info(`Ejected "${flags.name}" -> ${result.path}. You own it now (ADR-0034 scaffold-and-own).`);
|
|
249
357
|
}
|