@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 +8 -0
- package/lib/{src/changes.js → changes.js} +52 -74
- package/lib/{src/git.d.ts → git.d.ts} +1 -1
- package/lib/git.js +93 -0
- package/lib/{src/tracking.d.ts → tracking.d.ts} +2 -0
- package/lib/tracking.js +154 -0
- package/package.json +17 -17
- package/lib/src/git.js +0 -114
- package/lib/src/tracking.js +0 -139
- package/lib/test/changes.spec.d.ts +0 -1
- package/lib/test/changes.spec.js +0 -195
- package/lib/test/git.spec.d.ts +0 -1
- package/lib/test/git.spec.js +0 -210
- package/lib/test/helpers/repo.d.ts +0 -24
- package/lib/test/helpers/repo.js +0 -131
- package/lib/test/tracking.spec.d.ts +0 -1
- package/lib/test/tracking.spec.js +0 -312
- /package/lib/{src/changes.d.ts → changes.d.ts} +0 -0
- /package/lib/{src/index.d.ts → index.d.ts} +0 -0
- /package/lib/{src/index.js → index.js} +0 -0
package/lib/src/tracking.js
DELETED
|
@@ -1,139 +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.OrgTracking = exports.FileState = void 0;
|
|
16
|
-
const core_1 = require("@salesforce/core");
|
|
17
|
-
const process_1 = require("process");
|
|
18
|
-
const source_tracking_1 = require("@salesforce/source-tracking");
|
|
19
|
-
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
20
|
-
var FileState;
|
|
21
|
-
(function (FileState) {
|
|
22
|
-
FileState["Added"] = "add";
|
|
23
|
-
FileState["Modified"] = "modify";
|
|
24
|
-
FileState["Deleted"] = "delete";
|
|
25
|
-
FileState["NonDelete"] = "nondelete";
|
|
26
|
-
FileState["Ignored"] = "ignore";
|
|
27
|
-
FileState["Conflicted"] = "conflict";
|
|
28
|
-
})(FileState = exports.FileState || (exports.FileState = {}));
|
|
29
|
-
class OrgTracking {
|
|
30
|
-
constructor(options) {
|
|
31
|
-
this.options = options;
|
|
32
|
-
this.logger = options.logger;
|
|
33
|
-
}
|
|
34
|
-
getLocalStatus(withConflicts = false) {
|
|
35
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
const project = core_1.SfProject.getInstance(this.options.projectDir);
|
|
37
|
-
const org = yield core_1.Org.create({ connection: this.options.connection });
|
|
38
|
-
return yield this.withWorkingDir(this.options.projectDir, () => __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
const tracking = yield source_tracking_1.SourceTracking.create({
|
|
40
|
-
org,
|
|
41
|
-
project,
|
|
42
|
-
ignoreLocalCache: true,
|
|
43
|
-
});
|
|
44
|
-
yield tracking.ensureRemoteTracking(true);
|
|
45
|
-
const initValue = { local: [], remote: [] };
|
|
46
|
-
const status = yield tracking
|
|
47
|
-
.getStatus({ local: true, remote: false })
|
|
48
|
-
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
if (withConflicts) {
|
|
50
|
-
//Taken from sourceTracking.ts from the @salesforce/source-tracking lib
|
|
51
|
-
const conflictFiles = (yield tracking.getConflicts())
|
|
52
|
-
.flatMap(conflict => conflict.filenames)
|
|
53
|
-
.filter((value) => typeof value === 'string');
|
|
54
|
-
res = res.map(row => (Object.assign(Object.assign({}, row), { conflict: !!row.filePath && conflictFiles.includes(row.filePath) })));
|
|
55
|
-
}
|
|
56
|
-
return res;
|
|
57
|
-
}))
|
|
58
|
-
.catch(e => {
|
|
59
|
-
this.logger.logError(e);
|
|
60
|
-
return [];
|
|
61
|
-
});
|
|
62
|
-
return status.reduce((acc, row) => {
|
|
63
|
-
acc[row.origin].push(this.toSyncStatusRow(row));
|
|
64
|
-
return acc;
|
|
65
|
-
}, initValue);
|
|
66
|
-
}));
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
deployAndUpdateSourceTracking(paths) {
|
|
70
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
return yield this.withWorkingDir(this.options.projectDir, () => __awaiter(this, void 0, void 0, function* () {
|
|
72
|
-
return this.deploy(paths)
|
|
73
|
-
.then(res => this.updateSourceTracking(res))
|
|
74
|
-
.catch(e => this.logger.logError(e));
|
|
75
|
-
}));
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
deploy(paths) {
|
|
79
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
80
|
-
const set = source_deploy_retrieve_1.ComponentSet.fromSource(paths);
|
|
81
|
-
const deploy = yield set.deploy({
|
|
82
|
-
usernameOrConnection: this.options.connection,
|
|
83
|
-
});
|
|
84
|
-
this.logger.logDeployProgress('Starting deploy');
|
|
85
|
-
deploy.onUpdate(response => {
|
|
86
|
-
const { status, numberComponentsDeployed, numberComponentsTotal } = response;
|
|
87
|
-
const progress = `${numberComponentsDeployed}/${numberComponentsTotal}`;
|
|
88
|
-
const message = `Status: ${status} Progress: ${progress}`;
|
|
89
|
-
this.logger.logDeployProgress(message);
|
|
90
|
-
});
|
|
91
|
-
return yield deploy.pollStatus().then(res => {
|
|
92
|
-
this.logger.logMessage('Finished deploy');
|
|
93
|
-
return res;
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
updateSourceTracking(result) {
|
|
98
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
-
const project = core_1.SfProject.getInstance(this.options.projectDir);
|
|
100
|
-
const org = yield core_1.Org.create({ connection: this.options.connection });
|
|
101
|
-
const tracking = yield source_tracking_1.SourceTracking.create({
|
|
102
|
-
org,
|
|
103
|
-
project,
|
|
104
|
-
ignoreLocalCache: true,
|
|
105
|
-
});
|
|
106
|
-
yield tracking.updateTrackingFromDeploy(result);
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
toSyncStatusRow(from) {
|
|
110
|
-
const state = [];
|
|
111
|
-
if (from.ignored) {
|
|
112
|
-
state.push(FileState.Ignored);
|
|
113
|
-
}
|
|
114
|
-
if (from.conflict) {
|
|
115
|
-
state.push(FileState.Conflicted);
|
|
116
|
-
}
|
|
117
|
-
state.push(from.state);
|
|
118
|
-
return {
|
|
119
|
-
fullName: from.fullName,
|
|
120
|
-
path: from.filePath,
|
|
121
|
-
state: state,
|
|
122
|
-
type: from.type,
|
|
123
|
-
origin: from.origin,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
withWorkingDir(path, op) {
|
|
127
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
128
|
-
const startDir = (0, process_1.cwd)();
|
|
129
|
-
(0, process_1.chdir)(path);
|
|
130
|
-
try {
|
|
131
|
-
return yield op();
|
|
132
|
-
}
|
|
133
|
-
finally {
|
|
134
|
-
(0, process_1.chdir)(startDir);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
exports.OrgTracking = OrgTracking;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/test/changes.spec.js
DELETED
|
@@ -1,195 +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
|
-
const src_1 = require("../src");
|
|
16
|
-
const mockGitImpl = {
|
|
17
|
-
getDefaultBranchName: jest.fn(),
|
|
18
|
-
getLocalChangedAndCreated: jest.fn(),
|
|
19
|
-
diffRange: jest.fn(),
|
|
20
|
-
gitRoot: jest.fn(),
|
|
21
|
-
getFilteredStatus: jest.fn(),
|
|
22
|
-
};
|
|
23
|
-
jest.mock('../src/git', () => {
|
|
24
|
-
const { FileStatus } = jest.requireActual('../src/git');
|
|
25
|
-
return {
|
|
26
|
-
Git: jest.fn().mockImplementation(() => mockGitImpl),
|
|
27
|
-
FileStatus,
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
describe('Branch changes', () => {
|
|
31
|
-
const mockRootDir = '/reporoot';
|
|
32
|
-
beforeEach(() => {
|
|
33
|
-
mockGitImpl.gitRoot.mockResolvedValue(mockRootDir);
|
|
34
|
-
});
|
|
35
|
-
afterEach(() => {
|
|
36
|
-
jest.clearAllMocks();
|
|
37
|
-
mockGitImpl.getDefaultBranchName.mockReset();
|
|
38
|
-
mockGitImpl.getLocalChangedAndCreated.mockReset();
|
|
39
|
-
mockGitImpl.diffRange.mockReset();
|
|
40
|
-
mockGitImpl.gitRoot.mockReset();
|
|
41
|
-
mockGitImpl.getFilteredStatus.mockReset();
|
|
42
|
-
});
|
|
43
|
-
describe('getDefaultBranchDiffByRef', () => {
|
|
44
|
-
it('returns the correct set of files when git ops resolve', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
-
//Given
|
|
46
|
-
mockGitImpl.getDefaultBranchName.mockResolvedValue('default/branch/name');
|
|
47
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
48
|
-
mockGitImpl.getLocalChangedAndCreated.mockResolvedValue(new Set(['SomeFile.txt']));
|
|
49
|
-
//When
|
|
50
|
-
const res = yield (0, src_1.getDefaultBranchDiffByRef)('./some/path/to/dir', 'abc12fcd');
|
|
51
|
-
//Then
|
|
52
|
-
expect(mockGitImpl.getDefaultBranchName).toBeCalledTimes(1);
|
|
53
|
-
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
54
|
-
expect(mockGitImpl.diffRange).toHaveBeenCalledWith('default/branch/name', 'abc12fcd');
|
|
55
|
-
expect(res).toEqual(new Set([
|
|
56
|
-
`${mockRootDir}/File.txt`,
|
|
57
|
-
`${mockRootDir}/AnotherClass.txt`,
|
|
58
|
-
`${mockRootDir}/SomeFile.txt`,
|
|
59
|
-
]));
|
|
60
|
-
}));
|
|
61
|
-
it('rejects and throws error when "getDefaultBranchName" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
-
//Given
|
|
63
|
-
mockGitImpl.getDefaultBranchName.mockRejectedValue(Error('no head ref error'));
|
|
64
|
-
//When/Then
|
|
65
|
-
yield expect((0, src_1.getDefaultBranchDiffByRef)('./some/path/to/dir', 'abc12fcd')).rejects.toEqual(Error("Local branch operation failed. Cause: 'no head ref error'"));
|
|
66
|
-
}));
|
|
67
|
-
it('rejects and throws error when "getLocalChangedAndCreated" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
68
|
-
//Given
|
|
69
|
-
mockGitImpl.getDefaultBranchName.mockResolvedValue('default/branch/name');
|
|
70
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
71
|
-
mockGitImpl.getLocalChangedAndCreated.mockRejectedValue(Error('op failed'));
|
|
72
|
-
//When/Then
|
|
73
|
-
yield expect((0, src_1.getDefaultBranchDiffByRef)('./some/path/to/dir', 'abc12fcd')).rejects.toEqual(Error("Local branch operation failed. Cause: 'Getting diff operation failed. Cause: 'op failed''"));
|
|
74
|
-
}));
|
|
75
|
-
});
|
|
76
|
-
describe('getDefaultBranchDiff', () => {
|
|
77
|
-
it('returns the correct set of files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
-
//Given
|
|
79
|
-
mockGitImpl.getDefaultBranchName.mockResolvedValue('default/branch/name');
|
|
80
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
81
|
-
mockGitImpl.getLocalChangedAndCreated.mockResolvedValue(new Set(['SomeFile.txt']));
|
|
82
|
-
//When
|
|
83
|
-
const res = yield (0, src_1.getDefaultBranchDiff)('./some/path/to/dir');
|
|
84
|
-
//Then
|
|
85
|
-
expect(mockGitImpl.getDefaultBranchName).toBeCalledTimes(1);
|
|
86
|
-
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
87
|
-
expect(mockGitImpl.diffRange).toHaveBeenCalledWith('default/branch/name', 'HEAD');
|
|
88
|
-
expect(res).toEqual(new Set([
|
|
89
|
-
`${mockRootDir}/File.txt`,
|
|
90
|
-
`${mockRootDir}/AnotherClass.txt`,
|
|
91
|
-
`${mockRootDir}/SomeFile.txt`,
|
|
92
|
-
]));
|
|
93
|
-
}));
|
|
94
|
-
it('rejects and throws error when "getLocalChangedAndCreated" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
-
//Given
|
|
96
|
-
mockGitImpl.getDefaultBranchName.mockResolvedValue('default/branch/name');
|
|
97
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
98
|
-
mockGitImpl.getLocalChangedAndCreated.mockRejectedValue(Error('op failed'));
|
|
99
|
-
//When/Then
|
|
100
|
-
yield expect((0, src_1.getDefaultBranchDiff)('./some/path/to/dir')).rejects.toEqual(Error("Local branch operation failed. Cause: 'Getting diff operation failed. Cause: 'op failed''"));
|
|
101
|
-
}));
|
|
102
|
-
});
|
|
103
|
-
describe('getDiffRange', () => {
|
|
104
|
-
it('returns the correct set of files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
|
-
//Given
|
|
106
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
107
|
-
mockGitImpl.getLocalChangedAndCreated.mockResolvedValue(new Set(['SomeFile.txt']));
|
|
108
|
-
//When
|
|
109
|
-
const res = yield (0, src_1.getDiffRange)('./some/path/to/dir', 'ref1', 'ref2');
|
|
110
|
-
//Then
|
|
111
|
-
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
112
|
-
expect(mockGitImpl.diffRange).toHaveBeenCalledWith('ref1', 'ref2');
|
|
113
|
-
expect(res).toEqual(new Set([
|
|
114
|
-
`${mockRootDir}/File.txt`,
|
|
115
|
-
`${mockRootDir}/AnotherClass.txt`,
|
|
116
|
-
`${mockRootDir}/SomeFile.txt`,
|
|
117
|
-
]));
|
|
118
|
-
}));
|
|
119
|
-
it('rejects and throws error when "getLocalChangedAndCreated" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
|
-
//Given
|
|
121
|
-
mockGitImpl.getDefaultBranchName.mockResolvedValue('default/branch/name');
|
|
122
|
-
mockGitImpl.diffRange.mockResolvedValue(new Set(['File.txt', 'AnotherClass.txt']));
|
|
123
|
-
mockGitImpl.getLocalChangedAndCreated.mockRejectedValue(Error('op failed'));
|
|
124
|
-
//When/Then
|
|
125
|
-
yield expect((0, src_1.getDiffRange)('./some/path/to/dir', 'ref1', 'ref2')).rejects.toEqual(Error("Getting diff operation failed. Cause: 'op failed'"));
|
|
126
|
-
}));
|
|
127
|
-
});
|
|
128
|
-
describe('getLocalChanges', () => {
|
|
129
|
-
it('returns the correct set of files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
130
|
-
//Given
|
|
131
|
-
mockGitImpl.getLocalChangedAndCreated.mockResolvedValue(new Set(['SomeFile.txt']));
|
|
132
|
-
//When
|
|
133
|
-
const res = yield (0, src_1.getLocalChanges)('./some/path/to/dir');
|
|
134
|
-
//Then
|
|
135
|
-
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
136
|
-
expect(res).toEqual(new Set([`${mockRootDir}/SomeFile.txt`]));
|
|
137
|
-
}));
|
|
138
|
-
it('rejects and throws error when op fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
139
|
-
//Given
|
|
140
|
-
mockGitImpl.getLocalChangedAndCreated.mockRejectedValue(Error('op failed'));
|
|
141
|
-
//When/Then
|
|
142
|
-
yield expect((0, src_1.getLocalChanges)('./some/path/to/dir')).rejects.toEqual(Error("Getting local changes operation failed. Cause: 'op failed'"));
|
|
143
|
-
}));
|
|
144
|
-
});
|
|
145
|
-
describe('getDeployableClasses', () => {
|
|
146
|
-
it('returns the correct set of files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
147
|
-
//Given
|
|
148
|
-
const pdir = `${mockRootDir}/project/dir`;
|
|
149
|
-
mockGitImpl.getFilteredStatus.mockImplementation(fn => {
|
|
150
|
-
const files = [
|
|
151
|
-
{
|
|
152
|
-
path: `${pdir}/SomeFile.cls`,
|
|
153
|
-
working_dir: 'M',
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
return Promise.resolve(new Set(files.filter(fn).map(p => p.path)));
|
|
157
|
-
});
|
|
158
|
-
//When
|
|
159
|
-
const res = yield (0, src_1.getDeployableClasses)(pdir, 'orgId');
|
|
160
|
-
//Then
|
|
161
|
-
expect(mockGitImpl.getFilteredStatus).toBeCalledTimes(1);
|
|
162
|
-
expect(mockGitImpl.getFilteredStatus).toHaveBeenCalledWith(expect.anything(), `${pdir}/.sf/orgs/orgId/localSourceTracking`);
|
|
163
|
-
expect(res).toEqual(new Set([`${pdir}/SomeFile.cls`]));
|
|
164
|
-
}));
|
|
165
|
-
it('filters non classes and deleted', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
166
|
-
//Given
|
|
167
|
-
const pdir = `${mockRootDir}/project/dir`;
|
|
168
|
-
mockGitImpl.getFilteredStatus.mockImplementation(fn => {
|
|
169
|
-
const files = [
|
|
170
|
-
{
|
|
171
|
-
path: `${pdir}/SomeFile.txt`,
|
|
172
|
-
working_dir: 'M',
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
path: `${pdir}/SomeFile2.cls`,
|
|
176
|
-
working_dir: 'D',
|
|
177
|
-
},
|
|
178
|
-
];
|
|
179
|
-
return Promise.resolve(new Set(files.filter(fn).map(p => p.path)));
|
|
180
|
-
});
|
|
181
|
-
//When
|
|
182
|
-
const res = yield (0, src_1.getDeployableClasses)(pdir, 'orgId');
|
|
183
|
-
//Then
|
|
184
|
-
expect(mockGitImpl.getFilteredStatus).toBeCalledTimes(1);
|
|
185
|
-
expect(mockGitImpl.getFilteredStatus).toHaveBeenCalledWith(expect.anything(), `${pdir}/.sf/orgs/orgId/localSourceTracking`);
|
|
186
|
-
expect(res).toEqual(new Set());
|
|
187
|
-
}));
|
|
188
|
-
it('rejects and throws error when op fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
189
|
-
//Given
|
|
190
|
-
mockGitImpl.getFilteredStatus.mockRejectedValue(Error('op failed'));
|
|
191
|
-
//When/Then
|
|
192
|
-
yield expect((0, src_1.getDeployableClasses)('/project/dir', 'orgId')).rejects.toEqual(Error("Getting local changes operation failed. Cause: 'op failed'"));
|
|
193
|
-
}));
|
|
194
|
-
});
|
|
195
|
-
});
|
package/lib/test/git.spec.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/test/git.spec.js
DELETED
|
@@ -1,210 +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
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
-
};
|
|
17
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
const path_1 = __importDefault(require("path"));
|
|
19
|
-
const src_1 = require("../src");
|
|
20
|
-
const repo_1 = require("./helpers/repo");
|
|
21
|
-
describe('Git', () => {
|
|
22
|
-
const dir = './test/repos';
|
|
23
|
-
const repoHelper = repo_1.RepoHelper.getInstance(dir);
|
|
24
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
-
yield repoHelper.init();
|
|
26
|
-
}));
|
|
27
|
-
afterEach(() => {
|
|
28
|
-
repoHelper.tearDown();
|
|
29
|
-
});
|
|
30
|
-
describe('version check', () => {
|
|
31
|
-
it('does not fail when Git version is equal to 2.20.0', () => {
|
|
32
|
-
//Given/When
|
|
33
|
-
const mock = {
|
|
34
|
-
version: jest.fn().mockReturnValue({
|
|
35
|
-
installed: true,
|
|
36
|
-
major: 2,
|
|
37
|
-
minor: 20,
|
|
38
|
-
patch: 0,
|
|
39
|
-
}),
|
|
40
|
-
};
|
|
41
|
-
expect(src_1.Git.versionCheck(mock)).resolves;
|
|
42
|
-
});
|
|
43
|
-
it('does not fail when Git version is higher', () => {
|
|
44
|
-
//Given/When
|
|
45
|
-
const mock = {
|
|
46
|
-
version: jest.fn().mockReturnValue({
|
|
47
|
-
installed: true,
|
|
48
|
-
major: 2,
|
|
49
|
-
minor: 30,
|
|
50
|
-
patch: 2,
|
|
51
|
-
}),
|
|
52
|
-
};
|
|
53
|
-
//Then
|
|
54
|
-
expect(src_1.Git.versionCheck(mock)).resolves;
|
|
55
|
-
});
|
|
56
|
-
it('fails when Git is not installed', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
-
//Given/When
|
|
58
|
-
const mock = {
|
|
59
|
-
version: jest.fn().mockReturnValue({ installed: false }),
|
|
60
|
-
};
|
|
61
|
-
//Then
|
|
62
|
-
yield expect(src_1.Git.versionCheck(mock)).rejects.toThrow(Error('"git" is not installed or available on the PATH'));
|
|
63
|
-
}));
|
|
64
|
-
it('fails when Git major version is lower', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
-
//Given/When
|
|
66
|
-
const mock = {
|
|
67
|
-
version: jest.fn().mockReturnValue({
|
|
68
|
-
installed: true,
|
|
69
|
-
major: 1,
|
|
70
|
-
}),
|
|
71
|
-
};
|
|
72
|
-
//Then
|
|
73
|
-
yield expect(src_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.20'));
|
|
74
|
-
}));
|
|
75
|
-
it('fails when Git minor version is lower', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
-
//Given/When
|
|
77
|
-
const mock = {
|
|
78
|
-
version: jest.fn().mockReturnValue({
|
|
79
|
-
installed: true,
|
|
80
|
-
major: 2,
|
|
81
|
-
minor: 19,
|
|
82
|
-
}),
|
|
83
|
-
};
|
|
84
|
-
//Then
|
|
85
|
-
yield expect(src_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.20'));
|
|
86
|
-
}));
|
|
87
|
-
});
|
|
88
|
-
describe('rev parse', () => {
|
|
89
|
-
it('get git root', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
-
const repoDirPath = path_1.default.resolve(repoHelper.repoDir);
|
|
91
|
-
const revParse = yield new src_1.Git(repoHelper.repoDir).gitRoot();
|
|
92
|
-
expect(revParse).toBe(repoDirPath);
|
|
93
|
-
}));
|
|
94
|
-
});
|
|
95
|
-
describe('branch operation', () => {
|
|
96
|
-
it('fails to find default branch name when head is not set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
-
//Given/When/Then
|
|
98
|
-
yield expect(new src_1.Git(repoHelper.repoDir).getDefaultBranchName()).rejects.toThrow(Error("Failed to find symbolic ref no remote HEAD with message: 'fatal: ref refs/remotes/origin/HEAD is not a symbolic ref'"));
|
|
99
|
-
}));
|
|
100
|
-
it('find default branch name when head is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
-
//Given
|
|
102
|
-
repoHelper.createOrUpdateFile('file.txt', 'Test Text');
|
|
103
|
-
yield repoHelper
|
|
104
|
-
.stageAndCommitAll(['file.txt'])
|
|
105
|
-
.then(() => repoHelper.push())
|
|
106
|
-
.then(() => repoHelper.setHead());
|
|
107
|
-
//When
|
|
108
|
-
const branchName = yield new src_1.Git(repoHelper.repoDir).getDefaultBranchName();
|
|
109
|
-
//Then
|
|
110
|
-
expect(branchName).toBe('origin/main');
|
|
111
|
-
}));
|
|
112
|
-
it('find default branch name when head is set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
113
|
-
//Given
|
|
114
|
-
repoHelper.createOrUpdateFile('file.txt', 'Test Text');
|
|
115
|
-
yield repoHelper
|
|
116
|
-
.stageAndCommitAll(['file.txt'])
|
|
117
|
-
.then(() => repoHelper.push())
|
|
118
|
-
.then(() => repoHelper.setHead());
|
|
119
|
-
//When
|
|
120
|
-
const branchName = yield new src_1.Git(repoHelper.repoDir).getDefaultBranchName();
|
|
121
|
-
//Then
|
|
122
|
-
expect(branchName).toBe('origin/main');
|
|
123
|
-
}));
|
|
124
|
-
});
|
|
125
|
-
describe('file change operations', () => {
|
|
126
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
-
repoHelper.createOrUpdateFile('file.txt', 'text');
|
|
128
|
-
yield repoHelper
|
|
129
|
-
.stageAndCommitAll(['file.txt'])
|
|
130
|
-
.then(() => repoHelper.push())
|
|
131
|
-
.then(() => repoHelper.setHead());
|
|
132
|
-
}));
|
|
133
|
-
describe('local changes', () => {
|
|
134
|
-
it('finds modified files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
-
//Given
|
|
136
|
-
repoHelper.createOrUpdateFile('file.txt', 'modify');
|
|
137
|
-
//When
|
|
138
|
-
const files = yield new src_1.Git(repoHelper.repoDir).getLocalChangedAndCreated();
|
|
139
|
-
//Then
|
|
140
|
-
expect(files).toEqual(new Set(['file.txt']));
|
|
141
|
-
}));
|
|
142
|
-
it('finds unstaged renamed files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
143
|
-
//Given
|
|
144
|
-
repoHelper.renameFileInRepo('file.txt', 'renamed.txt');
|
|
145
|
-
// await repoHelper.gitStage();
|
|
146
|
-
//When
|
|
147
|
-
const files = yield new src_1.Git(repoHelper.repoDir).getLocalChangedAndCreated();
|
|
148
|
-
//Then
|
|
149
|
-
expect(files).toEqual(new Set(['renamed.txt']));
|
|
150
|
-
}));
|
|
151
|
-
it('finds unstaged new files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
152
|
-
//Given
|
|
153
|
-
repoHelper.createOrUpdateFile('newFile.txt', 'content');
|
|
154
|
-
//When
|
|
155
|
-
const files = yield new src_1.Git(repoHelper.repoDir).getLocalChangedAndCreated();
|
|
156
|
-
//Then
|
|
157
|
-
expect(files).toEqual(new Set(['newFile.txt']));
|
|
158
|
-
}));
|
|
159
|
-
it('does not include deleted files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
160
|
-
//Given
|
|
161
|
-
repoHelper.rmFile('file.txt');
|
|
162
|
-
//When
|
|
163
|
-
const files = yield new src_1.Git(repoHelper.repoDir).getLocalChangedAndCreated();
|
|
164
|
-
//Then
|
|
165
|
-
expect(files).toEqual(new Set());
|
|
166
|
-
}));
|
|
167
|
-
it('finds staged renamed, modified and new files ', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
168
|
-
//Setup for renamed file
|
|
169
|
-
repoHelper.createOrUpdateFile('second.txt', 'txt');
|
|
170
|
-
yield repoHelper.stageAndCommitAll(['second.txt']);
|
|
171
|
-
//Given
|
|
172
|
-
repoHelper.createOrUpdateFile('file.txt', 'modifiy');
|
|
173
|
-
repoHelper.renameFileInRepo('second.txt', 'renamed.txt');
|
|
174
|
-
repoHelper.createOrUpdateFile('newFile.txt', 'content');
|
|
175
|
-
yield repoHelper.stageAll();
|
|
176
|
-
//When
|
|
177
|
-
const files = yield new src_1.Git(repoHelper.repoDir).getLocalChangedAndCreated();
|
|
178
|
-
//Then
|
|
179
|
-
expect(files).toEqual(new Set(['file.txt', 'renamed.txt', 'newFile.txt']));
|
|
180
|
-
}));
|
|
181
|
-
});
|
|
182
|
-
describe('branch diff changes', () => {
|
|
183
|
-
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
184
|
-
yield repoHelper
|
|
185
|
-
.checkout('dev', 'main')
|
|
186
|
-
.then(() => repoHelper.createOrUpdateFile('newFile.txt', 'text'))
|
|
187
|
-
.then(() => repoHelper.stageAndCommitAll(['newFile.txt']));
|
|
188
|
-
}));
|
|
189
|
-
it('finds diff against for default branch and HEAD', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
-
//Given
|
|
191
|
-
repoHelper.createOrUpdateFile('anotherFileForCommit.txt', 'text');
|
|
192
|
-
yield repoHelper.stageAndCommitAll(['anotherFileForCommit.txt']);
|
|
193
|
-
//When
|
|
194
|
-
const files = yield new src_1.Git(repoHelper.repoDir).diffRange('origin/main', 'HEAD');
|
|
195
|
-
//Then
|
|
196
|
-
expect(files).toEqual(new Set(['newFile.txt', 'anotherFileForCommit.txt']));
|
|
197
|
-
}));
|
|
198
|
-
it('finds diff against default branch and commit ref', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
199
|
-
//Given
|
|
200
|
-
const currentRef = (yield repoHelper.getGitLog())[0].hash;
|
|
201
|
-
repoHelper.createOrUpdateFile('anotherFileForCommit.txt', 'text');
|
|
202
|
-
yield repoHelper.stageAndCommitAll(['anotherFileForCommit.txt']);
|
|
203
|
-
//When
|
|
204
|
-
const files = yield new src_1.Git(repoHelper.repoDir).diffRange('origin/main', currentRef);
|
|
205
|
-
//Then
|
|
206
|
-
expect(files).toEqual(new Set(['newFile.txt']));
|
|
207
|
-
}));
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export declare class RepoHelper {
|
|
2
|
-
private isInit;
|
|
3
|
-
private rootDir;
|
|
4
|
-
private remoteRepoDir;
|
|
5
|
-
private testRepoDir;
|
|
6
|
-
private static instances;
|
|
7
|
-
private constructor();
|
|
8
|
-
static getInstance(rootDir: string): RepoHelper;
|
|
9
|
-
private get git();
|
|
10
|
-
private initRemoteRepo;
|
|
11
|
-
private cloneRepo;
|
|
12
|
-
get repoDir(): string;
|
|
13
|
-
init(): Promise<void>;
|
|
14
|
-
setHead(): Promise<string | void>;
|
|
15
|
-
push(): Promise<void | import("simple-git").PushResult>;
|
|
16
|
-
checkout(branchName: string, from: string): Promise<void>;
|
|
17
|
-
stageAll(files?: string[]): Promise<string>;
|
|
18
|
-
getGitLog(): Promise<readonly (import("simple-git").DefaultLogFields & import("simple-git").ListLogLine)[]>;
|
|
19
|
-
stageAndCommitAll(files?: string[]): Promise<import("simple-git").CommitResult>;
|
|
20
|
-
tearDown(): void;
|
|
21
|
-
createOrUpdateFile(fileName: string, content: string): void;
|
|
22
|
-
rmFile(file: string): void;
|
|
23
|
-
renameFileInRepo(from: string, to: string): void;
|
|
24
|
-
}
|