Skip to content

Commit a27fbf4

Browse files
authored
refactor(git): extract some helper functions (#5902)
* refactor: extract helper function to get the latest commit hash * refactor: simplify type of `GitCli`'s args * refactor: remove unnecessary Git args filtering * chore: document error-throwing of `GitCli` * refactor: inline unnecessary local variable * refactor: remove some code smells * Optimize imports * Inline unnecessary local variables * Avoid implicit `any` type * chore: explicit return type * refactor(git): extract some git commands as named functions
1 parent 8148447 commit a27fbf4

File tree

2 files changed

+39
-22
lines changed

2 files changed

+39
-22
lines changed

core/src/vcs/git.ts

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import { performance } from "perf_hooks"
1010
import { isAbsolute, join, normalize, posix, relative, resolve } from "path"
11-
import { isString } from "lodash-es"
1211
import fsExtra from "fs-extra"
1312
import { PassThrough } from "stream"
1413
import type {
@@ -67,21 +66,23 @@ export function parseGitUrl(url: string) {
6766
(e.g. https://github.com/org/repo.git#main). Actually got: '${url}'`,
6867
})
6968
}
70-
const parsed = { repositoryUrl: parts[0], hash: parts[1] }
71-
return parsed
69+
return { repositoryUrl: parts[0], hash: parts[1] }
7270
}
7371

7472
export interface GitCli {
75-
(...args: (string | undefined)[]): Promise<string[]>
73+
/**
74+
* @throws ChildProcessError
75+
*/
76+
(...args: string[]): Promise<string[]>
7677
}
7778

