@apexdevtools/git-ops 1.4.0 → 1.4.2

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
@@ -1,5 +1,13 @@
1
1
  # git-ops - Changelog
2
2
 
3
+ ## 1.4.2 - 2026-06-14
4
+
5
+ - Refresh TypeScript, lint, package manager, and GitHub Actions tooling.
6
+
7
+ ## 1.4.1 - 2024-11-22
8
+
9
+ - Fix missing deploy error reporting
10
+
3
11
  ## 1.4.0 - 2024-02-07
4
12
 
5
13
  - Add `getDeployableClasses` API for native based tracking
@@ -2,20 +2,15 @@
2
2
  /*
3
3
  * Copyright (c) 2024 Certinia Inc. All rights reserved.
4
4
  */
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
5
  var __importDefault = (this && this.__importDefault) || function (mod) {
15
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
16
7
  };
17
8
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.getDeployableClasses = exports.getLocalChanges = exports.getDiffRange = exports.getDefaultBranchDiffByRef = exports.getDefaultBranchDiff = void 0;
9
+ exports.getDefaultBranchDiff = getDefaultBranchDiff;
10
+ exports.getDefaultBranchDiffByRef = getDefaultBranchDiffByRef;
11
+ exports.getDiffRange = getDiffRange;
12
+ exports.getLocalChanges = getLocalChanges;
13
+ exports.getDeployableClasses = getDeployableClasses;
19
14
  const path_1 = __importDefault(require("path"));
20
15
  const git_1 = require("./git");
21
16
  /**
@@ -23,12 +18,9 @@ const git_1 = require("./git");
23
18
  * @param dir: string of the directory thr operation should be performed on
24
19
  * @returns set of absolute paths of changed files
25
20
  */
