sfdx-git-delta 4.12.1 → 5.0.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/CHANGELOG.md +16 -0
- package/README.md +30 -35
- package/lib/commands/sgd/source/delta.js +8 -8
- package/lib/commands/sgd/source/delta.js.map +1 -1
- package/lib/main.d.ts +2 -2
- package/lib/main.js +16 -18
- package/lib/main.js.map +1 -1
- package/lib/metadata/metadataManager.d.ts +1 -1
- package/lib/metadata/metadataManager.js +8 -8
- package/lib/metadata/metadataManager.js.map +1 -1
- package/lib/metadata/v54.json +1321 -0
- package/lib/service/botHandler.js +8 -8
- package/lib/service/botHandler.js.map +1 -1
- package/lib/service/customObjectHandler.d.ts +1 -1
- package/lib/service/customObjectHandler.js +20 -16
- package/lib/service/customObjectHandler.js.map +1 -1
- package/lib/service/inFileHandler.d.ts +5 -5
- package/lib/service/inFileHandler.js +34 -34
- package/lib/service/inFileHandler.js.map +1 -1
- package/lib/service/inFolderHandler.js +9 -11
- package/lib/service/inFolderHandler.js.map +1 -1
- package/lib/service/inResourceHandler.d.ts +1 -1
- package/lib/service/inResourceHandler.js +21 -21
- package/lib/service/inResourceHandler.js.map +1 -1
- package/lib/service/inTranslationHandler.js +6 -6
- package/lib/service/inTranslationHandler.js.map +1 -1
- package/lib/service/standardHandler.d.ts +10 -10
- package/lib/service/standardHandler.js +46 -29
- package/lib/service/standardHandler.js.map +1 -1
- package/lib/service/subCustomObjectHandler.js +8 -8
- package/lib/service/subCustomObjectHandler.js.map +1 -1
- package/lib/service/typeHandlerFactory.js +2 -2
- package/lib/service/typeHandlerFactory.js.map +1 -1
- package/lib/service/waveHandler.js +2 -2
- package/lib/service/waveHandler.js.map +1 -1
- package/lib/utils/asyncFilter.d.ts +2 -0
- package/lib/utils/asyncFilter.js +3 -0
- package/lib/utils/asyncFilter.js.map +1 -0
- package/lib/utils/childProcessUtils.d.ts +2 -2
- package/lib/utils/childProcessUtils.js +21 -9
- package/lib/utils/childProcessUtils.js.map +1 -1
- package/lib/utils/cliHelper.d.ts +4 -2
- package/lib/utils/cliHelper.js +51 -23
- package/lib/utils/cliHelper.js.map +1 -1
- package/lib/utils/fileGitDiff.d.ts +1 -1
- package/lib/utils/fileGitDiff.js +7 -7
- package/lib/utils/fileGitDiff.js.map +1 -1
- package/lib/utils/packageConstructor.js +11 -4
- package/lib/utils/packageConstructor.js.map +1 -1
- package/lib/utils/repoGitDiff.d.ts +15 -6
- package/lib/utils/repoGitDiff.js +79 -49
- package/lib/utils/repoGitDiff.js.map +1 -1
- package/lib/utils/repoSetup.d.ts +6 -3
- package/lib/utils/repoSetup.js +17 -20
- package/lib/utils/repoSetup.js.map +1 -1
- package/lib/utils/typeUtils.js +3 -3
- package/lib/utils/typeUtils.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +9 -13
- package/bin/cli +0 -57
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [5.0.0](https://github.com/scolladon/sfdx-git-delta/compare/v4.12.1...v5.0.0) (2022-03-11)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* sgd single node executable is not shipped anymore
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* decommissionate sgd ([#221](https://github.com/scolladon/sfdx-git-delta/issues/221)) ([ecd146f](https://github.com/scolladon/sfdx-git-delta/commit/ecd146f0e6480f68bbf08362e3a535c7f0fe24ba))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
* pull request CI base commit ([#253](https://github.com/scolladon/sfdx-git-delta/issues/253)) ([163ee52](https://github.com/scolladon/sfdx-git-delta/commit/163ee5245ce79bbcb44323bfb249b7437d88c51c))
|
|
20
|
+
|
|
5
21
|
### [4.12.1](https://github.com/scolladon/sfdx-git-delta/compare/v4.12.0...v4.12.1) (2022-01-05)
|
|
6
22
|
|
|
7
23
|
|
package/README.md
CHANGED
|
@@ -13,19 +13,7 @@ sfdx sgd:source:delta --to "HEAD" --from "HEAD^" --output "."
|
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
```sh
|
|
16
|
-
|
|
17
|
-
cat package/package.xml
|
|
18
|
-
echo
|
|
19
|
-
echo "---- Deploying added and modified metadata ----"
|
|
20
|
-
sfdx force:source:deploy -x package/package.xml
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
echo "--- destructiveChanges.xml generated with deleted metadata ---"
|
|
25
|
-
cat destructiveChanges/destructiveChanges.xml
|
|
26
|
-
echo
|
|
27
|
-
echo "--- Deleting removed metadata ---"
|
|
28
|
-
sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings
|
|
16
|
+
sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml
|
|
29
17
|
```
|
|
30
18
|
|
|
31
19
|
## What is SFDX-Git-Delta?
|
|
@@ -53,7 +41,7 @@ If you are a Technical Architect or Developer, then it’s a very useful tool fo
|
|
|
53
41
|
|
|
54
42
|
SGD is designed to be part of a CI/CD pipeline (Jenkins, Bitbucket Pipelines, GitLab CI, GitHub Actions, Azure DevOps...) that handles the deployment of the sources to the Salesforce org(s).
|
|
55
43
|
|
|
56
|
-
Pro tips: If you are in the process of building your CI/CD pipeline, make sure you already have a fully
|
|
44
|
+
Pro tips: If you are in the process of building your CI/CD pipeline, make sure you already have a fully functional pipeline **before** implementing delta deployments (otherwise it will just make it harder to debug your pipeline). It's also important to implement a bypass in your pipeline, to have the ability to fallback to full deployment in case the delta deployment is not behaving the way you expected it.
|
|
57
45
|
|
|
58
46
|
**DISCLAIMER:**
|
|
59
47
|
|
|
@@ -75,7 +63,7 @@ Because this plugin is not signed, you will get a warning saying that "This plug
|
|
|
75
63
|
|
|
76
64
|
If you run your CI/CD jobs inside a Docker image, you can add the plugin to your image. Here is an example of a Dockerfile including the SGD plugin: https://github.com/mehdisfdc/sfdx-cli-gitlab
|
|
77
65
|
|
|
78
|
-
⚠️ The Salesforce CLI plugin is now the only supported way to install SGD. There used to be another way to install it directly through yarn or npm. The legacy `sgd` command is now deprecated and
|
|
66
|
+
⚠️ The Salesforce CLI plugin is now the only supported way to install SGD. There used to be another way to install it directly through yarn or npm. The legacy `sgd` command is now deprecated and decommissioned.
|
|
79
67
|
|
|
80
68
|
### Prerequisites
|
|
81
69
|
|
|
@@ -110,7 +98,7 @@ OPTIONS
|
|
|
110
98
|
-W, --ignore-whitespace ignore git diff whitespace (space,
|
|
111
99
|
tab, eol) changes
|
|
112
100
|
|
|
113
|
-
-a, --api-version=api-version [default:
|
|
101
|
+
-a, --api-version=api-version [default: 54] salesforce API version
|
|
114
102
|
|
|
115
103
|
-d, --generate-delta generate delta files in [--output]
|
|
116
104
|
folder
|
|
@@ -142,7 +130,7 @@ OPTIONS
|
|
|
142
130
|
this command invocation
|
|
143
131
|
```
|
|
144
132
|
|
|
145
|
-
_See code: [src/commands/sgd/source/delta.ts](https://github.com/scolladon/sfdx-git-delta/blob/
|
|
133
|
+
_See code: [src/commands/sgd/source/delta.ts](https://github.com/scolladon/sfdx-git-delta/blob/v5.0.0/src/commands/sgd/source/delta.ts)_
|
|
146
134
|
<!-- commandsstop -->
|
|
147
135
|
|
|
148
136
|
### Important note for Windows users:
|
|
@@ -167,7 +155,7 @@ In our example, the latest commit to main is composed of:
|
|
|
167
155
|
In this situation, we would expect the CI pipeline to:
|
|
168
156
|
|
|
169
157
|
1. **Deploy to Production only 3 classes** (no matter how much metadata is present in the force-app folder): `TriggerHandler`, `TriggerHandler_Test`, and `TestDataFactory`
|
|
170
|
-
2. **Delete from Production 1
|
|
158
|
+
2. **Delete from Production 1 class**: `AnotherTriggerFramework`
|
|
171
159
|
|
|
172
160
|
So let’s do it!
|
|
173
161
|
|
|
@@ -197,9 +185,21 @@ _Content of the `destructiveChanges.xml` file in our scenario:_
|
|
|
197
185
|
|
|
198
186
|
In addition, we also could have generated a copy of the **force-app** folder with only the added and changed metadata, by using the `--generate-delta (-d)` option (more on that later).
|
|
199
187
|
|
|
200
|
-
### Deploy
|
|
188
|
+
### Deploy the delta metadata:
|
|
189
|
+
|
|
190
|
+
The simplest option to deploy the delta changes is to use `force:source:deploy`:
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
sfdx force:source:deploy -x package/package.xml --postdestructivechanges destructiveChanges/destructiveChanges.xml
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
And voilà! 🥳
|
|
197
|
+
|
|
198
|
+
However, keep in mind that the above command will fail if the destructive change was meant to be executed before the deployment (i.e. as `--predestructivechanges`), or if a warning occurs. Make sure to handle those error scenarios in your CI/CD pipeline, so that you don't get stuck by a failed destructive change.
|
|
199
|
+
|
|
200
|
+
If needed, you can also separate the deploy of added/modified metadata and the destructive deployment, as in the below examples:
|
|
201
201
|
|
|
202
|
-
|
|
202
|
+
Use the `package/package.xml` file to deploy only the added/modified metadata:
|
|
203
203
|
|
|
204
204
|
```sh
|
|
205
205
|
echo "--- package.xml generated with added and modified metadata ---"
|
|
@@ -209,9 +209,7 @@ echo "---- Deploying added and modified metadata ----"
|
|
|
209
209
|
sfdx force:source:deploy -x package/package.xml
|
|
210
210
|
```
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
The CI pipeline can use the `destructiveChanges` folder to deploy the corresponding destructive change:
|
|
212
|
+
Use the `destructiveChanges` folder to deploy only the destructive changes:
|
|
215
213
|
|
|
216
214
|
```sh
|
|
217
215
|
echo "--- destructiveChanges.xml generated with deleted metadata ---"
|
|
@@ -221,8 +219,6 @@ echo "--- Deleting removed metadata ---"
|
|
|
221
219
|
sfdx force:mdapi:deploy -d destructiveChanges --ignorewarnings
|
|
222
220
|
```
|
|
223
221
|
|
|
224
|
-
And voilà! 🥳
|
|
225
|
-
|
|
226
222
|
### Diff between branches:
|
|
227
223
|
|
|
228
224
|
SGD works with any git sha pointer: commit sha, branch, tag, git expression (HEAD, etc.).
|
|
@@ -254,9 +250,9 @@ sfdx sgd:source:delta --to develop --from $(git merge-base develop main) --outpu
|
|
|
254
250
|
|
|
255
251
|
### Generate a folder containing only the added/modified sources:
|
|
256
252
|
|
|
257
|
-
Using a package.xml file to deploy a subset of the metadata is
|
|
253
|
+
Using a package.xml file to deploy a subset of the metadata is probably the simplest approach to delta deployments. But there are some situations where you may want to have the actual source files related to all the components that have been changed recently.
|
|
258
254
|
|
|
259
|
-
One example is to speed up object deployments: the package.xml approach will result on the entire sub-folder for a given object to be deployed. On the opposite, having a copy of the actual sources added/modified allows you to
|
|
255
|
+
One example is to speed up object deployments: the package.xml approach will result on the entire sub-folder for a given object to be deployed. On the opposite, having a copy of the actual sources added/modified allows you to chirurgically deploy only the modified components.
|
|
260
256
|
|
|
261
257
|
This is where the `--generate-delta (-d)` option comes handy!
|
|
262
258
|
|
|
@@ -267,7 +263,7 @@ mkdir changed-sources
|
|
|
267
263
|
sfdx sgd:source:delta --to "HEAD" --from "HEAD^" --output changed-sources/ --generate-delta
|
|
268
264
|
```
|
|
269
265
|
|
|
270
|
-
In addition to the `package` and `destructiveChanges` folders, the `sfdx sgd:source:delta` command will also produce a copy of the added/changed files in the
|
|
266
|
+
In addition to the `package` and `destructiveChanges` folders, the `sfdx sgd:source:delta` command will also produce a copy of the added/changed files in the output folder.
|
|
271
267
|
|
|
272
268
|
_Content of the output folder when using the --generate-delta option, with the same scenario as above:_
|
|
273
269
|
|
|
@@ -293,7 +289,7 @@ But, sometimes you may need to have two different ignore policies for generating
|
|
|
293
289
|
|
|
294
290
|
Use the `--ignore-destructive` parameter to specify a dedicated ignore file to handle deletions (resulting in metadata listed in the `destructiveChanges.xml` output). In other words, this will override the `--ignore [-i]` parameter for deleted items.
|
|
295
291
|
|
|
296
|
-
For example, consider a repository containing multiple sub-folders (force-app/main,force-app/sample, etc) and a commit deleting the Custom\_\_c object from one folder and modifying the Custom\_\_c object from another folder. This event will be treated has a Modification and a Deletion. By default, the Custom\_\_c object would appear in the `package.xml` and in `destructiveChanges.xml`, which could be a little bit inconsistent and can break the CI/CD build. This is a situation where your may want to use the `--ignore-destructive [-D]` parameter! Add the Custom\_\_c object pattern in an ignore file and pass it in the CLI parameter:
|
|
292
|
+
For example, consider a repository containing multiple sub-folders (force-app/main, force-app/sample, etc) and a commit deleting the Custom\_\_c object from one folder and modifying the Custom\_\_c object from another folder. This event will be treated has a Modification and a Deletion. By default, the Custom\_\_c object would appear in the `package.xml` and in `destructiveChanges.xml`, which could be a little bit inconsistent and can break the CI/CD build. This is a situation where your may want to use the `--ignore-destructive [-D]` parameter! Add the Custom\_\_c object pattern in an ignore file and pass it in the CLI parameter:
|
|
297
293
|
|
|
298
294
|
```sh
|
|
299
295
|
# destructiveignore
|
|
@@ -328,7 +324,7 @@ $ sfdx sgd:source:delta --from commit --include-destructive destructiveinclude
|
|
|
328
324
|
The `--source [-s]`parameter allows you to specify a folder to focus on, making any other folder ignored.
|
|
329
325
|
It means the delta generation will only focus on the dedicated folder.
|
|
330
326
|
|
|
331
|
-
For example, consider a repository containing multiple sub-folders (force-app/package,force-app/unpackaged, etc).
|
|
327
|
+
For example, consider a repository containing multiple sub-folders (force-app/package, force-app/unpackaged, etc).
|
|
332
328
|
This repository contains sources deployed in a packaged (force-app/package folder) and sources deployed unpackaged (force-app/unpackaged)
|
|
333
329
|
You only want to apply delta generation for the unpackaged sources.
|
|
334
330
|
|
|
@@ -352,11 +348,11 @@ $ sfdx sgd:source:delta --from commit --source force-app/unpackaged
|
|
|
352
348
|
|
|
353
349
|
### Generate a comma-separated list of the added and modified Apex classes:
|
|
354
350
|
|
|
355
|
-
Depending on your testing strategy, [you may be interested in generating a
|
|
351
|
+
Depending on your testing strategy, [you may be interested in generating a comma-separated list of the added and modified Apex classes](https://github.com/scolladon/sfdx-git-delta/issues/126) (to use in the `sfdx force:source:deploy --testlevel RunSpecifiedTests` command, for example).
|
|
356
352
|
|
|
357
353
|
To cover this requirement, you can use a tool such as [yq](https://github.com/kislyuk/yq) to parse the content of the package.xml file produced by SGD:
|
|
358
354
|
|
|
359
|
-
`xq . < package/package.xml | jq '.Package.types |
|
|
355
|
+
`xq . < package/package.xml | jq '.Package.types | [.] | flatten | map(select(.name=="ApexClass")) | .[] | .members | [.] | flatten | map(select(. | index("*") | not)) | unique | join(",")'`
|
|
360
356
|
|
|
361
357
|
### Use the module in your own node application
|
|
362
358
|
|
|
@@ -366,13 +362,13 @@ If you want to embed sgd in your node application, install it has a dependency f
|
|
|
366
362
|
yarn add sfdx-git-delta
|
|
367
363
|
```
|
|
368
364
|
|
|
369
|
-
Then use the
|
|
365
|
+
Then use the JavaScript module
|
|
370
366
|
|
|
371
367
|
```js
|
|
372
368
|
// sample/app.js
|
|
373
369
|
const sgd = require('sfdx-git-delta')
|
|
374
370
|
|
|
375
|
-
const work = sgd({
|
|
371
|
+
const work = await sgd({
|
|
376
372
|
to: '', // commit sha to where the diff is done. [default : "HEAD"]
|
|
377
373
|
from: '', // (required) commit sha from where the diff is done. [default : git rev-list --max-parents=0 HEAD]
|
|
378
374
|
output: '', // source package specific output. [default : "./output"]
|
|
@@ -391,7 +387,6 @@ console.log(JSON.stringify(work))
|
|
|
391
387
|
|
|
392
388
|
## Built With
|
|
393
389
|
|
|
394
|
-
- [commander](https://github.com/tj/commander.js/) - The complete solution for node.js command-line interfaces, inspired by Ruby's commander.
|
|
395
390
|
- [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) - Validate XML, Parse XML to JS/JSON and vise versa, or parse XML to Nimn rapidly without C/C++ based libraries and no callback
|
|
396
391
|
- [fs-extra](https://github.com/jprichardson/node-fs-extra) - Node.js: extra methods for the fs object like copy(), remove(), mkdirs().
|
|
397
392
|
- [ignore](https://github.com/kaelzhang/node-ignore#readme) - is a manager, filter and parser which implemented in pure JavaScript according to the .gitignore spec 2.22.1.
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const command_1 = require("@salesforce/command");
|
|
4
4
|
const core_1 = require("@salesforce/core");
|
|
5
5
|
const sgd = require("../../../main");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const { TO_DEFAULT_VALUE, REPO_DEFAULT_VALUE, SOURCE_DEFAULT_VALUE, OUTPUT_DEFAULT_VALUE, } = require('../../../utils/cliHelper');
|
|
7
|
+
const { sfdc: { latestApiVersion }, } = require('../../../../package.json');
|
|
8
8
|
// Initialize Messages with the current plugin directory
|
|
9
9
|
core_1.Messages.importMessagesDirectory(__dirname);
|
|
10
10
|
const COMMAND_NAME = 'delta';
|
|
@@ -21,7 +21,7 @@ class SourceDeltaGenerate extends command_1.SfdxCommand {
|
|
|
21
21
|
warnings: [],
|
|
22
22
|
};
|
|
23
23
|
try {
|
|
24
|
-
const jobResult = sgd({
|
|
24
|
+
const jobResult = await sgd({
|
|
25
25
|
to: this.flags.to,
|
|
26
26
|
from: this.flags.from,
|
|
27
27
|
output: this.flags.output,
|
|
@@ -52,7 +52,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
52
52
|
to: command_1.flags.string({
|
|
53
53
|
char: 't',
|
|
54
54
|
description: messages.getMessage('toFlag'),
|
|
55
|
-
default:
|
|
55
|
+
default: TO_DEFAULT_VALUE,
|
|
56
56
|
}),
|
|
57
57
|
from: command_1.flags.string({
|
|
58
58
|
char: 'f',
|
|
@@ -62,7 +62,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
62
62
|
repo: command_1.flags.filepath({
|
|
63
63
|
char: 'r',
|
|
64
64
|
description: messages.getMessage('repoFlag'),
|
|
65
|
-
default:
|
|
65
|
+
default: REPO_DEFAULT_VALUE,
|
|
66
66
|
}),
|
|
67
67
|
ignore: command_1.flags.filepath({
|
|
68
68
|
char: 'i',
|
|
@@ -75,7 +75,7 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
75
75
|
source: command_1.flags.filepath({
|
|
76
76
|
char: 's',
|
|
77
77
|
description: messages.getMessage('sourceFlag'),
|
|
78
|
-
default:
|
|
78
|
+
default: SOURCE_DEFAULT_VALUE,
|
|
79
79
|
}),
|
|
80
80
|
'ignore-whitespace': command_1.flags.boolean({
|
|
81
81
|
char: 'W',
|
|
@@ -84,12 +84,12 @@ SourceDeltaGenerate.flagsConfig = {
|
|
|
84
84
|
output: command_1.flags.filepath({
|
|
85
85
|
char: 'o',
|
|
86
86
|
description: messages.getMessage('outputFlag'),
|
|
87
|
-
default:
|
|
87
|
+
default: OUTPUT_DEFAULT_VALUE,
|
|
88
88
|
}),
|
|
89
89
|
'api-version': command_1.flags.number({
|
|
90
90
|
char: 'a',
|
|
91
91
|
description: messages.getMessage('apiVersionFlag'),
|
|
92
|
-
default: parseFloat(
|
|
92
|
+
default: parseFloat(latestApiVersion),
|
|
93
93
|
}),
|
|
94
94
|
'generate-delta': command_1.flags.boolean({
|
|
95
95
|
char: 'd',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../../src/commands/sgd/source/delta.ts"],"names":[],"mappings":";;AAAA,iDAAwD;AACxD,2CAA2C;AAE3C,qCAAoC;AACpC,MAAM,
|
|
1
|
+
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../../../src/commands/sgd/source/delta.ts"],"names":[],"mappings":";;AAAA,iDAAwD;AACxD,2CAA2C;AAE3C,qCAAoC;AACpC,MAAM,EACJ,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,GACrB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAA;AACvC,MAAM,EACJ,IAAI,EAAE,EAAE,gBAAgB,EAAE,GAC3B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAA;AAEvC,wDAAwD;AACxD,eAAQ,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAA;AAC3C,MAAM,YAAY,GAAG,OAAO,CAAA;AAE5B,iGAAiG;AACjG,mFAAmF;AACnF,MAAM,QAAQ,GAAG,eAAQ,CAAC,YAAY,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAA;AAEtE,MAAqB,mBAAoB,SAAQ,qBAAW;IA4DnD,KAAK,CAAC,GAAG;;QACd,MAAM,MAAM,GAAG;YACb,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YACzB,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,EAAE;SACb,CAAA;QACD,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC;gBAC1B,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE;gBACjB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;gBACrB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;gBACzB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;gBACzB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;gBACzB,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC;gBACnD,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;gBACrC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;gBACrB,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC;gBACjD,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;gBAC3C,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;gBAC3B,kBAAkB,EAAE,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC;aACtD,CAAC,CAAA;YACF,MAAM,CAAC,QAAQ,GAAG,MAAA,SAAS,aAAT,SAAS,uBAAT,SAAS,CAAE,QAAQ,0CAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;SACvE;QAAC,OAAO,GAAG,EAAE;YACZ,MAAM,CAAC,OAAO,GAAG,KAAK,CAAA;YACtB,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,OAAO,CAAA;YAC1B,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;SACrB;QACD,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5C,OAAO,IAAI,CAAA;IACb,CAAC;;AA1FH,sCA2FC;AA1Fe,+BAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;AAE7C,+BAAW,GAAG;IAC7B,EAAE,EAAE,eAAK,CAAC,MAAM,CAAC;QACf,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC;QAC1C,OAAO,EAAE,gBAAgB;KAC1B,CAAC;IACF,IAAI,EAAE,eAAK,CAAC,MAAM,CAAC;QACjB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAC5C,QAAQ,EAAE,IAAI;KACf,CAAC;IACF,IAAI,EAAE,eAAK,CAAC,QAAQ,CAAC;QACnB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QAC5C,OAAO,EAAE,kBAAkB;KAC5B,CAAC;IACF,MAAM,EAAE,eAAK,CAAC,QAAQ,CAAC;QACrB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;KAC/C,CAAC;IACF,oBAAoB,EAAE,eAAK,CAAC,QAAQ,CAAC;QACnC,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,uBAAuB,CAAC;KAC1D,CAAC;IACF,MAAM,EAAE,eAAK,CAAC,QAAQ,CAAC;QACrB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAC9C,OAAO,EAAE,oBAAoB;KAC9B,CAAC;IACF,mBAAmB,EAAE,eAAK,CAAC,OAAO,CAAC;QACjC,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC;KACzD,CAAC;IACF,MAAM,EAAE,eAAK,CAAC,QAAQ,CAAC;QACrB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QAC9C,OAAO,EAAE,oBAAoB;KAC9B,CAAC;IACF,aAAa,EAAE,eAAK,CAAC,MAAM,CAAC;QAC1B,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAClD,OAAO,EAAE,UAAU,CAAC,gBAAgB,CAAC;KACtC,CAAC;IACF,gBAAgB,EAAE,eAAK,CAAC,OAAO,CAAC;QAC9B,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC;KAC9C,CAAC;IACF,OAAO,EAAE,eAAK,CAAC,QAAQ,CAAC;QACtB,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC;KAChD,CAAC;IACF,qBAAqB,EAAE,eAAK,CAAC,QAAQ,CAAC;QACpC,IAAI,EAAE,GAAG;QACT,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;KAC3D,CAAC;CACH,CAAA"}
|
package/lib/main.d.ts
CHANGED
package/lib/main.js
CHANGED
|
@@ -4,37 +4,35 @@ const TypeHandlerFactory = require('./service/typeHandlerFactory');
|
|
|
4
4
|
const metadataManager = require('./metadata/metadataManager');
|
|
5
5
|
const CLIHelper = require('./utils/cliHelper');
|
|
6
6
|
const RepoGitDiff = require('./utils/repoGitDiff');
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const { outputFile } = require('fs-extra');
|
|
8
|
+
const { join } = require('path');
|
|
9
9
|
const DESTRUCTIVE_CHANGES_FILE_NAME = 'destructiveChanges';
|
|
10
10
|
const PACKAGE_FILE_NAME = 'package';
|
|
11
11
|
const XML_FILE_EXTENSION = 'xml';
|
|
12
|
-
module.exports = config => {
|
|
12
|
+
module.exports = async (config) => {
|
|
13
13
|
const cliHelper = new CLIHelper(config);
|
|
14
|
-
cliHelper.validateConfig();
|
|
15
|
-
const metadata = metadataManager.getDefinition('directoryName', config.apiVersion);
|
|
14
|
+
await cliHelper.validateConfig();
|
|
15
|
+
const metadata = await metadataManager.getDefinition('directoryName', config.apiVersion);
|
|
16
16
|
const repoGitDiffHelper = new RepoGitDiff(config, metadata);
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const lines = [...filteredLines, ...includedLines];
|
|
20
|
-
const work = treatDiff(config, lines, metadata);
|
|
21
|
-
treatPackages(work.diffs, config, metadata);
|
|
17
|
+
const lines = await repoGitDiffHelper.getLines();
|
|
18
|
+
const work = await treatDiff(config, lines, metadata);
|
|
22
19
|
return work;
|
|
23
20
|
};
|
|
24
|
-
const treatDiff = (config, lines, metadata) => {
|
|
21
|
+
const treatDiff = async (config, lines, metadata) => {
|
|
25
22
|
const work = {
|
|
26
23
|
config: config,
|
|
27
24
|
diffs: { package: {}, destructiveChanges: {} },
|
|
28
25
|
warnings: [],
|
|
29
26
|
};
|
|
30
27
|
const typeHandlerFactory = new TypeHandlerFactory(work, metadata);
|
|
31
|
-
lines.
|
|
28
|
+
await Promise.all(lines.map(line => typeHandlerFactory.getTypeHandler(line).handle()));
|
|
29
|
+
await treatPackages(work.diffs, config, metadata);
|
|
32
30
|
return work;
|
|
33
31
|
};
|
|
34
|
-
const treatPackages = (dcJson, config, metadata) => {
|
|
32
|
+
const treatPackages = async (dcJson, config, metadata) => {
|
|
35
33
|
cleanPackages(dcJson);
|
|
36
34
|
const pc = new PackageConstructor(config, metadata);
|
|
37
|
-
[
|
|
35
|
+
await Promise.all([
|
|
38
36
|
{
|
|
39
37
|
filename: `${DESTRUCTIVE_CHANGES_FILE_NAME}.${XML_FILE_EXTENSION}`,
|
|
40
38
|
folder: DESTRUCTIVE_CHANGES_FILE_NAME,
|
|
@@ -50,10 +48,10 @@ const treatPackages = (dcJson, config, metadata) => {
|
|
|
50
48
|
folder: DESTRUCTIVE_CHANGES_FILE_NAME,
|
|
51
49
|
xmlContent: pc.constructPackage({}),
|
|
52
50
|
},
|
|
53
|
-
].
|
|
54
|
-
const location =
|
|
55
|
-
|
|
56
|
-
});
|
|
51
|
+
].map(async (op) => {
|
|
52
|
+
const location = join(config.output, op.folder, op.filename);
|
|
53
|
+
outputFile(location, op.xmlContent);
|
|
54
|
+
}));
|
|
57
55
|
};
|
|
58
56
|
const cleanPackages = dcJson => {
|
|
59
57
|
const additive = dcJson[PACKAGE_FILE_NAME];
|
package/lib/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,MAAM,kBAAkB,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAA;AAChE,MAAM,kBAAkB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAA;AAClE,MAAM,eAAe,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAA;AAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAC9C,MAAM,WAAW,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAElD,MAAM,
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function getDefinition(grouping: any, apiVersion: any): any
|
|
1
|
+
export function getDefinition(grouping: any, apiVersion: any): Promise<any>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const
|
|
3
|
-
const
|
|
2
|
+
const { resolve } = require('path');
|
|
3
|
+
const { readdir } = require('fs').promises;
|
|
4
4
|
let _apiMap;
|
|
5
5
|
const describeMetadata = {};
|
|
6
|
-
const getApiMap = () => {
|
|
6
|
+
const getApiMap = async () => {
|
|
7
7
|
if (!_apiMap) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const dir = await readdir(__dirname);
|
|
9
|
+
_apiMap = dir
|
|
10
10
|
.filter(file => /^[a-z]+\d+\.json$/.test(file))
|
|
11
11
|
.reduce((accu, file) => {
|
|
12
12
|
const version = file.match(/\d+/)[0];
|
|
@@ -20,13 +20,13 @@ const getApiMap = () => {
|
|
|
20
20
|
return _apiMap;
|
|
21
21
|
};
|
|
22
22
|
module.exports = {
|
|
23
|
-
getDefinition: (grouping, apiVersion) => {
|
|
23
|
+
getDefinition: async (grouping, apiVersion) => {
|
|
24
24
|
if (!describeMetadata[apiVersion]) {
|
|
25
|
-
const apiMap = getApiMap();
|
|
25
|
+
const apiMap = await getApiMap();
|
|
26
26
|
const apiFile = !!apiVersion && Object.prototype.hasOwnProperty.call(apiMap, apiVersion)
|
|
27
27
|
? apiMap[apiVersion]
|
|
28
28
|
: apiMap.latest;
|
|
29
|
-
describeMetadata[apiVersion] = require(
|
|
29
|
+
describeMetadata[apiVersion] = require(resolve(__dirname, apiFile));
|
|
30
30
|
}
|
|
31
31
|
return describeMetadata[apiVersion].reduce((metadata, describe) => {
|
|
32
32
|
metadata[describe[grouping]] = describe;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadataManager.js","sourceRoot":"","sources":["../../src/metadata/metadataManager.js"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,MAAM,
|
|
1
|
+
{"version":3,"file":"metadataManager.js","sourceRoot":"","sources":["../../src/metadata/metadataManager.js"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AACnC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAA;AAE1C,IAAI,OAAO,CAAA;AACX,MAAM,gBAAgB,GAAG,EAAE,CAAA;AAE3B,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;IAC3B,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;QACpC,OAAO,GAAG,GAAG;aACV,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aAC9C,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;YACpC,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;YACpB,IAAI,CAAC,MAAM;gBACT,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAA;YAC/D,OAAO,IAAI,CAAA;QACb,CAAC,EAAE,EAAE,CAAC,CAAA;QACR,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;KACzC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,OAAO,GAAG;IACf,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;QAC5C,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE;YACjC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAA;YAChC,MAAM,OAAO,GACX,CAAC,CAAC,UAAU,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC;gBACtE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBACpB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;YACnB,gBAAgB,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;SACpE;QAED,OAAO,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;YAChE,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAA;YACvC,OAAO,QAAQ,CAAA;QACjB,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC;CACF,CAAA"}
|