@apexdevtools/git-ops 1.0.0 → 1.0.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 +9 -1
- package/README.md +11 -1
- package/lib/src/FilesChanged/BranchChanges.d.ts +15 -0
- package/lib/src/FilesChanged/BranchChanges.js +24 -0
- package/lib/src/Git/Git.d.ts +1 -0
- package/lib/src/Git/Git.js +6 -1
- package/lib/src/api/IGit.d.ts +1 -0
- package/lib/test/BranchChanges/BranchChanges.spec.js +24 -2
- package/lib/test/Git/Git.spec.js +17 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Library to do git operations to find changed files in a given git repository.
|
|
4
4
|
|
|
5
|
+
## Prerequisite
|
|
6
|
+
|
|
7
|
+
Minimum `git` version of `2.30.0` must already be installed on the host machine.
|
|
8
|
+
|
|
5
9
|
## Getting Started
|
|
6
10
|
|
|
7
11
|
To build run
|
|
@@ -21,9 +25,15 @@ pnpm test
|
|
|
21
25
|
|
|
22
26
|
**Prerequisite**: The head mus tbe set on the repo otherwise any functions using default branch will fail
|
|
23
27
|
|
|
28
|
+
### Installation
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
npm i @apexdevtools/git-ops
|
|
32
|
+
```
|
|
33
|
+
|
|
24
34
|
### Finding changed files
|
|
25
35
|
|
|
26
|
-
Getting changed files using the default branch in that repo given a ref. This
|
|
36
|
+
Getting changed files using the default branch in that repo given a ref. This finds the default branch in the repo using `git symbolic-ref 'refs/remotes/origin/HEAD'` so the `HEAD` must be set.
|
|
27
37
|
The output of the command is same as running `git diff branchName...ref` combined with `git status`.
|
|
28
38
|
|
|
29
39
|
**Note:** files with the status of deleted (`D`) and ignored (`!`) will not be included in the change set.
|
|
@@ -1,2 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Works out a set of changed files by performing getDefaultBranchDiffByRef(repoRootDir, 'HEAD')
|
|
3
|
+
* @param dir: string of the directory thr operation should be performed on
|
|
4
|
+
* @returns set of absolute paths of changed files
|
|
5
|
+
*/
|
|
1
6
|
export declare function getDefaultBranchDiff(dir: string): Promise<Set<string>>;
|
|
7
|
+
/**
|
|
8
|
+
* Works out changed files using the default branch in that repo given a ref.
|
|
9
|
+
* This find the default branch in the repo using `git symbolic-ref 'refs/remotes/origin/HEAD'`
|
|
10
|
+
* so the `HEAD` must be set. The output of the command is same as running `git diff branchName...ref`
|
|
11
|
+
* combined with `git status`.
|
|
12
|
+
* Files with the status of deleted (`D`) and ignored (`!`) will not be included in the change set.
|
|
13
|
+
* @param dir: string of the directory thr operation should be performed on
|
|
14
|
+
* @param red: string git ref. i.e HEAD, or commit hash
|
|
15
|
+
* @returns set of absolute paths of changed files
|
|
16
|
+
*/
|
|
2
17
|
export declare function getDefaultBranchDiffByRef(dir: string, ref: string): Promise<Set<string>>;
|
|
@@ -11,23 +11,47 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
12
|
});
|
|
13
13
|
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
14
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
18
|
exports.getDefaultBranchDiffByRef = exports.getDefaultBranchDiff = void 0;
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
16
20
|
const Git_1 = require("../Git/Git");
|
|
21
|
+
/**
|
|
22
|
+
* Works out a set of changed files by performing getDefaultBranchDiffByRef(repoRootDir, 'HEAD')
|
|
23
|
+
* @param dir: string of the directory thr operation should be performed on
|
|
24
|
+
* @returns set of absolute paths of changed files
|
|
25
|
+
*/
|
|
17
26
|
function getDefaultBranchDiff(dir) {
|
|
18
27
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
28
|
return getDefaultBranchDiffByRef(dir, 'HEAD');
|
|
20
29
|
});
|
|
21
30
|
}
|
|
22
31
|
exports.getDefaultBranchDiff = getDefaultBranchDiff;
|
|
32
|
+
/**
|
|
33
|
+
* Works out changed files using the default branch in that repo given a ref.
|
|
34
|
+
* This find the default branch in the repo using `git symbolic-ref 'refs/remotes/origin/HEAD'`
|
|
35
|
+
* so the `HEAD` must be set. The output of the command is same as running `git diff branchName...ref`
|
|
36
|
+
* combined with `git status`.
|
|
37
|
+
* Files with the status of deleted (`D`) and ignored (`!`) will not be included in the change set.
|
|
38
|
+
* @param dir: string of the directory thr operation should be performed on
|
|
39
|
+
* @param red: string git ref. i.e HEAD, or commit hash
|
|
40
|
+
* @returns set of absolute paths of changed files
|
|
41
|
+
*/
|
|
23
42
|
function getDefaultBranchDiffByRef(dir, ref) {
|
|
24
43
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
44
|
const git = new Git_1.Git(dir);
|
|
45
|
+
const root = yield git.gitRoot();
|
|
26
46
|
return git
|
|
27
47
|
.getDefaultBranchName()
|
|
28
48
|
.then((branchName) => __awaiter(this, void 0, void 0, function* () {
|
|
29
49
|
return yield getChanges(git, branchName, ref);
|
|
30
50
|
}))
|
|
51
|
+
.then(changes => {
|
|
52
|
+
const fullPaths = [...changes].map(p => path_1.default.resolve(path_1.default.join(root, p)));
|
|
53
|
+
return new Set(fullPaths);
|
|
54
|
+
})
|
|
31
55
|
.catch(er => {
|
|
32
56
|
if (er instanceof Error)
|
|
33
57
|
throw Error(`Failed getting diff: ${er.message}`);
|
package/lib/src/Git/Git.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class Git implements IGit {
|
|
|
21
21
|
constructor(dir: string);
|
|
22
22
|
static versionCheck(git: SimpleGit): Promise<void>;
|
|
23
23
|
private get git();
|
|
24
|
+
gitRoot(): Promise<string>;
|
|
24
25
|
getDefaultBranchName(): Promise<string>;
|
|
25
26
|
diffRange(fromRef: string, toRef: string): Promise<Set<string>>;
|
|
26
27
|
getLocalChangedAndCreated(): Promise<Set<string>>;
|
package/lib/src/Git/Git.js
CHANGED
|
@@ -51,6 +51,11 @@ class Git {
|
|
|
51
51
|
return git;
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
+
gitRoot() {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
return (yield this.git).revparse('--show-toplevel');
|
|
57
|
+
});
|
|
58
|
+
}
|
|
54
59
|
getDefaultBranchName() {
|
|
55
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
56
61
|
return this.git
|
|
@@ -99,6 +104,6 @@ class Git {
|
|
|
99
104
|
}
|
|
100
105
|
exports.Git = Git;
|
|
101
106
|
Git.MIN_GIT_VERSION_MAJOR = 2;
|
|
102
|
-
Git.MIN_GIT_VERSION_MINOR =
|
|
107
|
+
Git.MIN_GIT_VERSION_MINOR = 30;
|
|
103
108
|
Git.MIN_GIT_VERSION_PATCH = 0;
|
|
104
109
|
Git.gitInstance = undefined;
|
package/lib/src/api/IGit.d.ts
CHANGED
|
@@ -11,13 +11,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
12
|
});
|
|
13
13
|
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
14
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
18
|
const Git_1 = require("../../src/Git/Git");
|
|
16
19
|
const BranchChanges_1 = require("../../src/FilesChanged/BranchChanges");
|
|
20
|
+
const path_1 = __importDefault(require("path"));
|
|
21
|
+
jest.mock('path');
|
|
17
22
|
const mockGitImpl = {
|
|
18
23
|
getDefaultBranchName: jest.fn(),
|
|
19
24
|
getLocalChangedAndCreated: jest.fn(),
|
|
20
25
|
diffRange: jest.fn(),
|
|
26
|
+
gitRoot: jest.fn(),
|
|
21
27
|
};
|
|
22
28
|
jest.mock('../../src/Git/Git', () => {
|
|
23
29
|
return {
|
|
@@ -26,6 +32,14 @@ jest.mock('../../src/Git/Git', () => {
|
|
|
26
32
|
});
|
|
27
33
|
const mockedGit = jest.mocked(Git_1.Git, { shallow: true });
|
|
28
34
|
describe('Branch changes', () => {
|
|
35
|
+
const mockRootDir = 'user/fake/path';
|
|
36
|
+
beforeAll(() => {
|
|
37
|
+
mockGitImpl.gitRoot.mockResolvedValue('abs/path/to/repo');
|
|
38
|
+
jest
|
|
39
|
+
.spyOn(path_1.default, 'resolve')
|
|
40
|
+
.mockImplementation(dir => `${mockRootDir}/${dir}`);
|
|
41
|
+
jest.spyOn(path_1.default, 'join').mockImplementation((a, b) => `${a}/${b}`);
|
|
42
|
+
});
|
|
29
43
|
afterEach(() => {
|
|
30
44
|
jest.clearAllMocks();
|
|
31
45
|
});
|
|
@@ -42,7 +56,11 @@ describe('Branch changes', () => {
|
|
|
42
56
|
expect(mockGitImpl.getDefaultBranchName).toBeCalledTimes(1);
|
|
43
57
|
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
44
58
|
expect(mockGitImpl.diffRange).toHaveBeenCalledWith('default/branch/name', 'abc12fcd');
|
|
45
|
-
expect(res).toEqual(new Set([
|
|
59
|
+
expect(res).toEqual(new Set([
|
|
60
|
+
`${mockRootDir}/abs/path/to/repo/File.txt`,
|
|
61
|
+
`${mockRootDir}/abs/path/to/repo/AnotherClass.txt`,
|
|
62
|
+
`${mockRootDir}/abs/path/to/repo/SomeFile.txt`,
|
|
63
|
+
]));
|
|
46
64
|
}));
|
|
47
65
|
it('rejects and throws error when "getDefaultBranchName" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
66
|
//Given
|
|
@@ -72,7 +90,11 @@ describe('Branch changes', () => {
|
|
|
72
90
|
expect(mockGitImpl.getDefaultBranchName).toBeCalledTimes(1);
|
|
73
91
|
expect(mockGitImpl.getLocalChangedAndCreated).toBeCalledTimes(1);
|
|
74
92
|
expect(mockGitImpl.diffRange).toHaveBeenCalledWith('default/branch/name', 'HEAD');
|
|
75
|
-
expect(res).toEqual(new Set([
|
|
93
|
+
expect(res).toEqual(new Set([
|
|
94
|
+
`${mockRootDir}/abs/path/to/repo/File.txt`,
|
|
95
|
+
`${mockRootDir}/abs/path/to/repo/AnotherClass.txt`,
|
|
96
|
+
`${mockRootDir}/abs/path/to/repo/SomeFile.txt`,
|
|
97
|
+
]));
|
|
76
98
|
}));
|
|
77
99
|
it('rejects and throws error when "getLocalChangedAndCreated" fails', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
100
|
//Given
|
package/lib/test/Git/Git.spec.js
CHANGED
|
@@ -11,11 +11,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
12
|
});
|
|
13
13
|
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
14
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
15
19
|
const Git_1 = require("../../src/Git/Git");
|
|
16
20
|
const RepoManager_1 = require("../FsUtils/RepoManager");
|
|
17
21
|
describe('Git', () => {
|
|
18
|
-
const
|
|
22
|
+
const dir = './test/repos';
|
|
23
|
+
const repoManager = RepoManager_1.RepoManager.getInstance(dir);
|
|
19
24
|
beforeEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
25
|
yield repoManager.init();
|
|
21
26
|
}));
|
|
@@ -23,10 +28,10 @@ describe('Git', () => {
|
|
|
23
28
|
yield repoManager.tearDown();
|
|
24
29
|
}));
|
|
25
30
|
describe('version check', () => {
|
|
26
|
-
it('does not fail when Git version is equal to 2.
|
|
31
|
+
it('does not fail when Git version is equal to 2.30.0', () => {
|
|
27
32
|
//Given/When
|
|
28
33
|
const mock = {
|
|
29
|
-
version: jest.fn().mockReturnValue({ major: 2, minor:
|
|
34
|
+
version: jest.fn().mockReturnValue({ major: 2, minor: 30, patch: 0 }),
|
|
30
35
|
};
|
|
31
36
|
expect(Git_1.Git.versionCheck(mock)).resolves;
|
|
32
37
|
});
|
|
@@ -36,7 +41,7 @@ describe('Git', () => {
|
|
|
36
41
|
version: jest.fn().mockReturnValue({ major: 1 }),
|
|
37
42
|
};
|
|
38
43
|
//Then
|
|
39
|
-
yield expect(Git_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.
|
|
44
|
+
yield expect(Git_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.30.0'));
|
|
40
45
|
}));
|
|
41
46
|
it('fails when Git minor version is lower', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
47
|
//Given/When
|
|
@@ -44,7 +49,7 @@ describe('Git', () => {
|
|
|
44
49
|
version: jest.fn().mockReturnValue({ major: 3, minor: 36 }),
|
|
45
50
|
};
|
|
46
51
|
//Then
|
|
47
|
-
yield expect(Git_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.
|
|
52
|
+
yield expect(Git_1.Git.versionCheck(mock)).rejects.toThrow(Error('Unsupported version of git. Min version must be 2.30.0'));
|
|
48
53
|
}));
|
|
49
54
|
it('fails when Git patch version is more than 0', () => {
|
|
50
55
|
//Given/When
|
|
@@ -55,6 +60,13 @@ describe('Git', () => {
|
|
|
55
60
|
expect(Git_1.Git.versionCheck(mock)).resolves;
|
|
56
61
|
});
|
|
57
62
|
});
|
|
63
|
+
describe('rev parse', () => {
|
|
64
|
+
it('get git root', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
|
+
const repoDirPath = path_1.default.resolve(repoManager.repoDir);
|
|
66
|
+
const revParse = yield new Git_1.Git(repoManager.repoDir).gitRoot();
|
|
67
|
+
expect(revParse).toBe(repoDirPath);
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
58
70
|
describe('branch operation', () => {
|
|
59
71
|
it('fails to find default branch name when head is not set', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
60
72
|
//Given/When/Then
|