26
- function getDefaultBranchDiff(dir) {
27
- return __awaiter(this, void 0, void 0, function* () {
28
- return getDefaultBranchDiffByRef(dir, 'HEAD');
29
- });
21
+ async function getDefaultBranchDiff(dir) {
22
+ return getDefaultBranchDiffByRef(dir, 'HEAD');
30
23
  }
31
- exports.getDefaultBranchDiff = getDefaultBranchDiff;
32
24
  /**
33
25
  * Works out changed files using the default branch in that repo given a ref.
34
26
  * This find the default branch in the repo using `git symbolic-ref 'refs/remotes/origin/HEAD'`
@@ -39,18 +31,15 @@ exports.getDefaultBranchDiff = getDefaultBranchDiff;
39
31
  * @param refTo: string git ref. i.e HEAD, or commit hash
40
32
  * @returns set of absolute paths of changed files
41
33
  */
42
- function getDefaultBranchDiffByRef(dir, refTo) {
43
- return __awaiter(this, void 0, void 0, function* () {
44
- const git = new git_1.Git(dir);
45
- return git
46
- .getDefaultBranchName()
47
- .then(branch => getDiffRange(dir, branch, refTo))
48
- .catch(er => {
49
- throw new NoLocalBranchException(er);
50
- });
34
+ async function getDefaultBranchDiffByRef(dir, refTo) {
35
+ const git = new git_1.Git(dir);
36
+ return git
37
+ .getDefaultBranchName()
38
+ .then(branch => getDiffRange(dir, branch, refTo))
39
+ .catch(er => {
40
+ throw new NoLocalBranchException(er);
51
41
  });
52
42
  }
53
- exports.getDefaultBranchDiffByRef = getDefaultBranchDiffByRef;
54
43
  /**
55
44
  * Works out the diff between a given range. Equivalent to `git diff ref1...ref2`
56
45
  * @param dir string of the directory thr operation should be performed on
@@ -58,37 +47,31 @@ exports.getDefaultBranchDiffByRef = getDefaultBranchDiffByRef;
58
47
  * @param toRef string git ref. i.e HEAD, or commit hash
59
48
  * @returns set of absolute paths of changed files
60
49
  */
61
- function getDiffRange(dir, fromRef, toRef) {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- const git = new git_1.Git(dir);
64
- const root = yield git.gitRoot();
65
- return getDiffChanges(git, fromRef, toRef)
66
- .then(changes => resolvePaths(changes, root))
67
- .catch(er => {
68
- throw new DiffFailedException(er);
69
- });
50
+ async function getDiffRange(dir, fromRef, toRef) {
51
+ const git = new git_1.Git(dir);
52
+ const root = await git.gitRoot();
53
+ return getDiffChanges(git, fromRef, toRef)
54
+ .then(changes => resolvePaths(changes, root))
55
+ .catch(er => {
56
+ throw new DiffFailedException(er);
70
57
  });
71
58
  }
72
- exports.getDiffRange = getDiffRange;
73
59
  /**
74
60
  * Get the local changes that not have been committed. Equivalent to `git status`
75
61
  * Files with the status of deleted (`D`) and ignored (`!`) will not be included in the change set.
76
62
  * @param dir tring of the directory thr operation should be performed on
77
63
  * @returns set of absolute paths of un committed files
78
64
  */
79
- function getLocalChanges(dir) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- const git = new git_1.Git(dir);
82
- const root = yield git.gitRoot();
83
- return git
84
- .getLocalChangedAndCreated()
85
- .then(changes => resolvePaths(changes, root))
86
- .catch(er => {
87
- throw new LocalChangeException(er);
88
- });
65
+ async function getLocalChanges(dir) {
66
+ const git = new git_1.Git(dir);
67
+ const root = await git.gitRoot();
68
+ return git
69
+ .getLocalChangedAndCreated()
70
+ .then(changes => resolvePaths(changes, root))
71
+ .catch(er => {
72
+ throw new LocalChangeException(er);
89
73
  });
90
74
  }
91
- exports.getLocalChanges = getLocalChanges;
92
75
  /**
93
76
  * Get the locally changed class files, based on source tracking repo. Note that it does
94
77
  * not respect the `.forceignore` yet.
@@ -97,40 +80,35 @@ exports.getLocalChanges = getLocalChanges;
97
80
  * @param orgId SF org ID, used to select tracking repo
98
81
  * @returns paths of class files that may need deploying
99
82
  */
100
- function getDeployableClasses(projectDir, orgId) {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- const git = new git_1.Git(projectDir);
103
- const trackingDir = getTrackingGitDir(projectDir, orgId);
104
- const stats = [
105
- git_1.FileStatus.Modified,
106
- git_1.FileStatus.Added,
107
- git_1.FileStatus.Renamed,
108
- git_1.FileStatus.Copied,
109
- git_1.FileStatus.Untracked,
110
- ];
111
- return git
112
- .getFilteredStatus(f => f.path.endsWith('.cls') && stats.includes(f.working_dir), trackingDir)
113
- .then(changes => resolvePaths(changes, projectDir))
114
- .catch(er => {
115
- throw new LocalChangeException(er);
116
- });
83
+ async function getDeployableClasses(projectDir, orgId) {
84
+ const git = new git_1.Git(projectDir);
85
+ const trackingDir = getTrackingGitDir(projectDir, orgId);
86
+ const stats = [
87
+ git_1.FileStatus.Modified,
88
+ git_1.FileStatus.Added,
89
+ git_1.FileStatus.Renamed,
90
+ git_1.FileStatus.Copied,
91
+ git_1.FileStatus.Untracked,
92
+ ];
93
+ return git
94
+ .getFilteredStatus(f => f.path.endsWith('.cls') && stats.includes(f.working_dir), trackingDir)
95
+ .then(changes => resolvePaths(changes, projectDir))
96
+ .catch(er => {
97
+ throw new LocalChangeException(er);
117
98
  });
118
99
  }
119
- exports.getDeployableClasses = getDeployableClasses;
120
100
  function resolvePaths(paths, root) {
121
101
  const fullPaths = [...paths].map(p => path_1.default.resolve(root, p));
122
102
  return new Set(fullPaths);
123
103
  }
124
- function getDiffChanges(git, ref1, ref2) {
125
- return __awaiter(this, void 0, void 0, function* () {
126
- const changes = yield Promise.all([
127
- git.diffRange(ref1, ref2),
128
- git.getLocalChangedAndCreated(),
129
- ]);
130
- const allChanges = new Set();
131
- changes.forEach(set => set.forEach(file => allChanges.add(file)));
132
- return allChanges;
133
- });
104
+ async function getDiffChanges(git, ref1, ref2) {
105
+ const changes = await Promise.all([
106
+ git.diffRange(ref1, ref2),
107
+ git.getLocalChangedAndCreated(),
108
+ ]);
109
+ const allChanges = new Set();
110
+ changes.forEach(set => set.forEach(file => allChanges.add(file)));
111
+ return allChanges;
134
112
  }
135
113
  function getTrackingGitDir(projectDir, orgId) {
136
114
  return path_1.default.resolve(projectDir, '.sf', 'orgs', orgId, 'localSourceTracking');
@@ -23,5 +23,5 @@ export declare class Git {
23
23
  getDefaultBranchName(): Promise<string>;
24
24
  diffRange(fromRef: string, toRef: string): Promise<Set<string>>;
25
25
  getLocalChangedAndCreated(): Promise<Set<string>>;
26
- getFilteredStatus(filterFn: (result: FileStatusResult) => boolean, gitDir?: string | undefined): Promise<Set<string>>;
26
+ getFilteredStatus(filterFn: (result: FileStatusResult) => boolean, gitDir?: string): Promise<Set<string>>;
27
27
  }
package/lib/git.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2024 Certinia Inc. All rights reserved.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Git = exports.FileStatus = void 0;
7
+ const simple_git_1 = require("simple-git");
8
+ var FileStatus;
9
+ (function (FileStatus) {
10
+ FileStatus["Unmodified"] = " ";
11
+ FileStatus["Modified"] = "M";
12
+ FileStatus["TypeChanged"] = "T";
13
+ FileStatus["Added"] = "A";
14
+ FileStatus["Deleted"] = "D";
15
+ FileStatus["Renamed"] = "R";
16
+ FileStatus["Copied"] = "C";
17
+ FileStatus["Updated"] = "U";
18
+ FileStatus["Untracked"] = "?";
19
+ FileStatus["Ignore"] = "!";
20
+ })(FileStatus || (exports.FileStatus = FileStatus = {}));
21
+ class Git {
22
+ static MIN_GIT_VERSION_MAJOR = 2;
23
+ static MIN_GIT_VERSION_MINOR = 20;
24
+ gitInstance = undefined;
25
+ dir;
26
+ constructor(dir) {
27
+ this.dir = dir;
28
+ }
29
+ static async versionCheck(git) {
30
+ const version = await git.version();
31
+ const isSupported = version.major >= this.MIN_GIT_VERSION_MAJOR &&
32
+ version.minor >= this.MIN_GIT_VERSION_MINOR;
33
+ if (!version.installed) {
34
+ throw new Error('"git" is not installed or available on the PATH');
35
+ }
36
+ if (!isSupported)
37
+ throw new Error(`Unsupported version of git. Min version must be ${this.MIN_GIT_VERSION_MAJOR}.${this.MIN_GIT_VERSION_MINOR}`);
38
+ }
39
+ get git() {
40
+ if (this.gitInstance)
41
+ return Promise.resolve(this.gitInstance);
42
+ const git = (0, simple_git_1.simpleGit)(this.dir);
43
+ return Git.versionCheck(git).then(() => {
44
+ this.gitInstance = git;
45
+ return git;
46
+ });
47
+ }
48
+ async gitRoot() {
49
+ return (await this.git).revparse('--show-toplevel');
50
+ }
51
+ async getDefaultBranchName() {
52
+ return this.git
53
+ .then(git => git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD', '--short']))
54
+ .catch(error => {
55
+ if (error instanceof Error)
56
+ throw Error(`Failed to find symbolic ref no remote HEAD with message: '${error.message.trim()}'`);
57
+ else
58
+ throw new Error('Failed to find symbolic ref no remote HEAD');
59
+ })
60
+ .then(branch => {
61
+ if (branch.startsWith('origin/'))
62
+ return branch.trim();
63
+ else
64
+ throw new Error(`Expected default branch '${branch}' to start with 'origin/'`);
65
+ });
66
+ }
67
+ async diffRange(fromRef, toRef) {
68
+ return this.git
69
+ .then(git => git.diff([`${fromRef}...${toRef}`, '--name-only', '-z']))
70
+ .then(diff => {
71
+ const files = diff
72
+ .split('\u0000')
73
+ .map(s => s.trim())
74
+ .filter(s => s); //Removes any falsy values
75
+ return new Set([...files]);
76
+ });
77
+ }
78
+ async getLocalChangedAndCreated() {
79
+ const excludeStatus = [FileStatus.Deleted, FileStatus.Ignore];
80
+ return this.getFilteredStatus(f => !excludeStatus.includes(f.index) &&
81
+ !excludeStatus.includes(f.working_dir));
82
+ }
83
+ async getFilteredStatus(filterFn, gitDir) {
84
+ return this.git
85
+ .then(git => {
86
+ return gitDir ? git.env('GIT_DIR', gitDir).status() : git.status();
87
+ })
88
+ .then(status => {
89
+ return new Set(...[status.files.filter(filterFn).map(f => f.path)]);
90
+ });
91
+ }
92
+ }
93
+ exports.Git = Git;
@@ -35,6 +35,8 @@ export declare class OrgTracking {
35
35
  getLocalStatus(withConflicts?: boolean): Promise<SyncStatus>;
36
36
  deployAndUpdateSourceTracking(paths: Array<string>): Promise<void>;
37
37
  private deploy;
38
+ private reportDeployStatus;
39
+ private reportDeployErrors;
38
40
  private updateSourceTracking;
39
41
  private toSyncStatusRow;
40
42
  private withWorkingDir;
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2024 Certinia Inc. All rights reserved.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OrgTracking = exports.FileState = void 0;
7
+ const core_1 = require("@salesforce/core");
8
+ const process_1 = require("process");
9
+ const source_tracking_1 = require("@salesforce/source-tracking");
10
+ const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
11
+ var FileState;
12
+ (function (FileState) {
13
+ FileState["Added"] = "add";
14
+ FileState["Modified"] = "modify";
15
+ FileState["Deleted"] = "delete";
16
+ FileState["NonDelete"] = "nondelete";
17
+ FileState["Ignored"] = "ignore";
18
+ FileState["Conflicted"] = "conflict";
19
+ })(FileState || (exports.FileState = FileState = {}));
20
+ class OrgTracking {
21
+ options;
22
+ logger;
23
+ constructor(options) {
24
+ this.options = options;
25
+ this.logger = options.logger;
26
+ }
27
+ async getLocalStatus(withConflicts = false) {
28
+ // source-tracking currently brings its own @salesforce/core type graph,
29
+ // so keep the runtime object and relax the compile-time boundary here.
30
+ const project = core_1.SfProject.getInstance(this.options.projectDir);
31
+ const org = (await core_1.Org.create({
32
+ connection: this.options.connection,
33
+ }));
34
+ return await this.withWorkingDir(this.options.projectDir, async () => {
35
+ const tracking = await source_tracking_1.SourceTracking.create({
36
+ org,
37
+ project,
38
+ ignoreLocalCache: true,
39
+ });
40
+ await tracking.ensureRemoteTracking(true);
41
+ const initValue = { local: [], remote: [] };
42
+ const status = await tracking
43
+ .getStatus({ local: true, remote: false })
44
+ .then(async (res) => {
45
+ if (withConflicts) {
46
+ //Taken from sourceTracking.ts from the @salesforce/source-tracking lib
47
+ const conflictFiles = (await tracking.getConflicts())
48
+ .flatMap(conflict => conflict.filenames)
49
+ .filter((value) => typeof value === 'string');
50
+ res = res.map(row => ({
51
+ ...row,
52
+ conflict: !!row.filePath && conflictFiles.includes(row.filePath),
53
+ }));
54
+ }
55
+ return res;
56
+ })
57
+ .catch(e => {
58
+ this.logger.logError(e);
59
+ return [];
60
+ });
61
+ return status.reduce((acc, row) => {
62
+ acc[row.origin].push(this.toSyncStatusRow(row));
63
+ return acc;
64
+ }, initValue);
65
+ });
66
+ }
67
+ async deployAndUpdateSourceTracking(paths) {
68
+ return await this.withWorkingDir(this.options.projectDir, async () => {
69
+ try {
70
+ this.logger.logDeployProgress('Starting deploy');
71
+ const result = await this.deploy(paths);
72
+ if (result.response.success) {
73
+ await this.updateSourceTracking(result);
74
+ }
75
+ else {
76
+ this.reportDeployErrors(result);
77
+ }
78
+ this.logger.logDeployProgress('Finished deploy');
79
+ }
80
+ catch (e) {
81
+ this.logger.logError(e);
82
+ }
83
+ });
84
+ }
85
+ async deploy(paths) {
86
+ const deploy = await source_deploy_retrieve_1.ComponentSet.fromSource(paths).deploy({
87
+ usernameOrConnection: this.options.connection,
88
+ });
89
+ deploy.onUpdate(response => this.reportDeployStatus(response));
90
+ const result = await deploy.pollStatus();
91
+ this.reportDeployStatus(result.response);
92
+ return result;
93
+ }
94
+ reportDeployStatus(response) {
95
+ const { status, numberComponentsDeployed, numberComponentsTotal, numberComponentErrors, } = response;
96
+ const progress = `${numberComponentsDeployed}/${numberComponentsTotal}`;
97
+ const message = `Status: ${status} | Progress: ${progress} | Errors: ${numberComponentErrors}`;
98
+ this.logger.logDeployProgress(message);
99
+ }
100
+ reportDeployErrors(result) {
101
+ const errors = result.getFileResponses().reduce((a, c) => {
102
+ if (c.state === source_deploy_retrieve_1.ComponentStatus.Failed) {
103
+ a.push(new Error(`${c.fullName}: ${c.error}`));
104
+ }
105
+ return a;
106
+ }, []);
107
+ if (errors.length) {
108
+ this.logger.logDeployProgress('Deploy errors:');
109
+ errors.forEach(err => this.logger.logError(err));
110
+ }
111
+ }
112
+ async updateSourceTracking(result) {
113
+ this.logger.logDeployProgress('Starting source tracking update');
114
+ const project = core_1.SfProject.getInstance(this.options.projectDir);
115
+ const org = (await core_1.Org.create({
116
+ connection: this.options.connection,
117
+ }));
118
+ const tracking = await source_tracking_1.SourceTracking.create({
119
+ org,
120
+ project,
121
+ ignoreLocalCache: true,
122
+ });
123
+ await tracking.updateTrackingFromDeploy(result);
124
+ this.logger.logDeployProgress('Finished source tracking update');
125
+ }
126
+ toSyncStatusRow(from) {
127
+ const state = [];
128
+ if (from.ignored) {
129
+ state.push(FileState.Ignored);
130
+ }
131
+ if (from.conflict) {
132
+ state.push(FileState.Conflicted);
133
+ }
134
+ state.push(from.state);
135
+ return {
136
+ fullName: from.fullName,
137
+ path: from.filePath,
138
+ state: state,
139
+ type: from.type,
140
+ origin: from.origin,
141
+ };
142
+ }
143
+ async withWorkingDir(path, op) {
144
+ const startDir = (0, process_1.cwd)();
145
+ (0, process_1.chdir)(path);
146
+ try {
147
+ return await op();
148
+ }
149
+ finally {
150
+ (0, process_1.chdir)(startDir);
151
+ }
152
+ }
153
+ }
154
+ exports.OrgTracking = OrgTracking;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apexdevtools/git-ops",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
4
4
  "description": "Library to do git operations to find changed files in a given git repository",
5
5
  "author": {
6
6
  "name": "Apex Dev Tools Team",
@@ -25,7 +25,9 @@
25
25
  "url": "https://github.com/apex-dev-tools/git-ops/issues"
26
26
  },
27
27
  "homepage": "https://github.com/apex-dev-tools/git-ops#readme",
28
- "packageManager": "pnpm@8.9.2",
28
+ "engines": {
29
+ "node": "^20.19.0 || ^22.13.0 || >=24"
30
+ },
29
31
  "dependencies": {
30
32
  "@salesforce/core": "^4.3.11",
31
33
  "@salesforce/source-deploy-retrieve": "^9.2.8",
@@ -33,22 +35,20 @@
33
35
  "simple-git": "^3.16.0"
34
36
  },
35
37
  "devDependencies": {
38
+ "@eslint/js": "^10.0.1",
36
39
  "@ryansonshine/commitizen": "^4.2.8",
37
40
  "@ryansonshine/cz-conventional-changelog": "^3.3.4",
38
- "@types/jest": "^29.5.0",
39
- "@types/node": "^18.15.11",
40
- "@typescript-eslint/eslint-plugin": "^5.59.8",
41
- "@typescript-eslint/parser": "^5.59.8",
42
- "eslint": "^8.41.0",
43
- "eslint-config-prettier": "^8.8.0",
44
- "eslint-plugin-node": "^11.1.0",
45
- "eslint-plugin-prettier": "^4.2.1",
46
- "husky": "^8.0.3",
47
- "jest": "^29.5.0",
48
- "lint-staged": "^13.2.2",
49
- "prettier": "^2.8.8",
50
- "ts-jest": "^29.1.0",
51
- "typescript": "^4.9.5"
41
+ "@types/jest": "^30.0.0",
42
+ "@types/node": "^22.19.17",
43
+ "eslint": "^10.2.1",
44
+ "eslint-config-prettier": "^10.1.8",
45
+ "husky": "^9.1.7",
46
+ "jest": "^30.3.0",
47
+ "lint-staged": "^17.0.2",
48
+ "prettier": "^3.8.3",
49
+ "ts-jest": "^29.4.5",
50
+ "typescript": "^6.0.3",
51
+ "typescript-eslint": "^8.59.0"
52
52
  },
53
53
  "config": {
54
54
  "commitizen": {
@@ -62,7 +62,7 @@
62
62
  "build": "tsc",
63
63
  "clean": "rm -rf ./lib/",
64
64
  "commit": "cz",
65
- "lint": "eslint ./src/ --fix",
65
+ "lint": "eslint --cache --cache-location .eslintcache ./src --fix",
66
66
  "test": "jest --coverage --runInBand",
67
67
  "test:watch": "jest --watch"
68
68
  }
package/lib/src/git.js DELETED
@@ -1,114 +0,0 @@
1
- "use strict";
2
- /*
3
- * Copyright (c) 2024 Certinia Inc. All rights reserved.
4
- */
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Git = exports.FileStatus = void 0;
16
- const simple_git_1 = require("simple-git");
17
- var FileStatus;
18
- (function (FileStatus) {
19
- FileStatus["Unmodified"] = " ";
20
- FileStatus["Modified"] = "M";
21
- FileStatus["TypeChanged"] = "T";
22
- FileStatus["Added"] = "A";
23
- FileStatus["Deleted"] = "D";
24
- FileStatus["Renamed"] = "R";
25
- FileStatus["Copied"] = "C";
26
- FileStatus["Updated"] = "U";
27
- FileStatus["Untracked"] = "?";
28
- FileStatus["Ignore"] = "!";
29
- })(FileStatus = exports.FileStatus || (exports.FileStatus = {}));
30
- class Git {
31
- constructor(dir) {
32
- this.gitInstance = undefined;
33
- this.dir = dir;
34
- }
35
- static versionCheck(git) {
36
- return __awaiter(this, void 0, void 0, function* () {
37
- const version = yield git.version();
38
- const isSupported = version.major >= this.MIN_GIT_VERSION_MAJOR &&
39
- version.minor >= this.MIN_GIT_VERSION_MINOR;
40
- if (!version.installed) {
41
- throw new Error('"git" is not installed or available on the PATH');
42
- }
43
- if (!isSupported)
44
- throw new Error(`Unsupported version of git. Min version must be ${this.MIN_GIT_VERSION_MAJOR}.${this.MIN_GIT_VERSION_MINOR}`);
45
- });
46
- }
47
- get git() {
48
- if (this.gitInstance)
49
- return Promise.resolve(this.gitInstance);
50
- //eslint-disable-next-line
51
- const git = (0, simple_git_1.simpleGit)(this.dir);
52
- return Git.versionCheck(git).then(() => {
53
- this.gitInstance = git;
54
- return git;
55
- });
56
- }
57
- gitRoot() {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- return (yield this.git).revparse('--show-toplevel');
60
- });
61
- }
62
- getDefaultBranchName() {
63
- return __awaiter(this, void 0, void 0, function* () {
64
- return this.git
65
- .then(git => git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD', '--short']))
66
- .catch(error => {
67
- if (error instanceof Error)
68
- throw Error(`Failed to find symbolic ref no remote HEAD with message: '${error.message.trim()}'`);
69
- else
70
- throw new Error('Failed to find symbolic ref no remote HEAD');
71
- })
72
- .then(branch => {
73
- if (branch.startsWith('origin/'))
74
- return branch.trim();
75
- else
76
- throw new Error(`Expected default branch '${branch}' to start with 'origin/'`);
77
- });
78
- });
79
- }
80
- diffRange(fromRef, toRef) {
81
- return __awaiter(this, void 0, void 0, function* () {
82
- return this.git
83
- .then(git => git.diff([`${fromRef}...${toRef}`, '--name-only', '-z']))
84
- .then(diff => {
85
- const files = diff
86
- .split('\u0000')
87
- .map(s => s.trim())
88
- .filter(s => s); //Removes any falsy values
89
- return new Set([...files]);
90
- });
91
- });
92
- }
93
- getLocalChangedAndCreated() {
94
- return __awaiter(this, void 0, void 0, function* () {
95
- const excludeStatus = [FileStatus.Deleted, FileStatus.Ignore];
96
- return this.getFilteredStatus(f => !excludeStatus.includes(f.index) &&
97
- !excludeStatus.includes(f.working_dir));
98
- });
99
- }
100
- getFilteredStatus(filterFn, gitDir) {
101
- return __awaiter(this, void 0, void 0, function* () {
102
- return this.git
103
- .then(git => {
104
- return gitDir ? git.env('GIT_DIR', gitDir).status() : git.status();
105
- })
106
- .then(status => {
107
- return new Set(...[status.files.filter(filterFn).map(f => f.path)]);
108
- });
109
- });
110
- }
111
- }
112
- exports.Git = Git;
113
- Git.MIN_GIT_VERSION_MAJOR = 2;
114
- Git.MIN_GIT_VERSION_MINOR = 20;