@salesforce/source-tracking 1.1.6 → 1.3.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,29 @@
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.3.0](https://github.com/forcedotcom/source-tracking/compare/v1.2.0...v1.3.0) (2022-03-25)
6
+
7
+ ### Features
8
+
9
+ - gracful-fs for EMFILE: too many open files ([1573828](https://github.com/forcedotcom/source-tracking/commit/1573828f5b3cf5f4f8b2023ff31b5764214d4b06))
10
+
11
+ ## [1.2.0](https://github.com/forcedotcom/source-tracking/compare/v1.1.7...v1.2.0) (2022-03-23)
12
+
13
+ ### Features
14
+
15
+ - let isogit deal with ignore files ([#135](https://github.com/forcedotcom/source-tracking/issues/135)) ([1ddb2cd](https://github.com/forcedotcom/source-tracking/commit/1ddb2cdb8f23688f7bb4876a893097a85581f4c1))
16
+
17
+ ### Bug Fixes
18
+
19
+ - ga tracking commands compatibility ([3a31a0d](https://github.com/forcedotcom/source-tracking/commit/3a31a0de448993c643ea4661a7a37772e46e8f51))
20
+ - support pkgDir with ./foo ([3b46454](https://github.com/forcedotcom/source-tracking/commit/3b46454b3e57f653cbe80c66fbfee1cac121c2a8))
21
+
22
+ ### [1.1.7](https://github.com/forcedotcom/source-tracking/compare/v1.1.6...v1.1.7) (2022-03-16)
23
+
24
+ ### Bug Fixes
25
+
26
+ - use isogit multiple add ([0845df8](https://github.com/forcedotcom/source-tracking/commit/0845df81845f07bd2bece444118497b2ef72e7aa))
27
+
5
28
  ### [1.1.6](https://github.com/forcedotcom/source-tracking/compare/v1.1.5...v1.1.6) (2022-03-14)
6
29
 
7
30
  ### [1.1.5](https://github.com/forcedotcom/source-tracking/compare/v1.1.4...v1.1.5) (2022-03-11)
@@ -57,13 +57,18 @@ const throwIfInvalid = ({ org, projectPath, toValidate, command, }) => {
57
57
  throw new core_1.SfdxError(`${messages.getMessage('sourceTrackingFileVersionMismatch', ['new/beta'])}\n\nTry this:\n${messages.getMessage('useOtherVersion', ['new/beta', (0, exports.replaceRenamedCommands)(command.replace(':legacy', ''))])}.\n${messages.getMessage('clearSuggestion', [
58
58
  'new/beta',
59
59
  (0, exports.replaceRenamedCommands)('sfdx force:source:tracking:clear'),
60
+ (0, exports.replaceRenamedCommands)('sfdx force:source:tracking:reset', true),
60
61
  ])}.`, 'SourceTrackingFileVersionMismatch');
61
62
  }
62
63
  // We expected it to be the plugin-source version but it is using the old tracking files
63
64
  if (toValidate === 'plugin-source') {
64
65
  throw new core_1.SfdxError(messages.getMessage('sourceTrackingFileVersionMismatch', ['old/legacy']), 'SourceTrackingFileVersionMismatch', [
65
66
  messages.getMessage('useOtherVersion', ['old/legacy', (0, exports.replaceRenamedCommands)(command, true)]),
66
- messages.getMessage('clearSuggestion', ['old/legacy', 'sfdx force:source:tracking:clear']),
67
+ messages.getMessage('clearSuggestion', [
68
+ 'old/legacy',
69
+ 'sfdx force:source:legacy:tracking:clear',
70
+ 'sfdx force:source:tracking:reset',
71
+ ]),
67
72
  ]);
68
73
  }
69
74
  };
@@ -82,10 +87,10 @@ const replaceRenamedCommands = (input, reverse = false) => {
82
87
  };
83
88
  exports.replaceRenamedCommands = replaceRenamedCommands;
84
89
  const renames = new Map([
85
- ['force:source:status', 'force:source:beta:status'],
86
- ['force:source:push', 'force:source:beta:push'],
87
- ['force:source:pull', 'force:source:beta:pull'],
88
- ['force:source:tracking:reset', 'force:source:beta:tracking:reset'],
89
- ['force:source:tracking:clear', 'force:source:beta:tracking:clear'],
90
+ ['force:source:legacy:status', 'force:source:status'],
91
+ ['force:source:legacy:push', 'force:source:push'],
92
+ ['force:source:legacy:pull', 'force:source:pull'],
93
+ ['force:source:legacy:tracking:reset', 'force:source:tracking:reset'],
94
+ ['force:source:legacy:tracking:clear', 'force:source:tracking:clear'],
90
95
  ]);
91
96
  //# sourceMappingURL=compatibility.js.map
@@ -9,6 +9,7 @@ interface CommitRequest {
9
9
  deployedFiles?: string[];
10
10
  deletedFiles?: string[];
11
11
  message?: string;
12
+ needsUpdatedStatus?: boolean;
12
13
  }
13
14
  export declare class ShadowRepo {
14
15
  private static instanceMap;
@@ -17,7 +18,6 @@ export declare class ShadowRepo {
17
18
  private packageDirs;
18
19
  private status;
19
20
  private logger;
20
- private gitIgnoreLocations;
21
21
  private constructor();
22
22
  static getInstance(options: ShadowRepoOptions): Promise<ShadowRepo>;
23
23
  init(): Promise<void>;
@@ -74,9 +74,6 @@ export declare class ShadowRepo {
74
74
  *
75
75
  * @returns sha (string)
76
76
  */
77
- commitChanges({ deployedFiles, deletedFiles, message, }?: CommitRequest): Promise<string>;
78
- private locateIgnoreFiles;
79
- private stashIgnoreFile;
80
- private unStashIgnoreFile;
77
+ commitChanges({ deployedFiles, deletedFiles, message, needsUpdatedStatus, }?: CommitRequest): Promise<string>;
81
78
  }
82
79
  export {};
@@ -5,16 +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");
12
+ const fs = require("graceful-fs");
13
13
  const core_1 = require("@salesforce/core");
14
14
  const git = require("isomorphic-git");
15
15
  const functions_1 = require("./functions");
16
16
  const gitIgnoreFileName = '.gitignore';
17
- const stashedGitIgnoreFileName = '.BAK.gitignore';
18
17
  /**
19
18
  * returns the full path to where we store the shadow repo
20
19
  */
@@ -29,7 +28,6 @@ const HEAD = 1;
29
28
  const WORKDIR = 2;
30
29
  class ShadowRepo {
31
30
  constructor(options) {
32
- this.gitIgnoreLocations = [];
33
31
  this.gitDir = getGitDir(options.orgId, options.projectPath);
34
32
  this.projectPath = options.projectPath;
35
33
  this.packageDirs = options.packageDirs;
@@ -46,19 +44,18 @@ class ShadowRepo {
46
44
  async init() {
47
45
  this.logger = await core_1.Logger.child('ShadowRepo');
48
46
  // initialize the shadow repo if it doesn't exist
49
- if (!core_1.fs.existsSync(this.gitDir)) {
47
+ if (!fs.existsSync(this.gitDir)) {
50
48
  this.logger.debug('initializing git repo');
51
49
  await this.gitInit();
52
50
  }
53
- await this.locateIgnoreFiles();
54
51
  }
55
52
  /**
56
53
  * Initialize a new source tracking shadow repo. Think of git init
57
54
  *
58
55
  */
59
56
  async gitInit() {
60
- await core_1.fs.promises.mkdir(this.gitDir, { recursive: true });
61
- await git.init({ fs: core_1.fs, dir: this.projectPath, gitdir: this.gitDir, defaultBranch: 'main' });
57
+ await fs.promises.mkdir(this.gitDir, { recursive: true });
58
+ await git.init({ fs, dir: this.projectPath, gitdir: this.gitDir, defaultBranch: 'main' });
62
59
  }
63
60
  /**
64
61
  * Delete the local tracking files
@@ -66,12 +63,12 @@ class ShadowRepo {
66
63
  * @returns the deleted directory
67
64
  */
68
65
  async delete() {
69
- if (typeof core_1.fs.promises.rm === 'function') {
70
- await core_1.fs.promises.rm(this.gitDir, { recursive: true, force: true });
66
+ if (typeof fs.promises.rm === 'function') {
67
+ await fs.promises.rm(this.gitDir, { recursive: true, force: true });
71
68
  }
72
69
  else {
73
70
  // when node 12 support is over, switch to promise version
74
- core_1.fs.rmdirSync(this.gitDir, { recursive: true });
71
+ fs.rmdirSync(this.gitDir, { recursive: true });
75
72
  }
76
73
  return this.gitDir;
77
74
  }
@@ -85,37 +82,34 @@ class ShadowRepo {
85
82
  */
86
83
  async getStatus(noCache = false) {
87
84
  if (!this.status || noCache) {
88
- try {
89
- // only ask about OS once but use twice
90
- const isWindows = os.type() === 'Windows_NT';
91
- await this.stashIgnoreFile();
92
- const filepaths = isWindows
93
- ? // iso-git uses posix paths, but packageDirs has already normalized them so we need to convert if windows
94
- this.packageDirs.map((dir) => dir.path.split(path.sep).join(path.posix.sep))
95
- : this.packageDirs.map((dir) => dir.path);
96
- // status hasn't been initalized yet
97
- this.status = await git.statusMatrix({
98
- fs: core_1.fs,
99
- dir: this.projectPath,
100
- gitdir: this.gitDir,
101
- filepaths,
102
- filter: (f) =>
103
- // no hidden files
104
- !f.includes(`${path.sep}.`) &&
105
- // no lwc tests
106
- !f.includes('__tests__') &&
107
- // no gitignore files
108
- ![gitIgnoreFileName, stashedGitIgnoreFileName].includes(path.basename(f)) &&
109
- // isogit uses `startsWith` for filepaths so it's possible to get a false positive
110
- filepaths.some((pkgDir) => (0, functions_1.pathIsInFolder)(f, pkgDir)),
111
- });
112
- // isomorphic-git stores things in unix-style tree. Convert to windows-style if necessary
113
- if (isWindows) {
114
- this.status = this.status.map((row) => [path.normalize(row[FILE]), row[HEAD], row[WORKDIR], row[3]]);
115
- }
116
- }
117
- finally {
118
- await this.unStashIgnoreFile();
85
+ // only ask about OS once but use twice
86
+ const isWindows = os.type() === 'Windows_NT';
87
+ // iso-git uses relative, posix paths
88
+ // but packageDirs has already resolved / normalized them
89
+ // so we need to make them project-relative again and convert if windows
90
+ const filepaths = this.packageDirs
91
+ .map((dir) => path.relative(this.projectPath, dir.fullPath))
92
+ .map((p) => (isWindows ? p.split(path.sep).join(path.posix.sep) : p));
93
+ // status hasn't been initalized yet
94
+ this.status = await git.statusMatrix({
95
+ fs,
96
+ dir: this.projectPath,
97
+ gitdir: this.gitDir,
98
+ filepaths,
99
+ ignored: true,
100
+ filter: (f) =>
101
+ // no hidden files
102
+ !f.includes(`${path.sep}.`) &&
103
+ // no lwc tests
104
+ !f.includes('__tests__') &&
105
+ // no gitignore files
106
+ !f.endsWith(gitIgnoreFileName) &&
107
+ // isogit uses `startsWith` for filepaths so it's possible to get a false positive
108
+ filepaths.some((pkgDir) => (0, functions_1.pathIsInFolder)(f, pkgDir)),
109
+ });
110
+ // isomorphic-git stores things in unix-style tree. Convert to windows-style if necessary
111
+ if (isWindows) {
112
+ this.status = this.status.map((row) => [path.normalize(row[FILE]), row[HEAD], row[WORKDIR], row[3]]);
119
113
  }
120
114
  }
121
115
  return this.status;
@@ -173,63 +167,41 @@ class ShadowRepo {
173
167
  *
174
168
  * @returns sha (string)
175
169
  */
176
- async commitChanges({ deployedFiles = [], deletedFiles = [], message = 'sfdx source tracking', } = {}) {
170
+ async commitChanges({ deployedFiles = [], deletedFiles = [], message = 'sfdx source tracking', needsUpdatedStatus = true, } = {}) {
177
171
  // if no files are specified, commit all changes
178
172
  if (deployedFiles.length === 0 && deletedFiles.length === 0) {
179
173
  // this is valid, might not be an error
180
174
  return 'no files to commit';
181
175
  }
182
- this.logger.debug('changes are', deployedFiles);
183
- this.logger.debug('deletes are', deletedFiles);
184
- await this.stashIgnoreFile();
185
176
  // these are stored in posix/style/path format. We have to convert inbound stuff from windows
186
177
  if (os.type() === 'Windows_NT') {
187
178
  deployedFiles = deployedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
188
179
  deletedFiles = deletedFiles.map((filepath) => path.normalize(filepath).split(path.sep).join(path.posix.sep));
189
180
  }
190
- const uniqueDeployedFiles = Array.from(new Set(deployedFiles));
191
- const uniqueDeletedFiles = Array.from(new Set(deletedFiles));
192
- try {
193
- // stage changes
194
- await Promise.all([
195
- ...uniqueDeployedFiles.map((filepath) => git.add({ fs: core_1.fs, dir: this.projectPath, gitdir: this.gitDir, filepath })),
196
- ...uniqueDeletedFiles.map((filepath) => git.remove({ fs: core_1.fs, dir: this.projectPath, gitdir: this.gitDir, filepath })),
197
- ]);
198
- const sha = await git.commit({
199
- fs: core_1.fs,
181
+ if (deployedFiles.length) {
182
+ await git.add({
183
+ fs,
200
184
  dir: this.projectPath,
201
185
  gitdir: this.gitDir,
202
- message,
203
- author: { name: 'sfdx source tracking' },
186
+ filepath: [...new Set(deployedFiles)],
187
+ force: true,
204
188
  });
205
- // status changed as a result of the commit. This prevents users from having to run getStatus(true) to avoid cache
206
- await this.getStatus(true);
207
- return sha;
208
189
  }
209
- finally {
210
- await this.unStashIgnoreFile();
190
+ for (const filepath of [...new Set(deletedFiles)]) {
191
+ await git.remove({ fs, dir: this.projectPath, gitdir: this.gitDir, filepath });
211
192
  }
212
- }
213
- async locateIgnoreFiles() {
214
- // set the gitIgnoreLocations so we only have to do it once
215
- this.gitIgnoreLocations = (await git.walk({
216
- fs: core_1.fs,
193
+ const sha = await git.commit({
194
+ fs,
217
195
  dir: this.projectPath,
218
196
  gitdir: this.gitDir,
219
- trees: [git.WORKDIR()],
220
- // eslint-disable-next-line @typescript-eslint/require-await
221
- map: async (filepath) => filepath,
222
- }))
223
- .filter((filepath) => filepath.includes(gitIgnoreFileName))
224
- .map((ignoreFile) => path.join(this.projectPath, ignoreFile));
225
- }
226
- async stashIgnoreFile() {
227
- // allSettled allows them to fail (example, the file wasn't where it was expected).
228
- await Promise.allSettled(this.gitIgnoreLocations.map((originalLocation) => core_1.fs.promises.rename(originalLocation, originalLocation.replace(gitIgnoreFileName, stashedGitIgnoreFileName))));
229
- }
230
- async unStashIgnoreFile() {
231
- // allSettled allows them to fail (example, the file wasn't where it was expected).
232
- await Promise.allSettled(this.gitIgnoreLocations.map((originalLocation) => core_1.fs.promises.rename(originalLocation.replace(gitIgnoreFileName, stashedGitIgnoreFileName), originalLocation)));
197
+ message,
198
+ author: { name: 'sfdx source tracking' },
199
+ });
200
+ // status changed as a result of the commit. This prevents users from having to run getStatus(true) to avoid cache
201
+ if (needsUpdatedStatus) {
202
+ await this.getStatus(true);
203
+ }
204
+ return sha;
233
205
  }
234
206
  }
235
207
  exports.ShadowRepo = ShadowRepo;
@@ -11,6 +11,7 @@ var _a;
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.remoteChangeElementToChangeResult = exports.RemoteSourceTrackingService = void 0;
13
13
  const path = require("path");
14
+ const fs = require("fs");
14
15
  const ts_retry_promise_1 = require("ts-retry-promise");
15
16
  const core_1 = require("@salesforce/core");
16
17
  const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
@@ -98,8 +99,8 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
98
99
  static async delete(orgId) {
99
100
  const fileToDelete = RemoteSourceTrackingService.getFilePath(orgId);
100
101
  // the file might not exist, in which case we don't need to delete it
101
- if (core_1.fs.existsSync(fileToDelete)) {
102
- await core_1.fs.promises.unlink(fileToDelete);
102
+ if (fs.existsSync(fileToDelete)) {
103
+ await fs.promises.unlink(fileToDelete);
103
104
  }
104
105
  return path.isAbsolute(fileToDelete) ? fileToDelete : path.join(process.cwd(), fileToDelete);
105
106
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "sourceTrackingFileVersionMismatch": "This project uses the %s version of source tracking files.",
3
- "clearSuggestion": "Clear the %s version of the tracking files by running '%s'",
3
+ "clearSuggestion": "Push/Pull any local or remote changes. Then, clear the %s version of the tracking files by running '%s' followed by '%s'.",
4
4
  "useOtherVersion": "Use the %s version of the command, '%s' with your existing tracking files."
5
5
  }
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.1.6",
4
+ "version": "1.3.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
- "isomorphic-git": "^1.9.2",
49
+ "graceful-fs": "^4.2.9",
50
+ "isomorphic-git": "1.16.0",
50
51
  "ts-retry-promise": "^0.6.0"
51
52
  },
52
53
  "devDependencies": {