Skip to content

Commit deba9b3

Browse files
committed
parse commits with tests
Signed-off-by: shmck <[email protected]>
1 parent 692cb66 commit deba9b3

File tree

2 files changed

+178
-20
lines changed

2 files changed

+178
-20
lines changed

src/utils/commits.ts

+27-20
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,52 @@ type GetCommitOptions = {
1616

1717
export type CommitLogObject = { [position: string]: string[] };
1818

19-
export function parseCommits(logs: ListLogSummary<any>) {
19+
20+
21+
export function parseCommits(logs: ListLogSummary<any>): { [hash: string]: string[]} {
2022
// Filter relevant logs
2123
const commits: CommitLogObject = {};
2224
const positions: string[] = [];
2325

2426
for (const commit of logs.all) {
2527
const matches = commit.message.match(
26-
/^(?<stepId>(?<levelId>L?\d+)([S|\.]\d+))(?<stepType>[Q|A|T|S])?/
28+
/^(?<init>INIT)|(L?(?<levelId>\d+)[S|\.]?(?<stepId>\d+)?(?<stepType>[Q|A|T|S])?)/
2729
);
2830

2931
if (matches && matches.length) {
3032
// Use an object of commit arrays to collect all commits
31-
const position = matches[0];
32-
if (!commits[position]) {
33-
// does not exist, create the list
34-
commits[position] = [commit.hash];
33+
const { groups } = matches
34+
let position
35+
if (groups.init) {
36+
position = 'INIT'
37+
} else if (groups.levelId && groups.stepId) {
38+
let stepType
39+
// @deprecated Q
40+
if (!groups.stepType || ['Q', 'T'].includes(groups.stepType)) {
41+
stepType = 'T' // test
42+
// @deprecated A
43+
} else if (!groups.stepType || ['A', 'S'].includes(groups.stepType)) {
44+
stepType = 'S' // solution
45+
}
46+
position = `${groups.levelId}.${groups.stepId}:${stepType}`
47+
} else if (groups.levelId) {
48+
position = groups.levelId
3549
} else {
36-
// add to the list
37-
commits[position].unshift(commit.hash);
50+
console.warn(`No matcher for commit "${commit.message}"`)
3851
}
52+
commits[position] = [...(commits[position] || []), commit.hash]
3953
positions.unshift(position);
4054
} else {
4155
const initMatches = commit.message.match(/^INIT/);
4256
if (initMatches && initMatches.length) {
43-
if (!commits.INIT) {
44-
// does not exist, create the list
45-
commits.INIT = [commit.hash];
46-
} else {
47-
// add to the list
48-
commits.INIT.unshift(commit.hash);
49-
}
57+
commits.INIT = [...(commits.INIT || []), commit.hash]
5058
positions.unshift("INIT");
5159
}
5260
}
5361
}
54-
return { commits, positions };
62+
// validate order
63+
validateCommitOrder(positions);
64+
return commits;
5565
}
5666

5767
export async function getCommits({
@@ -95,10 +105,7 @@ export async function getCommits({
95105
// Load all logs
96106
const logs = await git.log();
97107

98-
const { commits, positions } = parseCommits(logs);
99-
100-
// validate order
101-
validateCommitOrder(positions);
108+
const commits = parseCommits(logs);
102109

103110
return commits;
104111
} catch (e) {

tests/commitParse.test.ts

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { parseCommits } from "../src/utils/commits";
2+
3+
describe("commitParse", () => {
4+
it("should parse out #. commits", () => {
5+
const logs = {
6+
all: [
7+
{
8+
message: "INIT",
9+
hash: "1",
10+
},
11+
{
12+
message: "1. First Level",
13+
hash: "2",
14+
},
15+
{
16+
message: "1.1 First Step",
17+
hash: "3",
18+
},
19+
],
20+
total: 2,
21+
latest: {},
22+
};
23+
const commits = parseCommits(logs);
24+
expect(commits).toEqual({
25+
INIT: ["1"],
26+
"1": ["2"],
27+
"1.1:T": ["3"],
28+
});
29+
});
30+
// @deprecated - remove L#
31+
it("should parse out L# commits", () => {
32+
const logs = {
33+
all: [
34+
{
35+
message: "INIT",
36+
hash: "1",
37+
},
38+
{
39+
message: "L1 First Level",
40+
hash: "2",
41+
},
42+
{
43+
message: "L1S1 First Step",
44+
hash: "3",
45+
},
46+
],
47+
total: 2,
48+
latest: {},
49+
};
50+
const commits = parseCommits(logs);
51+
expect(commits).toEqual({
52+
INIT: ["1"],
53+
"1": ["2"],
54+
"1.1:T": ["3"],
55+
});
56+
});
57+
// @deprecated - remove with QA
58+
it("should parse out #.Q|A commits", () => {
59+
const logs = {
60+
all: [
61+
{
62+
message: "INIT",
63+
hash: "1",
64+
},
65+
{
66+
message: "1. First Level",
67+
hash: "2",
68+
},
69+
{
70+
message: "1.1Q First Step",
71+
hash: "3",
72+
},
73+
{
74+
message: "1.1A First Step Solution",
75+
hash: "4",
76+
},
77+
],
78+
total: 2,
79+
latest: {},
80+
};
81+
const commits = parseCommits(logs);
82+
expect(commits).toEqual({
83+
INIT: ["1"],
84+
"1": ["2"],
85+
"1.1:T": ["3"],
86+
"1.1:S": ["4"],
87+
});
88+
});
89+
it("should parse out #.T|S commits", () => {
90+
const logs = {
91+
all: [
92+
{
93+
message: "INIT",
94+
hash: "1",
95+
},
96+
{
97+
message: "1. First Level",
98+
hash: "2",
99+
},
100+
{
101+
message: "1.1T First Step",
102+
hash: "3",
103+
},
104+
{
105+
message: "1.1S First Step Solution",
106+
hash: "4",
107+
},
108+
],
109+
total: 2,
110+
latest: {},
111+
};
112+
const commits = parseCommits(logs);
113+
expect(commits).toEqual({
114+
INIT: ["1"],
115+
"1": ["2"],
116+
"1.1:T": ["3"],
117+
"1.1:S": ["4"],
118+
});
119+
});
120+
it("should parse out #._|S commits", () => {
121+
const logs = {
122+
all: [
123+
{
124+
message: "INIT",
125+
hash: "1",
126+
},
127+
{
128+
message: "1. First Level",
129+
hash: "2",
130+
},
131+
{
132+
message: "1.1 First Step",
133+
hash: "3",
134+
},
135+
{
136+
message: "1.1S First Step Solution",
137+
hash: "4",
138+
},
139+
],
140+
total: 2,
141+
latest: {},
142+
};
143+
const commits = parseCommits(logs);
144+
expect(commits).toEqual({
145+
INIT: ["1"],
146+
"1": ["2"],
147+
"1.1:T": ["3"],
148+
"1.1:S": ["4"],
149+
});
150+
});
151+
});

0 commit comments

Comments
 (0)