-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgit.ts
123 lines (104 loc) · 2.9 KB
/
git.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import * as exec from '@actions/exec'
import {Settings} from './settings'
export class Git {
private settings: Settings
constructor(settings: Settings) {
this.settings = settings
}
async currentTag(): Promise<string> {
const res = await this.execGit(['tag', '--points-at=HEAD'])
if (!res.stdout.length) {
// No current tag exists
return ''
}
// In case there are multiple tags get the first valid version tag
if (this.settings.tagRegex) {
let foundTag = ''
res.stdout.forEach(tag => {
if (this.settings.tagRegex.test(tag)) {
foundTag = tag
return
}
})
// Return either matched tag or none
return foundTag
}
// Get the first tag we found if there's no tag regex
return res.stdout[0]
}
async previousTag(tag: string): Promise<string> {
const res = await this.execGit(['describe', '--tags', '--abbrev=0', `${tag}^`])
if (res.exitCode != 0) {
// No previous tag exists
return ''
}
if (this.settings.tagRegex) {
const foundTag = res.stdout[0]
if (!this.settings.tagRegex.test(foundTag)) {
// If previous tag doesn't match the regex keep searching back
return this.previousTag(foundTag)
}
}
// We either matched the regex or we didn't have one
return res.stdout[0]
}
async log(from: string, to: string): Promise<GitCommit[]> {
let args = ['log', '--pretty=oneline', '--abbrev-commit', '--no-decorate', '--no-color']
let refs = ''
if (from) {
refs = `${from}..`
}
if (to) {
refs = `${refs}${to}`
}
if (refs) {
args.push(refs)
}
const res = await this.execGit(args)
let commits: GitCommit[] = []
res.stdout.forEach(commit => {
const split = commit.split(' ')
const hash = split[0]
const message = split.slice(1).join(' ').trim()
if (this.settings.filterRegex && this.settings.filterRegex.test(message)) {
return
}
commits.push(new GitCommit(hash, message))
})
return commits
}
private async execGit(args: string[]): Promise<GitOutput> {
const env = {}
for (const key of Object.keys(process.env)) {
env[key] = process.env[key]
}
const result = new GitOutput()
const options = {
cwd: process.cwd(),
env,
ignoreReturnCode: true,
listeners: {
stdout: (data: Buffer) => {
const lines = data.toString().trim().split(/\r?\n/)
lines.forEach(line => {
result.stdout.push(line.trim())
})
}
}
}
result.exitCode = await exec.exec(`"${this.settings.gitPath}"`, args, options)
return result
}
}
class GitOutput {
stdout: string[] = []
exitCode = 0
}
export class GitCommit {
hash: string = ''
message: string = ''
constructor(hash: string, message: string) {
this.hash = hash
this.message = message
}
}