From 6b1fdbecc4b5344c26793489a850c867102fd29d Mon Sep 17 00:00:00 2001 From: Michael Brewer Date: Sun, 31 Mar 2024 18:23:38 -0700 Subject: [PATCH] feat(git-clone): add support for tree git clone url --- git-clone/main.test.ts | 65 ++++++++++++++++++++++++++++++++++++++++++ git-clone/main.tf | 19 ++++++++++-- git-clone/run.sh | 15 ++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/git-clone/main.test.ts b/git-clone/main.test.ts index 0c3dd54..a23aa8a 100644 --- a/git-clone/main.test.ts +++ b/git-clone/main.test.ts @@ -14,6 +14,71 @@ describe("git-clone", async () => { url: "foo", }); + it("repo_dir should match repo name for https", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + base_dir: "/tmp", + url: "https://github.com/coder/coder.git", + }); + expect(state.outputs.repo_dir.value).toEqual("/tmp/coder"); + expect(state.outputs.clone_url.value).toEqual( + "https://github.com/coder/coder.git", + ); + expect(state.outputs.branch_name.value).toEqual(""); + }); + + it("repo_dir should match repo name for https without .git", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + base_dir: "/tmp", + url: "https://github.com/coder/coder", + }); + expect(state.outputs.repo_dir.value).toEqual("/tmp/coder"); + expect(state.outputs.clone_url.value).toEqual( + "https://github.com/coder/coder", + ); + expect(state.outputs.branch_name.value).toEqual(""); + }); + + it("repo_dir should match repo name for ssh", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + base_dir: "/tmp", + url: "git@github.com:coder/coder.git", + }); + expect(state.outputs.repo_dir.value).toEqual("/tmp/coder"); + expect(state.outputs.clone_url.value).toEqual( + "git@github.com:coder/coder.git", + ); + expect(state.outputs.branch_name.value).toEqual(""); + }); + + it("repo_dir should match repo name with gitlab tree url", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + base_dir: "/tmp", + url: "https://gitlab.com/mike.brew/repo-tests.log/-/tree/feat/branch", + }); + expect(state.outputs.repo_dir.value).toEqual("/tmp/repo-tests.log"); + expect(state.outputs.clone_url.value).toEqual( + "https://gitlab.com/mike.brew/repo-tests.log", + ); + expect(state.outputs.branch_name.value).toEqual("feat/branch"); + }); + + it("repo_dir should match repo name with github tree url", async () => { + const state = await runTerraformApply(import.meta.dir, { + agent_id: "foo", + base_dir: "/tmp", + url: "https://github.com/michaelbrewer/repo-tests.log/tree/feat/branch", + }); + expect(state.outputs.repo_dir.value).toEqual("/tmp/repo-tests.log"); + expect(state.outputs.clone_url.value).toEqual( + "https://github.com/michaelbrewer/repo-tests.log", + ); + expect(state.outputs.branch_name.value).toEqual("feat/branch"); + }); + it("fails without git", async () => { const state = await runTerraformApply(import.meta.dir, { agent_id: "foo", diff --git a/git-clone/main.tf b/git-clone/main.tf index c1e65cf..22a44c9 100644 --- a/git-clone/main.tf +++ b/git-clone/main.tf @@ -26,7 +26,9 @@ variable "agent_id" { } locals { - clone_path = var.base_dir != "" ? join("/", [var.base_dir, replace(basename(var.url), ".git", "")]) : join("/", ["~", replace(basename(var.url), ".git", "")]) + clone_url = replace(replace(var.url, "//-/tree/.*/", ""), "//tree/.*/", "") + branch_name = replace(replace(replace(var.url, local.clone_url, ""), "/.*/-/tree//", ""), "/.*/tree//", "") + clone_path = var.base_dir != "" ? join("/", [var.base_dir, replace(basename(local.clone_url), ".git", "")]) : join("/", ["~", replace(basename(local.clone_url), ".git", "")]) } output "repo_dir" { @@ -34,11 +36,22 @@ output "repo_dir" { description = "Full path of cloned repo directory" } +output "clone_url" { + value = local.clone_url + description = "Git repository URL" +} + +output "branch_name" { + value = local.branch_name + description = "Git branch" +} + resource "coder_script" "git_clone" { agent_id = var.agent_id script = templatefile("${path.module}/run.sh", { - CLONE_PATH = local.clone_path - REPO_URL : var.url, + CLONE_PATH = local.clone_path, + REPO_URL : local.clone_url, + BRANCH_NAME : local.branch_name, }) display_name = "Git Clone" icon = "/icon/git.svg" diff --git a/git-clone/run.sh b/git-clone/run.sh index df647a1..5a8ac24 100755 --- a/git-clone/run.sh +++ b/git-clone/run.sh @@ -2,6 +2,7 @@ REPO_URL="${REPO_URL}" CLONE_PATH="${CLONE_PATH}" +BRANCH_NAME="${BRANCH_NAME}" # Expand home if it's specified! CLONE_PATH="$${CLONE_PATH/#\~/$${HOME}}" @@ -35,6 +36,20 @@ fi if [ -z "$(ls -A "$CLONE_PATH")" ]; then echo "Cloning $REPO_URL to $CLONE_PATH..." git clone "$REPO_URL" "$CLONE_PATH" + + # Return the exit code of the last command + exit_code=$? + if [ $exit_code -ne 0 ]; then + exit $exit_code + fi + + # If BRANCH_NAME is set of a non-blank value, switch to that branch + if [ -n "$BRANCH_NAME" ]; then + echo "Switch to branch $BRANCH_NAME..." + cd "$CLONE_PATH" || exit 1 + git switch "$BRANCH_NAME" + cd - || exit 1 + fi else echo "$CLONE_PATH already exists and isn't empty, skipping clone!" exit 0