Skip to content

Commit

Permalink
improvement: better error when attempting to run outside of git repo
Browse files Browse the repository at this point in the history
Closes #1194
  • Loading branch information
edvald committed Sep 17, 2019
1 parent ce9a2fb commit 0a80077
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
21 changes: 20 additions & 1 deletion garden-service/src/vcs/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,32 @@ export class GitHandler extends VcsHandler {
}
}

async getRepoRoot(log: LogEntry, path: string) {
const git = this.gitCli(log, path)

try {
return (await git("rev-parse", "--show-toplevel"))[0]
} catch (err) {
if (err.exitCode === 128) {
// Throw nice error when we detect that we're not in a repo root
throw new RuntimeError(deline`
Path ${path} is not in a git repository root. Garden must be run from within a git repo.
Please run \`git init\` if you're starting a new project and repository, or move the project to an
existing repository, and try again.
`, { path })
} else {
throw err
}
}
}

/**
* Returns a list of files, along with file hashes, under the given path, taking into account the configured
* .ignore files, and the specified include/exclude filters.
*/
async getFiles({ log, path, include, exclude }: GetFilesParams): Promise<VcsFile[]> {
const git = this.gitCli(log, path)
const gitRoot = (await git("rev-parse", "--show-toplevel"))[0]
const gitRoot = await this.getRepoRoot(log, path)

// List modified files, so that we can ensure we have the right hash for them later
const modified = new Set((await this.getModifiedFiles(git, path))
Expand Down
1 change: 1 addition & 0 deletions garden-service/src/vcs/vcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export abstract class VcsHandler {
constructor(protected gardenDirPath: string, protected ignoreFiles: string[]) { }

abstract name: string
abstract async getRepoRoot(log: LogEntry, path: string): Promise<string>
abstract async getFiles(params: GetFilesParams): Promise<VcsFile[]>
abstract async ensureRemoteSource(params: RemoteSourceParams): Promise<string>
abstract async updateRemoteSource(params: RemoteSourceParams): Promise<void>
Expand Down
27 changes: 26 additions & 1 deletion garden-service/test/unit/src/vcs/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { getCommitIdFromRefList, parseGitUrl, GitHandler } from "../../../../src
import { fixedExcludes } from "../../../../src/util/fs"
import { LogEntry } from "../../../../src/logger/log-entry"
import { hashRepoUrl } from "../../../../src/util/ext-source-util"
import { deline } from "../../../../src/util/string"

// Overriding this to make sure any ignorefile name is respected
const defaultIgnoreFilename = ".testignore"
Expand Down Expand Up @@ -56,7 +57,7 @@ async function addToIgnore(tmpPath: string, pathToExclude: string, ignoreFilenam
describe("GitHandler", () => {
let tmpDir: tmp.DirectoryResult
let tmpPath: string
let git
let git: any
let handler: GitHandler
let log: LogEntry

Expand All @@ -74,6 +75,30 @@ describe("GitHandler", () => {
await tmpDir.cleanup()
})

describe("getRepoRoot", () => {
it("should return the repo root if it is the same as the given path", async () => {
const path = tmpPath
expect(await handler.getRepoRoot(log, path)).to.equal(tmpPath)
})

it("should return the nearest repo root, given a subpath of that repo", async () => {
const dirPath = join(tmpPath, "dir")
await mkdir(dirPath)
expect(await handler.getRepoRoot(log, dirPath)).to.equal(tmpPath)
})

it("should throw a nice error when given a path outside of a repo", async () => {
await expectError(
() => handler.getRepoRoot(log, "/tmp"),
(err) => expect(err.message).to.equal(deline`
Path /tmp is not in a git repository root. Garden must be run from within a git repo.
Please run \`git init\` if you're starting a new project and repository, or move the project to
an existing repository, and try again.
`),
)
})
})

describe("getFiles", () => {
it("should work with no commits in repo", async () => {
expect(await handler.getFiles({ path: tmpPath, log })).to.eql([])
Expand Down
4 changes: 4 additions & 0 deletions garden-service/test/unit/src/vcs/vcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class TestVcsHandler extends VcsHandler {
name = "test"
private testVersions: TreeVersions = {}

async getRepoRoot() {
return "/foo"
}

async getFiles() {
return []
}
Expand Down

0 comments on commit 0a80077

Please sign in to comment.