@salesforce/source-tracking 1.2.0 → 1.4.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
CHANGED
|
@@ -2,6 +2,24 @@
|
|
|
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
|
+
## [1.4.0](https://github.com/forcedotcom/source-tracking/compare/v1.3.1...v1.4.0) (2022-04-27)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- comp set for pulls ([4b361a4](https://github.com/forcedotcom/source-tracking/commit/4b361a4f31ac4f810762ee8d6f8447f7eef1be31))
|
|
10
|
+
|
|
11
|
+
### [1.3.1](https://github.com/forcedotcom/source-tracking/compare/v1.3.0...v1.3.1) (2022-03-25)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- tracking really large repos in chunks, lower limit for windows ([0cb2ce5](https://github.com/forcedotcom/source-tracking/commit/0cb2ce5f3b65b8be9f4e4210aba010e919f692a3))
|
|
16
|
+
|
|
17
|
+
## [1.3.0](https://github.com/forcedotcom/source-tracking/compare/v1.2.0...v1.3.0) (2022-03-25)
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
- gracful-fs for EMFILE: too many open files ([1573828](https://github.com/forcedotcom/source-tracking/commit/1573828f5b3cf5f4f8b2023ff31b5764214d4b06))
|
|
22
|
+
|
|
5
23
|
## [1.2.0](https://github.com/forcedotcom/source-tracking/compare/v1.1.7...v1.2.0) (2022-03-23)
|
|
6
24
|
|
|
7
25
|
### Features
|
|
@@ -8,3 +8,4 @@ export declare const isBundle: (cmp: SourceComponent) => boolean;
|
|
|
8
8
|
* ex: '/foo/bar-extra/baz'.startsWith('foo/bar') would be true, but this function understands that they are not in the same folder
|
|
9
9
|
*/
|
|
10
10
|
export declare const pathIsInFolder: (filePath: string, folder: string) => boolean;
|
|
11
|
+
export declare const chunkArray: <T>(arr: T[], size: number) => T[][];
|
package/lib/shared/functions.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.pathIsInFolder = exports.isBundle = exports.getKeyFromObject = exports.getMetadataKey = void 0;
|
|
9
|
+
exports.chunkArray = exports.pathIsInFolder = exports.isBundle = exports.getKeyFromObject = exports.getMetadataKey = void 0;
|
|
10
10
|
const path_1 = require("path");
|
|
11
11
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
12
12
|
const getMetadataKey = (metadataType, metadataName) => {
|
|
@@ -37,4 +37,7 @@ exports.pathIsInFolder = pathIsInFolder;
|
|
|
37
37
|
const nonEmptyStringFilter = (value) => {
|
|
38
38
|
return (0, ts_types_1.isString)(value) && value.length > 0;
|
|
39
39
|
};
|
|
40
|
+
// adapted for TS from https://github.com/30-seconds/30-seconds-of-code/blob/master/snippets/chunk.md
|
|
41
|
+
const chunkArray = (arr, size) => Array.from({ length: Math.ceil(arr.length / size) }, (v, i) => arr.slice(i * size, i * size + size));
|
|
42
|
+
exports.chunkArray = chunkArray;
|
|
40
43
|
//# sourceMappingURL=functions.js.map
|
|
@@ -18,6 +18,9 @@ export declare class ShadowRepo {
|
|
|
18
18
|
private packageDirs;
|
|
19
19
|
private status;
|
|
20
20
|
private logger;
|
|
21
|
+
private isWindows;
|
|
22
|
+
/** do not try to add more than this many files at a time through isogit. You'll hit EMFILE: too many open files even with graceful-fs */
|
|
23
|
+
private maxFileAdd;
|
|
21
24
|
private constructor();
|
|
22
25
|
static getInstance(options: ShadowRepoOptions): Promise<ShadowRepo>;
|
|
23
26
|
init(): Promise<void>;
|
|
@@ -5,19 +5,15 @@
|
|
|
5
5
|
* Licensed under the BSD 3-Clause license.
|
|
6
6
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
7
|
*/
|
|
8
|
-
/* eslint-disable no-console */
|
|
9
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
9
|
exports.ShadowRepo = void 0;
|
|
11
10
|
const path = require("path");
|
|
12
11
|
const os = require("os");
|
|
13
|
-
const fs = require("fs");
|
|
12
|
+
const fs = require("graceful-fs");
|
|
14
13
|
const core_1 = require("@salesforce/core");
|
|
15
14
|
const git = require("isomorphic-git");
|
|
16
15
|
const functions_1 = require("./functions");
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* returns the full path to where we store the shadow repo
|
|
20
|
-
*/
|
|
16
|
+
/** returns the full path to where we store the shadow repo */
|
|
21
17
|
const getGitDir = (orgId, projectPath) => {
|
|
22
18
|
return path.join(projectPath, '.sfdx', 'orgs', orgId, 'localSourceTracking');
|
|
23
19
|
};
|
|
@@ -32,6 +28,8 @@ class ShadowRepo {
|
|
|
32
28
|
this.gitDir = getGitDir(options.orgId, options.projectPath);
|
|
33
29
|
this.projectPath = options.projectPath;
|
|
34
30
|
this.packageDirs = options.packageDirs;
|
|
31
|
+
this.isWindows = os.type() === 'Windows_NT';
|
|
32
|
+
this.maxFileAdd = this.isWindows ? 8000 : 15000;
|
|
35
33
|
}
|
|
36
34
|
// think of singleton behavior but unique to the projectPath
|
|
37
35
|
static async getInstance(options) {
|
|
@@ -83,14 +81,12 @@ class ShadowRepo {
|
|
|
83
81
|
*/
|
|
84
82
|
async getStatus(noCache = false) {
|
|
85
83
|
if (!this.status || noCache) {
|
|
86
|
-
// only ask about OS once but use twice
|
|
87
|
-
const isWindows = os.type() === 'Windows_NT';
|
|
88
84
|
// iso-git uses relative, posix paths
|
|
89
85
|
// but packageDirs has already resolved / normalized them
|
|
90
86
|
// so we need to make them project-relative again and convert if windows
|
|
91
87
|
const filepaths = this.packageDirs
|
|
92
88
|
.map((dir) => path.relative(this.projectPath, dir.fullPath))
|
|
93
|
-
.map((p) => (isWindows ? p.split(path.sep).join(path.posix.sep) : p));
|
|
89
|
+
.map((p) => (this.isWindows ? p.split(path.sep).join(path.posix.sep) : p));
|
|
94
90
|
// status hasn't been initalized yet
|
|
95
91
|
this.status = await git.statusMatrix({
|
|
96
92
|
fs,
|
|
@@ -104,12 +100,12 @@ class ShadowRepo {
|
|
|
104
100
|
// no lwc tests
|
|
105
101
|
!f.includes('__tests__') &&
|
|
106
102
|
// no gitignore files
|
|
107
|
-
!f.endsWith(
|
|
103
|
+
!f.endsWith('.gitignore') &&
|
|
108
104
|
// isogit uses `startsWith` for filepaths so it's possible to get a false positive
|
|
109
105
|
filepaths.some((pkgDir) => (0, functions_1.pathIsInFolder)(f, pkgDir)),
|
|
110
106
|
});
|
|
111
107
|
// isomorphic-git stores things in unix-style tree. Convert to windows-style if necessary
|
|
112
|
-
if (isWindows) {
|
|
108
|
+
if (this.isWindows) {
|
|
113
109
|
this.status = this.status.map((row) => [path.normalize(row[FILE]), row[HEAD], row[WORKDIR], row[3]]);
|
|
114
110
|
}
|
|
115
111
|
}
|
|
@@ -180,13 +176,27 @@ class ShadowRepo {
|
|
|
180
176
|
deletedFiles = deletedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
|
|
181
177
|
}
|
|
182
178
|
if (deployedFiles.length) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
179
|
+
const chunks = (0, functions_1.chunkArray)([...new Set(deployedFiles)], this.maxFileAdd);
|
|
180
|
+
for (const chunk of chunks) {
|
|
181
|
+
try {
|
|
182
|
+
await git.add({
|
|
183
|
+
fs,
|
|
184
|
+
dir: this.projectPath,
|
|
185
|
+
gitdir: this.gitDir,
|
|
186
|
+
filepath: chunk,
|
|
187
|
+
force: true,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
if (e instanceof git.Errors.MultipleGitError) {
|
|
192
|
+
this.logger.error('multiple errors on git.add', e.errors.slice(0, 5));
|
|
193
|
+
const error = new core_1.SfdxError(e.message, e.name, [], 1);
|
|
194
|
+
error.setData(e.errors);
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
190
200
|
}
|
|
191
201
|
for (const filepath of [...new Set(deletedFiles)]) {
|
|
192
202
|
await git.remove({ fs, dir: this.projectPath, gitdir: this.gitDir, filepath });
|
package/lib/sourceTracking.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare class SourceTracking extends AsyncCreatable {
|
|
|
33
33
|
* @returns ComponentSet[]
|
|
34
34
|
*/
|
|
35
35
|
localChangesAsComponentSet(byPackageDir?: boolean): Promise<ComponentSet[]>;
|
|
36
|
+
remoteNonDeletesAsComponentSet(): Promise<ComponentSet>;
|
|
36
37
|
/**
|
|
37
38
|
* Does most of the work for the force:source:status command.
|
|
38
39
|
* Outputs need a bit of massage since this aims to provide nice json.
|
package/lib/sourceTracking.js
CHANGED
|
@@ -116,6 +116,33 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
116
116
|
})
|
|
117
117
|
.filter((componentSet) => componentSet.size > 0);
|
|
118
118
|
}
|
|
119
|
+
async remoteNonDeletesAsComponentSet() {
|
|
120
|
+
const [changeResults, sourceBackedComponents] = await Promise.all([
|
|
121
|
+
// all changes based on remote tracking
|
|
122
|
+
this.getChanges({
|
|
123
|
+
origin: 'remote',
|
|
124
|
+
state: 'nondelete',
|
|
125
|
+
format: 'ChangeResult',
|
|
126
|
+
}),
|
|
127
|
+
// only returns source-backed components (SBC)
|
|
128
|
+
this.getChanges({
|
|
129
|
+
origin: 'remote',
|
|
130
|
+
state: 'nondelete',
|
|
131
|
+
format: 'SourceComponent',
|
|
132
|
+
}),
|
|
133
|
+
]);
|
|
134
|
+
const componentSet = new source_deploy_retrieve_1.ComponentSet(sourceBackedComponents);
|
|
135
|
+
// there may be remote adds not in the SBC. So we add those manually
|
|
136
|
+
changeResults.forEach((cr) => {
|
|
137
|
+
if (cr.type && cr.name && !componentSet.has({ type: cr.type, fullName: cr.name })) {
|
|
138
|
+
componentSet.add({
|
|
139
|
+
type: cr.type,
|
|
140
|
+
fullName: cr.name,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return componentSet;
|
|
145
|
+
}
|
|
119
146
|
/**
|
|
120
147
|
* Does most of the work for the force:source:status command.
|
|
121
148
|
* Outputs need a bit of massage since this aims to provide nice json.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/source-tracking",
|
|
3
3
|
"description": "API for tracking local and remote Salesforce metadata changes",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"@salesforce/core": "^2.33.1",
|
|
47
47
|
"@salesforce/kit": "^1.5.17",
|
|
48
48
|
"@salesforce/source-deploy-retrieve": "^5.9.4",
|
|
49
|
-
"
|
|
49
|
+
"graceful-fs": "^4.2.9",
|
|
50
|
+
"isomorphic-git": "1.17.0",
|
|
50
51
|
"ts-retry-promise": "^0.6.0"
|
|
51
52
|
},
|
|
52
53
|
"devDependencies": {
|