@hanseltime/template-repo-sync 2.2.0 → 2.2.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/CHANGELOG.md +7 -0
- package/lib/cjs/template-sync.js +26 -3
- package/lib/esm/template-sync.js +26 -3
- package/package.json +1 -1
- package/src/template-sync.spec.ts +87 -1
- package/src/template-sync.ts +27 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [2.2.1](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.2.0...v2.2.1) (2026-02-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* template sync afterRef updates ([21dd335](https://github.com/HanseltimeIndustries/template-repo-sync/commit/21dd335045034d132ad5f6ab7944a81c82b96981))
|
|
7
|
+
|
|
1
8
|
# [2.2.0](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.1.2...v2.2.0) (2026-02-21)
|
|
2
9
|
|
|
3
10
|
|
package/lib/cjs/template-sync.js
CHANGED
|
@@ -61,12 +61,29 @@ async function templateSync(options) {
|
|
|
61
61
|
const templateSyncConfig = (0, fs_1.existsSync)(cloneConfigPath)
|
|
62
62
|
? commentJSON.parse((0, fs_1.readFileSync)(cloneConfigPath).toString())
|
|
63
63
|
: { ignore: [] };
|
|
64
|
-
const
|
|
64
|
+
const localConfigFile = `${exports.TEMPLATE_SYNC_LOCAL_CONFIG}.json`;
|
|
65
|
+
const localConfigPath = (0, path_1.join)(options.repoDir, localConfigFile);
|
|
65
66
|
const localTemplateSyncConfig = (0, fs_1.existsSync)(localConfigPath)
|
|
66
67
|
? commentJSON.parse((0, fs_1.readFileSync)(localConfigPath).toString())
|
|
67
68
|
: { ignore: [] };
|
|
68
69
|
let filesToSync;
|
|
70
|
+
const ref = await currentRefDriver({
|
|
71
|
+
rootDir: tempCloneDir,
|
|
72
|
+
});
|
|
69
73
|
if (localTemplateSyncConfig.afterRef) {
|
|
74
|
+
if (ref === localTemplateSyncConfig.afterRef) {
|
|
75
|
+
// short circuit if the refs match
|
|
76
|
+
return {
|
|
77
|
+
localSkipFiles: [],
|
|
78
|
+
localFileChanges: {},
|
|
79
|
+
modifiedFiles: {
|
|
80
|
+
added: [],
|
|
81
|
+
modified: [],
|
|
82
|
+
deleted: [],
|
|
83
|
+
total: 0,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
70
87
|
filesToSync = await diffDriver(tempCloneDir, localTemplateSyncConfig.afterRef);
|
|
71
88
|
}
|
|
72
89
|
else {
|
|
@@ -114,7 +131,6 @@ async function templateSync(options) {
|
|
|
114
131
|
added: actualAdded,
|
|
115
132
|
modified: actualModified,
|
|
116
133
|
deleted: actualDeleted,
|
|
117
|
-
total: actualAdded.length + actualModified.length + actualDeleted.length,
|
|
118
134
|
};
|
|
119
135
|
// apply after ref
|
|
120
136
|
if (options.updateAfterRef) {
|
|
@@ -126,15 +142,22 @@ async function templateSync(options) {
|
|
|
126
142
|
const config = commentJSON.parse(configStr);
|
|
127
143
|
config.afterRef = ref;
|
|
128
144
|
(0, fs_1.writeFileSync)(localConfigPath, commentJSON.stringify(config, null, (0, formatting_1.inferJSONIndent)(configStr)));
|
|
145
|
+
modifiedFiles.modified.push(localConfigFile);
|
|
129
146
|
}
|
|
130
147
|
else {
|
|
131
148
|
(0, fs_1.writeFileSync)(localConfigPath, commentJSON.stringify({ afterRef: ref }, null, 4));
|
|
149
|
+
modifiedFiles.added.push(localConfigFile);
|
|
132
150
|
}
|
|
133
151
|
}
|
|
134
152
|
return {
|
|
135
153
|
localSkipFiles: Array.from(localSkipFiles),
|
|
136
154
|
localFileChanges,
|
|
137
|
-
modifiedFiles:
|
|
155
|
+
modifiedFiles: {
|
|
156
|
+
...modifiedFiles,
|
|
157
|
+
total: modifiedFiles.added.length +
|
|
158
|
+
modifiedFiles.deleted.length +
|
|
159
|
+
modifiedFiles.modified.length,
|
|
160
|
+
},
|
|
138
161
|
};
|
|
139
162
|
}
|
|
140
163
|
exports.templateSync = templateSync;
|
package/lib/esm/template-sync.js
CHANGED
|
@@ -61,12 +61,29 @@ async function templateSync(options) {
|
|
|
61
61
|
const templateSyncConfig = (0, fs_1.existsSync)(cloneConfigPath)
|
|
62
62
|
? commentJSON.parse((0, fs_1.readFileSync)(cloneConfigPath).toString())
|
|
63
63
|
: { ignore: [] };
|
|
64
|
-
const
|
|
64
|
+
const localConfigFile = `${exports.TEMPLATE_SYNC_LOCAL_CONFIG}.json`;
|
|
65
|
+
const localConfigPath = (0, path_1.join)(options.repoDir, localConfigFile);
|
|
65
66
|
const localTemplateSyncConfig = (0, fs_1.existsSync)(localConfigPath)
|
|
66
67
|
? commentJSON.parse((0, fs_1.readFileSync)(localConfigPath).toString())
|
|
67
68
|
: { ignore: [] };
|
|
68
69
|
let filesToSync;
|
|
70
|
+
const ref = await currentRefDriver({
|
|
71
|
+
rootDir: tempCloneDir,
|
|
72
|
+
});
|
|
69
73
|
if (localTemplateSyncConfig.afterRef) {
|
|
74
|
+
if (ref === localTemplateSyncConfig.afterRef) {
|
|
75
|
+
// short circuit if the refs match
|
|
76
|
+
return {
|
|
77
|
+
localSkipFiles: [],
|
|
78
|
+
localFileChanges: {},
|
|
79
|
+
modifiedFiles: {
|
|
80
|
+
added: [],
|
|
81
|
+
modified: [],
|
|
82
|
+
deleted: [],
|
|
83
|
+
total: 0,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
70
87
|
filesToSync = await diffDriver(tempCloneDir, localTemplateSyncConfig.afterRef);
|
|
71
88
|
}
|
|
72
89
|
else {
|
|
@@ -114,7 +131,6 @@ async function templateSync(options) {
|
|
|
114
131
|
added: actualAdded,
|
|
115
132
|
modified: actualModified,
|
|
116
133
|
deleted: actualDeleted,
|
|
117
|
-
total: actualAdded.length + actualModified.length + actualDeleted.length,
|
|
118
134
|
};
|
|
119
135
|
// apply after ref
|
|
120
136
|
if (options.updateAfterRef) {
|
|
@@ -126,15 +142,22 @@ async function templateSync(options) {
|
|
|
126
142
|
const config = commentJSON.parse(configStr);
|
|
127
143
|
config.afterRef = ref;
|
|
128
144
|
(0, fs_1.writeFileSync)(localConfigPath, commentJSON.stringify(config, null, (0, formatting_1.inferJSONIndent)(configStr)));
|
|
145
|
+
modifiedFiles.modified.push(localConfigFile);
|
|
129
146
|
}
|
|
130
147
|
else {
|
|
131
148
|
(0, fs_1.writeFileSync)(localConfigPath, commentJSON.stringify({ afterRef: ref }, null, 4));
|
|
149
|
+
modifiedFiles.added.push(localConfigFile);
|
|
132
150
|
}
|
|
133
151
|
}
|
|
134
152
|
return {
|
|
135
153
|
localSkipFiles: Array.from(localSkipFiles),
|
|
136
154
|
localFileChanges,
|
|
137
|
-
modifiedFiles:
|
|
155
|
+
modifiedFiles: {
|
|
156
|
+
...modifiedFiles,
|
|
157
|
+
total: modifiedFiles.added.length +
|
|
158
|
+
modifiedFiles.deleted.length +
|
|
159
|
+
modifiedFiles.modified.length,
|
|
160
|
+
},
|
|
138
161
|
};
|
|
139
162
|
}
|
|
140
163
|
exports.templateSync = templateSync;
|
package/package.json
CHANGED
|
@@ -292,7 +292,7 @@ describe("templateSync", () => {
|
|
|
292
292
|
// We will only update the templated.ts
|
|
293
293
|
const mockDiffDriver = jest.fn().mockImplementation(async () => ({
|
|
294
294
|
added: ["src/templated.ts"],
|
|
295
|
-
modified: ["src/index.ts"], // Add index.ts so we make sure it is still ignored -
|
|
295
|
+
modified: ["src/index.ts"], // Add index.ts so we make sure it is still ignored - see test-fixtures/template/templatesync.json ignores
|
|
296
296
|
deleted: [],
|
|
297
297
|
}));
|
|
298
298
|
const mockCurrentRefDriver = jest
|
|
@@ -311,6 +311,12 @@ describe("templateSync", () => {
|
|
|
311
311
|
|
|
312
312
|
// since there was no override for this file, no changes from the local file
|
|
313
313
|
expect(result.localFileChanges).toEqual(expect.objectContaining({}));
|
|
314
|
+
expect(result.modifiedFiles).toEqual({
|
|
315
|
+
added: ["src/templated.ts"],
|
|
316
|
+
modified: ["templatesync.local.json"], // Add index.ts so we make sure it is still ignored - due to a bug
|
|
317
|
+
deleted: [],
|
|
318
|
+
total: 2,
|
|
319
|
+
});
|
|
314
320
|
|
|
315
321
|
// Verify the files
|
|
316
322
|
await fileMatchTemplate(tmpDir, "templatesync.json");
|
|
@@ -332,6 +338,73 @@ describe("templateSync", () => {
|
|
|
332
338
|
});
|
|
333
339
|
expect(dummyCheckoutDriver).not.toHaveBeenCalled();
|
|
334
340
|
});
|
|
341
|
+
it("Does not update the local templatesync if updateAfterRef is true and the ref is the same", async () => {
|
|
342
|
+
// Remove the local sync overrides
|
|
343
|
+
await rm(join(tmpDir, "templatesync.local.json"));
|
|
344
|
+
|
|
345
|
+
const mockLocalConfig = {
|
|
346
|
+
afterRef: "dummySha",
|
|
347
|
+
ignore: [
|
|
348
|
+
// We don't have a need for this in here, but it's an example of keeping things cleaner for our custom plugins
|
|
349
|
+
"plugins/**",
|
|
350
|
+
],
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
writeFileSync(
|
|
354
|
+
join(tmpDir, "templatesync.local.json"),
|
|
355
|
+
JSON.stringify(mockLocalConfig),
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
// We will only update the templated.ts
|
|
359
|
+
const mockDiffDriver = jest.fn().mockImplementation(async () => ({
|
|
360
|
+
added: ["src/templated.ts"],
|
|
361
|
+
modified: ["src/index.ts"], // Add index.ts so we make sure it is still ignored - see test-fixtures/template/templatesync.json ignores
|
|
362
|
+
deleted: [],
|
|
363
|
+
}));
|
|
364
|
+
const mockCurrentRefDriver = jest
|
|
365
|
+
.fn()
|
|
366
|
+
.mockImplementation(async () => "dummySha");
|
|
367
|
+
const result = await templateSync({
|
|
368
|
+
tmpCloneDir: "stubbed-by-driver",
|
|
369
|
+
cloneDriver: dummyCloneDriver,
|
|
370
|
+
repoUrl: "not-important",
|
|
371
|
+
repoDir: tmpDir,
|
|
372
|
+
updateAfterRef: true,
|
|
373
|
+
diffDriver: mockDiffDriver,
|
|
374
|
+
currentRefDriver: mockCurrentRefDriver,
|
|
375
|
+
checkoutDriver: dummyCheckoutDriver,
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Nothing shoudl be reported as changing
|
|
379
|
+
expect(result).toEqual({
|
|
380
|
+
localFileChanges: {},
|
|
381
|
+
localSkipFiles: [],
|
|
382
|
+
modifiedFiles: {
|
|
383
|
+
added: [],
|
|
384
|
+
modified: [],
|
|
385
|
+
deleted: [],
|
|
386
|
+
total: 0,
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
// Verify the files
|
|
390
|
+
await fileMatchDownstream(tmpDir, "templatesync.json");
|
|
391
|
+
await fileMatchDownstream(tmpDir, "src/templated.ts");
|
|
392
|
+
|
|
393
|
+
// Expect the none of the diff files to work
|
|
394
|
+
await fileMatchDownstream(tmpDir, "src/index.ts");
|
|
395
|
+
await fileMatchDownstream(tmpDir, "plugins/custom-plugin.js");
|
|
396
|
+
await fileMatchDownstream(tmpDir, "package.json");
|
|
397
|
+
|
|
398
|
+
// Ensure we have updated the local template field
|
|
399
|
+
expect(
|
|
400
|
+
JSON.parse(
|
|
401
|
+
(await readFile(join(tmpDir, "templatesync.local.json"))).toString(),
|
|
402
|
+
),
|
|
403
|
+
).toEqual({
|
|
404
|
+
...mockLocalConfig,
|
|
405
|
+
});
|
|
406
|
+
expect(dummyCheckoutDriver).not.toHaveBeenCalled();
|
|
407
|
+
});
|
|
335
408
|
it("creates the local templatesync with the current ref if updateAfterRef is true and no local template exists", async () => {
|
|
336
409
|
// Remove the local sync overrides
|
|
337
410
|
await rm(join(tmpDir, "templatesync.local.json"));
|
|
@@ -356,6 +429,19 @@ describe("templateSync", () => {
|
|
|
356
429
|
|
|
357
430
|
// since there was no override for this file, no changes from the local file
|
|
358
431
|
expect(result.localFileChanges).toEqual(expect.objectContaining({}));
|
|
432
|
+
expect(result.modifiedFiles).toEqual({
|
|
433
|
+
added: [
|
|
434
|
+
"package.json",
|
|
435
|
+
"src/index.js",
|
|
436
|
+
"src/templated.js",
|
|
437
|
+
"src/templated.ts",
|
|
438
|
+
"templatesync.json",
|
|
439
|
+
"templatesync.local.json",
|
|
440
|
+
],
|
|
441
|
+
deleted: [],
|
|
442
|
+
modified: [],
|
|
443
|
+
total: 6,
|
|
444
|
+
});
|
|
359
445
|
|
|
360
446
|
// Verify the files
|
|
361
447
|
await fileMatchTemplate(tmpDir, "templatesync.json");
|
package/src/template-sync.ts
CHANGED
|
@@ -125,10 +125,8 @@ export async function templateSync(
|
|
|
125
125
|
) as unknown as Config)
|
|
126
126
|
: { ignore: [] };
|
|
127
127
|
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
`${TEMPLATE_SYNC_LOCAL_CONFIG}.json`,
|
|
131
|
-
);
|
|
128
|
+
const localConfigFile = `${TEMPLATE_SYNC_LOCAL_CONFIG}.json`;
|
|
129
|
+
const localConfigPath = join(options.repoDir, localConfigFile);
|
|
132
130
|
const localTemplateSyncConfig: LocalConfig = existsSync(localConfigPath)
|
|
133
131
|
? (commentJSON.parse(
|
|
134
132
|
readFileSync(localConfigPath).toString(),
|
|
@@ -136,7 +134,23 @@ export async function templateSync(
|
|
|
136
134
|
: { ignore: [] };
|
|
137
135
|
|
|
138
136
|
let filesToSync: DiffResult;
|
|
137
|
+
const ref = await currentRefDriver({
|
|
138
|
+
rootDir: tempCloneDir,
|
|
139
|
+
});
|
|
139
140
|
if (localTemplateSyncConfig.afterRef) {
|
|
141
|
+
if (ref === localTemplateSyncConfig.afterRef) {
|
|
142
|
+
// short circuit if the refs match
|
|
143
|
+
return {
|
|
144
|
+
localSkipFiles: [],
|
|
145
|
+
localFileChanges: {},
|
|
146
|
+
modifiedFiles: {
|
|
147
|
+
added: [],
|
|
148
|
+
modified: [],
|
|
149
|
+
deleted: [],
|
|
150
|
+
total: 0,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
140
154
|
filesToSync = await diffDriver(
|
|
141
155
|
tempCloneDir,
|
|
142
156
|
localTemplateSyncConfig.afterRef,
|
|
@@ -202,7 +216,6 @@ export async function templateSync(
|
|
|
202
216
|
added: actualAdded,
|
|
203
217
|
modified: actualModified,
|
|
204
218
|
deleted: actualDeleted,
|
|
205
|
-
total: actualAdded.length + actualModified.length + actualDeleted.length,
|
|
206
219
|
};
|
|
207
220
|
|
|
208
221
|
// apply after ref
|
|
@@ -219,17 +232,25 @@ export async function templateSync(
|
|
|
219
232
|
localConfigPath,
|
|
220
233
|
commentJSON.stringify(config, null, inferJSONIndent(configStr)),
|
|
221
234
|
);
|
|
235
|
+
modifiedFiles.modified.push(localConfigFile);
|
|
222
236
|
} else {
|
|
223
237
|
writeFileSync(
|
|
224
238
|
localConfigPath,
|
|
225
239
|
commentJSON.stringify({ afterRef: ref }, null, 4),
|
|
226
240
|
);
|
|
241
|
+
modifiedFiles.added.push(localConfigFile);
|
|
227
242
|
}
|
|
228
243
|
}
|
|
229
244
|
|
|
230
245
|
return {
|
|
231
246
|
localSkipFiles: Array.from(localSkipFiles),
|
|
232
247
|
localFileChanges,
|
|
233
|
-
modifiedFiles:
|
|
248
|
+
modifiedFiles: {
|
|
249
|
+
...modifiedFiles,
|
|
250
|
+
total:
|
|
251
|
+
modifiedFiles.added.length +
|
|
252
|
+
modifiedFiles.deleted.length +
|
|
253
|
+
modifiedFiles.modified.length,
|
|
254
|
+
},
|
|
234
255
|
};
|
|
235
256
|
}
|