From ba94982f4d42ad434dcdf91094b5d69d44e9fd88 Mon Sep 17 00:00:00 2001 From: Liviu Costea Date: Sun, 31 May 2020 18:07:17 +0300 Subject: examples: tag, Add create and push new tag --- _examples/README.md | 1 + _examples/tag-create-push/main.go | 168 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 _examples/tag-create-push/main.go (limited to '_examples') diff --git a/_examples/README.md b/_examples/README.md index 1d82fbd..80d4dd5 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -17,6 +17,7 @@ Here you can find a list of annotated _go-git_ examples: - [log](log/main.go) - Emulate `git log` command output iterating all the commit history from HEAD reference. - [branch](branch/main.go) - How to create and remove branches or any other kind of reference. - [tag](tag/main.go) - List/print repository tags. +- [tag create and push](tag-create-push/main.go) - Create and push a new tag. - [remotes](remotes/main.go) - Working with remotes: adding, removing, etc. - [progress](progress/main.go) - Printing the progress information from the sideband. - [revision](revision/main.go) - Solve a revision into a commit. diff --git a/_examples/tag-create-push/main.go b/_examples/tag-create-push/main.go new file mode 100644 index 0000000..11c76eb --- /dev/null +++ b/_examples/tag-create-push/main.go @@ -0,0 +1,168 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "time" + + "github.com/go-git/go-git/v5" + . "github.com/go-git/go-git/v5/_examples" + "github.com/go-git/go-git/v5/config" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/go-git/go-git/v5/plumbing/transport/ssh" +) + +func main() { + CheckArgs("", "", "", "", "", "") + url := os.Args[1] + directory := os.Args[2] + tag := os.Args[3] + name := os.Args[4] + email := os.Args[5] + key := os.Args[6] + + r, err := cloneRepo(url, directory, key) + + if err != nil { + log.Printf("clone repo error: %s", err) + return + } + + if tagExists(tag, r) { + log.Printf("Tag %s already exists, nothing to do here", tag) + return + } + + created, err := setTag(r, tag, defaultSignature(name, email)) + if err != nil { + log.Printf("create tag error: %s", err) + return + } + + if created { + err = pushTags(r, key) + if err != nil { + log.Printf("push tag error: %s", err) + return + } + } + +} + +func cloneRepo(url, dir, publicKeyPath string) (*git.Repository, error) { + + log.Printf("cloning %s into %s", url, dir) + auth, keyErr := publicKey(publicKeyPath) + if keyErr != nil { + return nil, keyErr + } + + r, err := git.PlainClone(dir, false, &git.CloneOptions{ + Progress: os.Stdout, + URL: url, + Auth: auth, + }) + + if err != nil { + if err == git.ErrRepositoryAlreadyExists { + log.Print("repo was already cloned") + } else { + log.Printf("clone git repo error: %s", err) + return nil, err + } + } + + return r, nil +} + +func publicKey(filePath string) (*ssh.PublicKeys, error) { + var publicKey *ssh.PublicKeys + sshKey, _ := ioutil.ReadFile(filePath) + publicKey, err := ssh.NewPublicKeys("git", []byte(sshKey), "") + if err != nil { + return nil, err + } + return publicKey, err +} + +func tagExists(tag string, r *git.Repository) bool { + tagFoundErr := "tag was found" + tags, err := r.TagObjects() + if err != nil { + log.Printf("get tags error: %s", err) + return false + } + res := false + err = tags.ForEach(func(t *object.Tag) error { + if t.Name == tag { + res = true + return fmt.Errorf(tagFoundErr) + } + return nil + }) + if err != nil && err.Error() != tagFoundErr { + log.Printf("iterate tags error: %s", err) + return false + } + return res +} + +func setTag(r *git.Repository, tag string, tagger *object.Signature) (bool, error) { + if tagExists(tag, r) { + log.Printf("tag %s already exists", tag) + return false, nil + } + log.Printf("Set tag %s", tag) + h, err := r.Head() + if err != nil { + log.Printf("get HEAD error: %s", err) + return false, err + } + + _, err = r.CreateTag(tag, h.Hash(), &git.CreateTagOptions{ + Tagger: tagger, + Message: tag, + }) + + if err != nil { + log.Printf("create tag error: %s", err) + return false, err + } + + return true, nil +} + +func pushTags(r *git.Repository, publicKeyPath string) error { + + auth, _ := publicKey(publicKeyPath) + + po := &git.PushOptions{ + RemoteName: "origin", + Progress: os.Stdout, + RefSpecs: []config.RefSpec{config.RefSpec("refs/tags/*:refs/tags/*")}, + Auth: auth, + } + + err := r.Push(po) + + if err != nil { + if err == git.NoErrAlreadyUpToDate { + log.Print("origin remote was up to date, no push done") + return nil + } + log.Printf("push to remote origin error: %s", err) + return err + } + + return nil +} + +func defaultSignature(name, email string) *object.Signature { + return &object.Signature{ + Name: name, + Email: email, + When: time.Now(), + } +} -- cgit From 1d4220f46090765a5ad929a419d4de38eee99099 Mon Sep 17 00:00:00 2001 From: Liviu Costea Date: Mon, 1 Jun 2020 14:42:50 +0300 Subject: examples, tag: Show git command --- _examples/tag-create-push/main.go | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to '_examples') diff --git a/_examples/tag-create-push/main.go b/_examples/tag-create-push/main.go index 11c76eb..0d216da 100644 --- a/_examples/tag-create-push/main.go +++ b/_examples/tag-create-push/main.go @@ -30,11 +30,6 @@ func main() { return } - if tagExists(tag, r) { - log.Printf("Tag %s already exists, nothing to do here", tag) - return - } - created, err := setTag(r, tag, defaultSignature(name, email)) if err != nil { log.Printf("create tag error: %s", err) @@ -59,6 +54,7 @@ func cloneRepo(url, dir, publicKeyPath string) (*git.Repository, error) { return nil, keyErr } + Info("git clone %s", url) r, err := git.PlainClone(dir, false, &git.CloneOptions{ Progress: os.Stdout, URL: url, @@ -66,12 +62,8 @@ func cloneRepo(url, dir, publicKeyPath string) (*git.Repository, error) { }) if err != nil { - if err == git.ErrRepositoryAlreadyExists { - log.Print("repo was already cloned") - } else { - log.Printf("clone git repo error: %s", err) - return nil, err - } + log.Printf("clone git repo error: %s", err) + return nil, err } return r, nil @@ -89,6 +81,7 @@ func publicKey(filePath string) (*ssh.PublicKeys, error) { func tagExists(tag string, r *git.Repository) bool { tagFoundErr := "tag was found" + Info("git show-ref --tag") tags, err := r.TagObjects() if err != nil { log.Printf("get tags error: %s", err) @@ -120,7 +113,7 @@ func setTag(r *git.Repository, tag string, tagger *object.Signature) (bool, erro log.Printf("get HEAD error: %s", err) return false, err } - + Info("git tag -a %s %s -m \"%s\"", tag, h.Hash(), tag) _, err = r.CreateTag(tag, h.Hash(), &git.CreateTagOptions{ Tagger: tagger, Message: tag, @@ -144,7 +137,7 @@ func pushTags(r *git.Repository, publicKeyPath string) error { RefSpecs: []config.RefSpec{config.RefSpec("refs/tags/*:refs/tags/*")}, Auth: auth, } - + Info("git push --tags") err := r.Push(po) if err != nil { -- cgit