From b5d7caac1873090629d4b870c0b3968f7537cdb2 Mon Sep 17 00:00:00 2001 From: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> Date: Sun, 11 Dec 2022 17:40:19 +0000 Subject: [PATCH] feat: adds tagging functionality Signed-off-by: ChrisJBurns <29541485+ChrisJBurns@users.noreply.github.com> --- .gitignore | 4 ++- internal/download/download.go | 61 ++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index c6eafba..be8a7be 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,6 @@ go.work create-cli # exclude the folders created by the download command -create-repositories \ No newline at end of file +create-repositories + +.DS_Store \ No newline at end of file diff --git a/internal/download/download.go b/internal/download/download.go index ae36ded..d9173d7 100644 --- a/internal/download/download.go +++ b/internal/download/download.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/spf13/viper" ) @@ -42,8 +43,10 @@ func ReturnRepoListWithCloudProviderTemplate(cloudProvider string) map[string]st } func Download() { + cloudProvider := viper.GetString("cloud-provider") personalAccessToken := viper.GetString("pat") + tag := "1.0.0.0" ReturnRepoListWithCloudProviderTemplate(cloudProvider) @@ -55,7 +58,7 @@ func Download() { for repoName, repoUrl := range ReposToClone { log.Printf("Cloning %s into %s", repoName, CreateRepositoryDirectory) - _, err := git.PlainClone(CreateRepositoryDirectory+repoName, false, &git.CloneOptions{ + r, err := git.PlainClone(CreateRepositoryDirectory+repoName, false, &git.CloneOptions{ // The intended use of a GitHub personal access token is in replace of your password // because access tokens can easily be revoked. // https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ @@ -66,10 +69,66 @@ func Download() { URL: repoUrl, Progress: os.Stdout, }) + if err != nil { + panic(err) + } + // get work tree for cloned repo + tree, err := r.Worktree() if err != nil { panic(err) } + + checkoutTag(tag, tree) + deletesMainBranch(r) + createAndCheckoutMainBranchOffTag(tag, r, tree) + } +} + +// checkoutTag checks out the passed tag +func checkoutTag(tag string, tree *git.Worktree) { + err := tree.Checkout(&git.CheckoutOptions{ + Branch: plumbing.ReferenceName("refs/tags/" + tag), + }) + if err != nil { + panic(err) } +} +// deletesMainBranch deletes the main branch because we want to create a new +// main branch off the specific tag. otherwise, the main branch will have the entire +// history of the repository which in this case we don't want. just the specific version +func deletesMainBranch(r *git.Repository) { + err := r.Storer.RemoveReference("refs/heads/main") + if err != nil { + panic(err) + } +} + +// createAndCheckpoutMainBranchOffTag will create and checkout a main branch off the commit hash reference +// of the tag that is passed in. this is to ensure that the main branch only has the code on the tag. +// otherwise, if you want the code on the 1.0.0.0 tag, without deleting and creating a new main +// branch off the tag, the main branch will have all of the latest code - which in this case is not +// what you want. +func createAndCheckoutMainBranchOffTag(tag string, r *git.Repository, tree *git.Worktree) { + // we get the commit reference that is at the tip of the tag + headRef, err := r.Reference(plumbing.ReferenceName("refs/tags/"+tag), false) + if err != nil { + panic(err) + } + + // we create a new branch called `main` off the commit hash from the tag + ref := plumbing.NewHashReference("refs/heads/main", headRef.Hash()) + err = r.Storer.SetReference(ref) + if err != nil { + panic(err) + } + + // we checkout the `main` branch just created. + err = tree.Checkout(&git.CheckoutOptions{ + Branch: plumbing.ReferenceName("refs/heads/main"), + }) + if err != nil { + panic(err) + } }