@hanseltime/template-repo-sync 1.3.1 → 2.0.4
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/.github/workflows/release.yaml +18 -7
- package/.github/workflows/test-flow.yaml +3 -3
- package/CHANGELOG.md +40 -0
- package/README.md +75 -35
- package/docs/merge-plugins/CURRENT_PLUGINS.md +3 -3
- package/docs/merge-plugins/{DEVELOPMENT.md → PLUGIN_DEVELOPMENT.md} +18 -25
- package/docs/merge-plugins/README.md +20 -30
- package/jest.config.js +1 -1
- package/lib/cjs/load-plugin.d.ts +8 -1
- package/lib/cjs/load-plugin.js +32 -26
- package/lib/cjs/merge-file.js +22 -33
- package/lib/cjs/plugins/index.d.ts +3 -1
- package/lib/cjs/plugins/index.js +1 -0
- package/lib/cjs/types.d.ts +12 -12
- package/lib/esm/load-plugin.js +32 -26
- package/lib/esm/merge-file.js +22 -33
- package/lib/esm/plugins/index.js +1 -0
- package/package.json +6 -1
- package/release.config.js +7 -1
- package/src/load-plugin.ts +35 -26
- package/src/merge-file.spec.ts +112 -134
- package/src/merge-file.ts +41 -50
- package/src/plugins/index.ts +2 -1
- package/src/template-sync.spec.ts +5 -10
- package/src/types.ts +12 -9
- package/test-fixtures/downstream/templatesync.json +12 -15
- package/test-fixtures/downstream/templatesync.local.json +5 -9
- package/test-fixtures/template/templatesync.json +12 -15
|
@@ -13,16 +13,25 @@ jobs:
|
|
|
13
13
|
with:
|
|
14
14
|
from: ${{ github.workflow }}
|
|
15
15
|
release:
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
id-token: write
|
|
16
19
|
runs-on: ubuntu-latest
|
|
17
20
|
needs: call-test-workflow
|
|
18
21
|
steps:
|
|
19
|
-
-
|
|
22
|
+
# Use our auto-commit permissioned app for our git actions
|
|
23
|
+
- uses: actions/create-github-app-token@v1
|
|
24
|
+
id: app-token
|
|
20
25
|
with:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
app-id: ${{ secrets.AUTO_COMMIT_APP_ID }}
|
|
27
|
+
private-key: ${{ secrets.AUTO_COMMIT_APP_PKEY }}
|
|
28
|
+
- uses: actions/checkout@v6
|
|
24
29
|
with:
|
|
25
|
-
|
|
30
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
31
|
+
- name: Use Node.js 24.x
|
|
32
|
+
uses: actions/setup-node@v6
|
|
33
|
+
with:
|
|
34
|
+
node-version: 24.x
|
|
26
35
|
cache: "npm"
|
|
27
36
|
cache-dependency-path: package-lock.json
|
|
28
37
|
- name: Install
|
|
@@ -32,5 +41,7 @@ jobs:
|
|
|
32
41
|
- name: Release
|
|
33
42
|
run: npm run release
|
|
34
43
|
env:
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
|
|
45
|
+
- name: Test Run
|
|
46
|
+
run: |
|
|
47
|
+
npm publish --access public
|
|
@@ -18,15 +18,15 @@ jobs:
|
|
|
18
18
|
|
|
19
19
|
strategy:
|
|
20
20
|
matrix:
|
|
21
|
-
node-version: [
|
|
21
|
+
node-version: [20.x, 22.x, 24.x]
|
|
22
22
|
|
|
23
23
|
steps:
|
|
24
|
-
- uses: actions/checkout@
|
|
24
|
+
- uses: actions/checkout@v6
|
|
25
25
|
# TODO: caching this action would accelerate the run
|
|
26
26
|
- name: corepack
|
|
27
27
|
run: |
|
|
28
28
|
corepack enable
|
|
29
|
-
- uses: actions/setup-node@
|
|
29
|
+
- uses: actions/setup-node@v6
|
|
30
30
|
with:
|
|
31
31
|
node-version: ${{ matrix.node-version }}
|
|
32
32
|
cache: "npm"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
## [2.0.4](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.0.3...v2.0.4) (2026-02-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* leave semantic release out of npm publish ([9c0d9a3](https://github.com/HanseltimeIndustries/template-repo-sync/commit/9c0d9a389faf34c944640a5a3fc153b038e61b1d))
|
|
7
|
+
|
|
8
|
+
## [2.0.3](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.0.2...v2.0.3) (2026-02-05)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* trigger a new release ([807e84f](https://github.com/HanseltimeIndustries/template-repo-sync/commit/807e84f51eaca42a2607cfbb57d2d672fb84a511))
|
|
14
|
+
|
|
15
|
+
## [2.0.2](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.0.1...v2.0.2) (2026-02-04)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* triger another release due to npm issues ([b6bc9ac](https://github.com/HanseltimeIndustries/template-repo-sync/commit/b6bc9ace83165906707a95ee3aa3a89082cf4d4c))
|
|
21
|
+
|
|
22
|
+
## [2.0.1](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v2.0.0...v2.0.1) (2026-02-04)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* trigger new release ([8a60867](https://github.com/HanseltimeIndustries/template-repo-sync/commit/8a60867539b35222e5074cfccab716f01c8d613d))
|
|
28
|
+
|
|
29
|
+
# [2.0.0](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v1.3.1...v2.0.0) (2026-02-04)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Features
|
|
33
|
+
|
|
34
|
+
* switch to multiple plugins and globs for merge config ([d419c90](https://github.com/HanseltimeIndustries/template-repo-sync/commit/d419c90b1f5e4fc9c8e8b973f1a43bb709267a4a))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### BREAKING CHANGES
|
|
38
|
+
|
|
39
|
+
* The merge field of config is is now an array of plugin configs instead of a map with a single extension
|
|
40
|
+
|
|
1
41
|
## [1.3.1](https://github.com/HanseltimeIndustries/template-repo-sync/compare/v1.3.0...v1.3.1) (2024-06-09)
|
|
2
42
|
|
|
3
43
|
|
package/README.md
CHANGED
|
@@ -13,15 +13,17 @@ best practice development patterns, then we naturally want to have a way to allo
|
|
|
13
13
|
changes, while also having control over things that may be specifically changed due to their need to support something beyond the
|
|
14
14
|
orgnaization standard.
|
|
15
15
|
|
|
16
|
+
<!-- Created with Markdown All In One VsCode Entension, rerun to update -->
|
|
17
|
+
|
|
16
18
|
- [Template Sync](#template-sync)
|
|
17
19
|
- [How to use this](#how-to-use-this)
|
|
18
20
|
- [Config file](#config-file)
|
|
19
21
|
- [File format](#file-format)
|
|
20
22
|
- [Example 1 - Using a custom plugin](#example-1---using-a-custom-plugin)
|
|
21
23
|
- [Example 2 - Using a custom plugin for some paths](#example-2---using-a-custom-plugin-for-some-paths)
|
|
24
|
+
- [Example 3 - First Rule precedence](#example-3---first-rule-precedence)
|
|
22
25
|
- [From SHA/Tag directive](#from-shatag-directive)
|
|
23
26
|
- [Programmatic API](#programmatic-api)
|
|
24
|
-
<!-- Created with Markdown All In One VsCode Entension, rerun to update -->
|
|
25
27
|
|
|
26
28
|
# How to use this
|
|
27
29
|
|
|
@@ -33,7 +35,7 @@ for those who would like to implement the same calls in another CI/CD structure.
|
|
|
33
35
|
There are two types of config files that you can create:
|
|
34
36
|
|
|
35
37
|
- `templatesync.config` in the template repo (this is for the template maintainer to specify how they would expect a roll out
|
|
36
|
-
to update and for them to exclude anything that is more of an example than a standard (for instance, a
|
|
38
|
+
to update and for them to exclude anything that is more of an example than a standard (for instance, a hello world placeholder))
|
|
37
39
|
|
|
38
40
|
- `templatesync.local.config` in the repo that cloned the template. This is meant for the repo maintainers to have the ability to avoid
|
|
39
41
|
or customize updates between the template repo in the event that they have deviated purposefully from it.
|
|
@@ -57,21 +59,31 @@ export interface Config {
|
|
|
57
59
|
/**
|
|
58
60
|
* If there is no merge config, then we will always just overwrite the file for the diff
|
|
59
61
|
*/
|
|
60
|
-
merge:
|
|
62
|
+
merge: [
|
|
61
63
|
/**
|
|
62
|
-
*
|
|
64
|
+
* The first merge rule that matches a file will be applied.
|
|
63
65
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
{
|
|
67
|
+
/**
|
|
68
|
+
* A string or list of strings that would be used by micromatch
|
|
69
|
+
* against the file paths
|
|
70
|
+
*/
|
|
71
|
+
glob: string | string[];
|
|
67
72
|
/**
|
|
68
|
-
*
|
|
73
|
+
* This could be a built-in merge plugin from this library
|
|
74
|
+
* i.e. "_json"
|
|
69
75
|
*
|
|
70
|
-
*
|
|
76
|
+
* It can also be an npm package or a path to a local file with
|
|
77
|
+
* a merge plugin that matches the interface
|
|
78
|
+
*/
|
|
79
|
+
plugin: string;
|
|
80
|
+
/**
|
|
81
|
+
* This is an object of options that correspond to the plugin
|
|
82
|
+
* you specified
|
|
71
83
|
*/
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
84
|
+
options: any;
|
|
85
|
+
},
|
|
86
|
+
];
|
|
75
87
|
}
|
|
76
88
|
```
|
|
77
89
|
|
|
@@ -83,14 +95,15 @@ in the local repo will be merged using the plugin we specified.
|
|
|
83
95
|
|
|
84
96
|
```typescript
|
|
85
97
|
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
98
|
+
merge: [
|
|
99
|
+
{
|
|
100
|
+
// For all .ini packages
|
|
101
|
+
glob: "**/*.ini",
|
|
102
|
+
// If you are running under package manager like yarn or npm,
|
|
103
|
+
// you can provide a valid pacakge or .js fil from your package to run
|
|
104
|
+
plugin: "my-installed-npm-package",
|
|
105
|
+
},
|
|
106
|
+
];
|
|
94
107
|
}
|
|
95
108
|
```
|
|
96
109
|
|
|
@@ -102,25 +115,52 @@ files, only the ones in custom-configs/ will use this merge operator.
|
|
|
102
115
|
|
|
103
116
|
```typescript
|
|
104
117
|
{
|
|
118
|
+
merge: [
|
|
119
|
+
{
|
|
120
|
+
// For all .ini packages
|
|
121
|
+
glob: "custom-configs/**",
|
|
122
|
+
// If you are running under package manager like yarn or npm,
|
|
123
|
+
// you can provide a valid pacakge or .js fil from your package to run
|
|
124
|
+
plugin: "my-installed-npm-package",
|
|
125
|
+
options: {
|
|
126
|
+
myPluginParam: "some parameter",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
```
|
|
105
132
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
### Example 3 - First Rule precedence
|
|
134
|
+
|
|
135
|
+
If you have multiple merge rules that would match a file. The first and only the first rule that matches will be applied.
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
{
|
|
139
|
+
merge: [
|
|
140
|
+
{
|
|
141
|
+
// For all .ini packages
|
|
142
|
+
glob: "custom-configs/**",
|
|
143
|
+
// If you are running under package manager like yarn or npm,
|
|
144
|
+
// you can provide a valid pacakge or .js fil from your package to run
|
|
145
|
+
plugin: "my-installed-npm-package",
|
|
146
|
+
options: {
|
|
147
|
+
myPluginParam: "some parameter",
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
// For all other .ini packages
|
|
152
|
+
glob: "**/*.ini",
|
|
153
|
+
// If you are running under package manager like yarn or npm,
|
|
154
|
+
// you can provide a valid pacakge or .js fil from your package to run
|
|
155
|
+
plugin: "my-installed-npm-package",
|
|
156
|
+
},
|
|
157
|
+
];
|
|
121
158
|
}
|
|
122
159
|
```
|
|
123
160
|
|
|
161
|
+
Note: if you need to do the equivalent of 2 merge plugins for a file, you can use a custom plugin
|
|
162
|
+
that would call both plugins!
|
|
163
|
+
|
|
124
164
|
## From SHA/Tag directive
|
|
125
165
|
|
|
126
166
|
One of the biggest pains of syncing templates is that you can end up seeing a change multiple times because your change has
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Current Merge Plugins
|
|
2
2
|
|
|
3
|
-
This document lists all merge plugins that are provided
|
|
3
|
+
This document lists all merge plugins that are provided as defaults for certain file extensions.
|
|
4
4
|
These should be found in the [plugins folder](src/plugins)
|
|
5
5
|
|
|
6
6
|
- [Current Merge Plugins](#current-merge-plugins)
|
|
@@ -17,6 +17,8 @@ These should be found in the [plugins folder](src/plugins)
|
|
|
17
17
|
|
|
18
18
|
The json merge plugin allows you to configure jsonpath based merges on any .json file.
|
|
19
19
|
|
|
20
|
+
Plugin Field Name: `_json`
|
|
21
|
+
|
|
20
22
|
## Configuration Options:
|
|
21
23
|
|
|
22
24
|
### Simple merge spec
|
|
@@ -85,8 +87,6 @@ interface Options {
|
|
|
85
87
|
|
|
86
88
|
#### Example
|
|
87
89
|
|
|
88
|
-
This
|
|
89
|
-
|
|
90
90
|
```json
|
|
91
91
|
{
|
|
92
92
|
"merge": {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Plugin Development
|
|
2
2
|
|
|
3
3
|
- [Plugin Development](#plugin-development)
|
|
4
|
-
- [Example: hello \<world\>](#example-hello-world)
|
|
5
|
-
|
|
4
|
+
- [Example: hello \<world\>](#example-hello-world)
|
|
5
|
+
- [Example one: local file](#example-one-local-file)
|
|
6
|
+
- [Example two: npm package](#example-two-npm-package)
|
|
6
7
|
|
|
7
8
|
The templatesync.json and templatesync.local.config files make use of a `"merge"` property where you can
|
|
8
9
|
customize the baseline behavior of ignore or overwrite from template.
|
|
@@ -89,19 +90,15 @@ With all of that set up, as long as we have the package available to the pacakge
|
|
|
89
90
|
|
|
90
91
|
```json
|
|
91
92
|
{
|
|
92
|
-
"merge":
|
|
93
|
-
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"world": "chad"
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
]
|
|
93
|
+
"merge": [
|
|
94
|
+
{
|
|
95
|
+
"glob": "**/*.txt",
|
|
96
|
+
"plugin": "dist/hello-plugin.js",
|
|
97
|
+
"options": {
|
|
98
|
+
"world": "chad"
|
|
99
|
+
}
|
|
103
100
|
}
|
|
104
|
-
|
|
101
|
+
]
|
|
105
102
|
}
|
|
106
103
|
```
|
|
107
104
|
|
|
@@ -112,18 +109,14 @@ simply reference the package (assuming that it exposes the required functions as
|
|
|
112
109
|
|
|
113
110
|
```json
|
|
114
111
|
{
|
|
115
|
-
"merge":
|
|
116
|
-
|
|
112
|
+
"merge": [
|
|
113
|
+
{
|
|
114
|
+
"glob": "**/*.txt",
|
|
117
115
|
"plugin": "@myscope/hello-merge",
|
|
118
|
-
"
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"options": {
|
|
122
|
-
"world": "chad"
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
]
|
|
116
|
+
"options": {
|
|
117
|
+
"world": "chad"
|
|
118
|
+
}
|
|
126
119
|
}
|
|
127
|
-
|
|
120
|
+
]
|
|
128
121
|
}
|
|
129
122
|
```
|
|
@@ -26,27 +26,23 @@ set of boilerplate for an npm package, you would probably provide an example pac
|
|
|
26
26
|
|
|
27
27
|
In this scenario, we expect the template user to declare their own `name` and `description`, and add their own
|
|
28
28
|
`scripts` and `devDependencies`. However, we are hoping to make sure that the publish method and and its
|
|
29
|
-
our-artifact-package are kept up-to-date on syncs. Because of this, we would make use of the
|
|
30
|
-
plugin that is
|
|
29
|
+
our-artifact-package are kept up-to-date on syncs. Because of this, we would make use of the built-in json merge
|
|
30
|
+
plugin `_json` that is provided with this library:
|
|
31
31
|
|
|
32
32
|
```json
|
|
33
33
|
{
|
|
34
|
-
"merge":
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
]
|
|
34
|
+
"merge": [
|
|
35
|
+
{
|
|
36
|
+
"glob": "package.json",
|
|
37
|
+
"plugin": "_json",
|
|
38
|
+
"options": {
|
|
39
|
+
"paths": [
|
|
40
|
+
["$.scripts.publish", "merge-template"], // Any changes to publish are so critical that we want them to sync
|
|
41
|
+
["$.devDependencies", "merge-template"] // Always ensure dev dependency versions for our scripts are updated
|
|
42
|
+
]
|
|
43
|
+
}
|
|
48
44
|
}
|
|
49
|
-
|
|
45
|
+
]
|
|
50
46
|
}
|
|
51
47
|
```
|
|
52
48
|
|
|
@@ -61,21 +57,15 @@ config file, they can specify their own merge configuration for the package.json
|
|
|
61
57
|
|
|
62
58
|
```json
|
|
63
59
|
{
|
|
64
|
-
"merge":
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"options": {
|
|
71
|
-
"paths": [
|
|
72
|
-
["$.devDependencies", "merge-template"] // Always ensure dev dependency versions for our scripts are updated
|
|
73
|
-
]
|
|
74
|
-
}
|
|
75
|
-
}
|
|
60
|
+
"merge": [
|
|
61
|
+
{
|
|
62
|
+
"glob": "package.json",
|
|
63
|
+
"plugin": "_json",
|
|
64
|
+
"paths": [
|
|
65
|
+
["$.devDependencies", "merge-template"] // Always ensure dev dependency versions for our scripts are updated
|
|
76
66
|
]
|
|
77
67
|
}
|
|
78
|
-
|
|
68
|
+
]
|
|
79
69
|
}
|
|
80
70
|
```
|
|
81
71
|
|
package/jest.config.js
CHANGED
package/lib/cjs/load-plugin.d.ts
CHANGED
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import { MergeConfig, MergePlugin } from "./types";
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Loads the plugin associated with the merge config
|
|
4
|
+
* @param mergeConfig
|
|
5
|
+
* @param forExt
|
|
6
|
+
* @param configDir
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadPlugin<T>(mergeConfig: MergeConfig<T>, configDir: string): Promise<MergePlugin<T>>;
|
package/lib/cjs/load-plugin.js
CHANGED
|
@@ -27,36 +27,42 @@ exports.loadPlugin = void 0;
|
|
|
27
27
|
const plugins_1 = require("./plugins");
|
|
28
28
|
const fs_1 = require("fs");
|
|
29
29
|
const path_1 = require("path");
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Loads the plugin associated with the merge config
|
|
32
|
+
* @param mergeConfig
|
|
33
|
+
* @param forExt
|
|
34
|
+
* @param configDir
|
|
35
|
+
* @returns
|
|
36
|
+
*/
|
|
37
|
+
async function loadPlugin(mergeConfig, configDir) {
|
|
38
|
+
if (mergeConfig.plugin.startsWith("_")) {
|
|
39
|
+
const defaultHandler = Object.values(plugins_1.defaultExtensionMap).find((el) => el.builtinName === mergeConfig.plugin);
|
|
40
|
+
if (!defaultHandler) {
|
|
41
|
+
throw new Error(`No builtin merge function supplied for ${mergeConfig.plugin}. Cannot have merge config without custom plugin supplied.`);
|
|
42
|
+
}
|
|
43
|
+
return defaultHandler;
|
|
44
|
+
}
|
|
31
45
|
let handler;
|
|
32
|
-
if
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
handler = require(importPath);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
handler = (await Promise.resolve(`${importPath}`).then(s => __importStar(require(s))));
|
|
44
|
-
}
|
|
45
|
-
if (!handler.merge) {
|
|
46
|
-
handler = handler
|
|
47
|
-
.default;
|
|
48
|
-
}
|
|
46
|
+
// First check if this is a local .js file
|
|
47
|
+
const localPath = (0, path_1.resolve)(configDir, mergeConfig.plugin);
|
|
48
|
+
const importPath = (0, fs_1.existsSync)(localPath) ? localPath : mergeConfig.plugin;
|
|
49
|
+
try {
|
|
50
|
+
// Sad workaround for testing since dynamic import segfaults
|
|
51
|
+
if (process.env.JEST_WORKER_ID !== undefined) {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
53
|
+
handler = require(importPath);
|
|
49
54
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
throw err;
|
|
55
|
+
else {
|
|
56
|
+
handler = (await Promise.resolve(`${importPath}`).then(s => __importStar(require(s))));
|
|
53
57
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
throw new Error(`No default merge function supplied for ${forExt}. Cannot have mere config without custom plugin supplied.`);
|
|
58
|
+
if (!handler.merge) {
|
|
59
|
+
handler = handler
|
|
60
|
+
.default;
|
|
58
61
|
}
|
|
59
|
-
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
console.error(err);
|
|
65
|
+
throw err;
|
|
60
66
|
}
|
|
61
67
|
return handler;
|
|
62
68
|
}
|
package/lib/cjs/merge-file.js
CHANGED
|
@@ -26,50 +26,39 @@ async function mergeFile(relPath, context) {
|
|
|
26
26
|
const ext = (0, path_1.extname)(relPath);
|
|
27
27
|
const filePath = (0, path_1.join)(cwd, relPath);
|
|
28
28
|
const templatePath = (0, path_1.join)(tempCloneDir, relPath);
|
|
29
|
-
const mergeConfig = templateSyncConfig.merge?.
|
|
30
|
-
const localMergeConfig = localTemplateSyncConfig.merge?.
|
|
31
|
-
|
|
29
|
+
const mergeConfig = templateSyncConfig.merge?.find((mergeConfig) => (0, micromatch_1.isMatch)(relPath, mergeConfig.glob));
|
|
30
|
+
const localMergeConfig = localTemplateSyncConfig.merge?.find((mergeConfig) => (0, micromatch_1.isMatch)(relPath, mergeConfig.glob));
|
|
31
|
+
const mergeHandler = mergeConfig
|
|
32
|
+
? await (0, load_plugin_1.loadPlugin)(mergeConfig, tempCloneDir)
|
|
33
|
+
: undefined;
|
|
34
|
+
const localMergeHandler = localMergeConfig
|
|
35
|
+
? await (0, load_plugin_1.loadPlugin)(localMergeConfig, cwd)
|
|
36
|
+
: undefined;
|
|
37
|
+
// Either write the merge or write the file
|
|
32
38
|
let fileContents;
|
|
33
39
|
const localChanges = [];
|
|
34
|
-
if ((0, fs_1.existsSync)(filePath) && (
|
|
40
|
+
if ((0, fs_1.existsSync)(filePath) && (mergeHandler || localMergeHandler)) {
|
|
35
41
|
const originalCurrentFile = (await (0, promises_1.readFile)(filePath)).toString();
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
if (mergeHandler) {
|
|
43
|
+
fileContents = await safeMerge(mergeHandler, mergeConfig?.plugin ?? `default for ${ext}`, originalCurrentFile, (await (0, promises_1.readFile)(templatePath)).toString(), {
|
|
44
|
+
relFilePath: relPath,
|
|
45
|
+
mergeArguments: mergeConfig?.options ?? {},
|
|
46
|
+
isLocalOptions: false,
|
|
41
47
|
});
|
|
42
|
-
if (mergeOptions) {
|
|
43
|
-
fileContents = await safeMerge(handler, mergeConfig.plugin ?? `default for ${ext}`, originalCurrentFile, (await (0, promises_1.readFile)(templatePath)).toString(), {
|
|
44
|
-
relFilePath: relPath,
|
|
45
|
-
mergeArguments: mergeOptions.options,
|
|
46
|
-
isLocalOptions: true,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
// Apply overwrite if we didn't set up merge
|
|
51
|
-
fileContents = (await (0, promises_1.readFile)(templatePath)).toString();
|
|
52
|
-
}
|
|
53
48
|
}
|
|
54
49
|
else {
|
|
55
50
|
// Apply overwrite if we didn't set up merge
|
|
56
51
|
fileContents = (await (0, promises_1.readFile)(templatePath)).toString();
|
|
57
52
|
}
|
|
58
53
|
// We apply the localMerge Config to the fileContent output by the template merge
|
|
59
|
-
if (
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
if (localMergeHandler) {
|
|
55
|
+
const localContents = await safeMerge(localMergeHandler, localMergeConfig?.plugin ?? `default for ${ext}`, originalCurrentFile, fileContents, {
|
|
56
|
+
relFilePath: relPath,
|
|
57
|
+
mergeArguments: localMergeConfig?.options ?? {},
|
|
58
|
+
isLocalOptions: true,
|
|
63
59
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
relFilePath: relPath,
|
|
67
|
-
mergeArguments: mergeOptions.options,
|
|
68
|
-
isLocalOptions: true,
|
|
69
|
-
});
|
|
70
|
-
localChanges.push(...(0, diff_1.diffLines)(fileContents, localContents));
|
|
71
|
-
fileContents = localContents;
|
|
72
|
-
}
|
|
60
|
+
localChanges.push(...(0, diff_1.diffLines)(fileContents, localContents));
|
|
61
|
+
fileContents = localContents;
|
|
73
62
|
}
|
|
74
63
|
}
|
|
75
64
|
else {
|
package/lib/cjs/plugins/index.js
CHANGED
package/lib/cjs/types.d.ts
CHANGED
|
@@ -30,18 +30,22 @@ type MergePluginOptions = JsonFileMergeOptions;
|
|
|
30
30
|
* Configuration object for a given file type merge configuration
|
|
31
31
|
*/
|
|
32
32
|
export interface MergeConfig<T> {
|
|
33
|
+
/**
|
|
34
|
+
* A glob or array of globs (using micromatch syntax) that selects the files that this applies to
|
|
35
|
+
* when merging
|
|
36
|
+
*/
|
|
37
|
+
glob: string | string[];
|
|
33
38
|
/**
|
|
34
39
|
* The node module, available on the calling node context, that you want to run.
|
|
35
|
-
*
|
|
40
|
+
* Built-in plugins can be specified via their built-in name (see documentation):
|
|
41
|
+
*
|
|
42
|
+
* Example: _json
|
|
36
43
|
*/
|
|
37
|
-
plugin
|
|
44
|
+
plugin: string;
|
|
38
45
|
/**
|
|
39
46
|
* An array of first match file globs that will then call the plugin with the appropriate options
|
|
40
47
|
*/
|
|
41
|
-
|
|
42
|
-
glob: string;
|
|
43
|
-
options: MergePluginOptions | T;
|
|
44
|
-
}[];
|
|
48
|
+
options: MergePluginOptions | T;
|
|
45
49
|
}
|
|
46
50
|
/**
|
|
47
51
|
* The shape of a template sync config file
|
|
@@ -51,9 +55,7 @@ export interface Config<T = unknown> {
|
|
|
51
55
|
/**
|
|
52
56
|
* If there is no merge config, then we will always just overwrite the file for the diff
|
|
53
57
|
*/
|
|
54
|
-
merge?:
|
|
55
|
-
[fileExt: string]: MergeConfig<T>;
|
|
56
|
-
};
|
|
58
|
+
merge?: MergeConfig<T>[];
|
|
57
59
|
}
|
|
58
60
|
/**
|
|
59
61
|
* The shape of a local template sync config file that overrides the root template repo
|
|
@@ -68,9 +70,7 @@ export interface LocalConfig<T = unknown> {
|
|
|
68
70
|
/**
|
|
69
71
|
* If there is no merge config, then we will always just overwrite the file for the diff
|
|
70
72
|
*/
|
|
71
|
-
merge?:
|
|
72
|
-
[fileExt: string]: MergeConfig<T>;
|
|
73
|
-
};
|
|
73
|
+
merge?: MergeConfig<T>[];
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Information around the file we are trying to merge and that arguments for that merge
|