7879
export function gitCli(log: Log, cwd: string, failOnPrompt = false): GitCli {
7980
/**
8081
* @throws ChildProcessError
8182
*/
82-
return async (...args: (string | undefined)[]) => {
83+
return async (...args: string[]) => {
8384
log.silly(`Calling git with args '${args.join(" ")}' in ${cwd}`)
84-
const { stdout } = await exec("git", args.filter(isString), {
85+
const { stdout } = await exec("git", args, {
8586
cwd,
8687
maxBuffer: 10 * 1024 * 1024,
8788
env: failOnPrompt ? { GIT_TERMINAL_PROMPT: "0", GIT_ASKPASS: "true" } : undefined,
@@ -90,7 +91,7 @@ export function gitCli(log: Log, cwd: string, failOnPrompt = false): GitCli {
9091
}
9192
}
9293

93-
async function getModifiedFiles(git: GitCli, path: string) {
94+
export async function getModifiedFiles(git: GitCli, path: string): Promise<string[]> {
9495
try {
9596
return await git("diff-index", "--name-only", "HEAD", path)
9697
} catch (err) {
@@ -103,6 +104,26 @@ async function getModifiedFiles(git: GitCli, path: string) {
103104
}
104105
}
105106

107+
export async function getLastCommitHash(git: GitCli): Promise<string> {
108+
const result = await git("rev-parse", "HEAD")
109+
return result[0]
110+
}
111+
112+
export async function getRepositoryRoot(git: GitCli): Promise<string> {
113+
const result = await git("rev-parse", "--show-toplevel")
114+
return result[0]
115+
}
116+
117+
export async function getBranchName(git: GitCli): Promise<string> {
118+
const result = await git("rev-parse", "--abbrev-ref", "HEAD")
119+
return result[0]
120+
}
121+
122+
export async function getOriginUrl(git: GitCli): Promise<string> {
123+
const result = await git("config", "--get", "remote.origin.url")
124+
return result[0]
125+
}
126+
106127
interface GitSubTreeIncludeExcludeFiles extends BaseIncludeExcludeFiles {
107128
hasIncludes: boolean
108129
}
@@ -170,7 +191,7 @@ export class GitHandler extends VcsHandler {
170191

171192
try {
172193
const git = gitCli(log, path, failOnPrompt)
173-
const repoRoot = (await git("rev-parse", "--show-toplevel"))[0]
194+
const repoRoot = await getRepositoryRoot(git)
174195
this.repoRoots.set(path, repoRoot)
175196
return repoRoot
176197
} catch (err) {
@@ -572,7 +593,7 @@ export class GitHandler extends VcsHandler {
572593
const gitLog = log.createLog({ name, showDuration: true }).info("Getting remote state")
573594
await git("remote", "update")
574595

575-
const localCommitId = (await git("rev-parse", "HEAD"))[0]
596+
const localCommitId = await getLastCommitHash(git)
576597
const remoteCommitId = isSha1(hash) ? hash : getCommitIdFromRefList(await git("ls-remote", repositoryUrl, hash))
577598

578599
if (localCommitId !== remoteCommitId) {
@@ -679,16 +700,16 @@ export class GitHandler extends VcsHandler {
679700
}
680701

681702
try {
682-
output.branch = (await git("rev-parse", "--abbrev-ref", "HEAD"))[0]
683-
output.commitHash = (await git("rev-parse", "HEAD"))[0]
703+
output.branch = await getBranchName(git)
704+
output.commitHash = await getLastCommitHash(git)
684705
} catch (err) {
685706
if (err instanceof ChildProcessError && err.details.code !== 128) {
686707
throw err
687708
}
688709
}
689710

690711
try {
691-
output.originUrl = (await git("config", "--get", "remote.origin.url"))[0]
712+
output.originUrl = await getOriginUrl(git)
692713
} catch (err) {
693714
// Just ignore if not available
694715
log.silly(`Tried to retrieve git remote.origin.url but encountered an error: ${err}`)

core/test/unit/src/vcs/git.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import { basename, dirname, join, relative, resolve } from "path"
1515
import type { TestGarden } from "../../../helpers.js"
1616
import { expectError, getDataDir, makeTestGarden, makeTestGardenA } from "../../../helpers.js"
1717
import type { GitCli } from "../../../../src/vcs/git.js"
18-
import { gitCli } from "../../../../src/vcs/git.js"
19-
import { explainGitError, getCommitIdFromRefList, GitHandler, parseGitUrl } from "../../../../src/vcs/git.js"
18+
import { explainGitError, getCommitIdFromRefList, gitCli, GitHandler, parseGitUrl } from "../../../../src/vcs/git.js"
2019
import type { Log } from "../../../../src/logger/log-entry.js"
2120
import { hashRepoUrl } from "../../../../src/util/ext-source-util.js"
2221
import { dedent, deline } from "../../../../src/util/string.js"
@@ -147,8 +146,8 @@ const commonGitHandlerTests = (gitScanMode: GitScanMode) => {
147146
})
148147

149148
const dirContexts = [
150-
{ ctx: "when called from repo root", pathFn: (tp) => tp },
151-
{ ctx: "when called from project root", pathFn: (tp) => resolve(tp, "somedir") },
149+
{ ctx: "when called from repo root", pathFn: (tp: string): string => tp },
150+
{ ctx: "when called from project root", pathFn: (tp: string): string => resolve(tp, "somedir") },
152151
]
153152

154153
for (const { ctx, pathFn } of dirContexts) {
@@ -1117,8 +1116,7 @@ const commonGitHandlerTests = (gitScanMode: GitScanMode) => {
11171116

11181117
describe("getRepoRoot", () => {
11191118
it("should return the repo root if it is the same as the given path", async () => {
1120-
const path = tmpPath
1121-
expect(await handler.getRepoRoot(log, path)).to.equal(tmpPath)
1119+
expect(await handler.getRepoRoot(log, tmpPath)).to.equal(tmpPath)
11221120
})
11231121

11241122
it("should return the nearest repo root, given a subpath of that repo", async () => {
@@ -1142,8 +1140,7 @@ const commonGitHandlerTests = (gitScanMode: GitScanMode) => {
11421140

11431141
describe("getPathInfo", () => {
11441142
it("should return empty strings with no commits in repo", async () => {
1145-
const path = tmpPath
1146-
const { branch, commitHash } = await handler.getPathInfo(log, path)
1143+
const { branch, commitHash } = await handler.getPathInfo(log, tmpPath)
11471144
expect(branch).to.equal("")
11481145
expect(commitHash).to.equal("")
11491146
})
@@ -1156,8 +1153,7 @@ const commonGitHandlerTests = (gitScanMode: GitScanMode) => {
11561153
})
11571154

11581155
it("should return empty strings when given a path outside of a repo", async () => {
1159-
const path = tmpPath
1160-
const { branch, commitHash, originUrl } = await handler.getPathInfo(log, path)
1156+
const { branch, commitHash, originUrl } = await handler.getPathInfo(log, tmpPath)
11611157
expect(branch).to.equal("")
11621158
expect(commitHash).to.equal("")
11631159
expect(originUrl).to.equal("")

0 commit comments

Comments
 (0)