Reorganizing to improve test surface.

This commit is contained in:
Martin Strobel 2017-12-07 14:21:55 -08:00
Родитель fa0b8235f4
Коммит bc983ff9ff
4 изменённых файлов: 134 добавлений и 33 удалений

Просмотреть файл

@ -1,17 +1,14 @@
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path"
"github.com/marstr/randname"
"github.com/marstr/mirrorcat"
"github.com/mitchellh/go-homedir"
@ -29,6 +26,9 @@ func init() {
panic(err)
}
viper.SetConfigName(".mirrorcat")
viper.SetConfigType("yaml")
viper.SetEnvPrefix("MIRRORCAT")
viper.SetDefault("branches", []string{"master"})
@ -38,7 +38,10 @@ func init() {
if home, err := homedir.Dir(); err == nil {
viper.AddConfigPath(home)
}
viper.AutomaticEnv()
viper.ReadInConfig()
log.Println("Used Config File: ", viper.ConfigFileUsed())
}
func handlePushEvent(output http.ResponseWriter, req *http.Request) {
@ -74,34 +77,10 @@ func handlePushEvent(output http.ResponseWriter, req *http.Request) {
return
}
cloneLoc := path.Join(os.TempDir(), randname.Generate())
defer os.RemoveAll(cloneLoc)
log.Println("Clone Location: ", cloneLoc)
if err = exec.Command("git", "clone", viper.GetString("original"), cloneLoc).Run(); err != nil {
err = mirrorcat.Push(context.Background(), viper.GetString("original"), viper.GetString("mirror"), pushed.Ref)
if err != nil {
output.WriteHeader(http.StatusInternalServerError)
fmt.Println(output, "Unable to clone original")
log.Println(output, "failed to clone:\n", err.Error())
return
}
remoteAdder := exec.Command("git", "remote", "add", mirrorRemoteHandle, viper.GetString("mirror"))
remoteAdder.Dir = cloneLoc
if err = remoteAdder.Run(); err != nil {
output.WriteHeader(http.StatusInternalServerError)
fmt.Println(output, "Unable to assign mirror remote")
log.Println(output, "failed to assign mirror remote:\n", err.Error())
return
}
pusher := exec.Command("git", "push", mirrorRemoteHandle, mirrorcat.NormalizeRef(pushed.Ref))
pusher.Dir = cloneLoc
if err = pusher.Run(); err != nil {
output.WriteHeader(http.StatusInternalServerError)
fmt.Println(output, "Unable to push")
log.Println("Unable to push:\n", err.Error())
log.Println("Unable to complete push:\n ", err.Error())
return
}
@ -115,6 +94,7 @@ func main() {
log.Printf("Listening on port %d\n", viper.GetInt("port"))
log.Println("Original: ", viper.GetString("original"))
log.Println("Mirror: ", viper.GetString("mirror"))
if http.ListenAndServe(fmt.Sprintf(":%d", viper.GetInt("port")), nil) != nil {
return
}

72
push.go
Просмотреть файл

@ -1,6 +1,17 @@
package mirrorcat
import "strings"
import (
"bytes"
"context"
"fmt"
"log"
"os"
"os/exec"
"path"
"strings"
"github.com/marstr/randname"
)
// PushEvent encapsulates all data that will be provided by a GitHub Webhook PushEvent.
// Read more at: https://developer.github.com/v3/activity/events/types/#pushevent
@ -39,3 +50,62 @@ func NormalizeRef(ref string) string {
}
return ref
}
type CmdErr struct {
error
Output []byte
}
func (ce CmdErr) Error() string {
builder := &bytes.Buffer{}
fmt.Fprintln(builder, "Original Error: ", ce.error.Error())
fmt.Fprintln(builder, "Command Output:\n", string(ce.Output))
return builder.String()
}
// Push clones the original repository, then pushes the branch specified to another repository.
func Push(ctx context.Context, original, mirror, ref string) (err error) {
const mirrorRemoteHandle = "other"
cloneLoc := path.Join(os.TempDir(), randname.Generate())
defer os.RemoveAll(cloneLoc)
runCmd := func(cmd *exec.Cmd) (err error) {
output, err := cmd.CombinedOutput()
if err != nil {
err = CmdErr{
error: err,
Output: output,
}
}
return
}
normalized := NormalizeRef(ref)
if err = runCmd(exec.CommandContext(ctx, "git", "clone", original, cloneLoc)); err != nil {
return
}
checkouter := exec.CommandContext(ctx, "git", "checkout", normalized)
checkouter.Dir = cloneLoc
if err = runCmd(checkouter); err != nil {
return
}
remoteAdder := exec.CommandContext(ctx, "git", "remote", "add", mirrorRemoteHandle, mirror)
remoteAdder.Dir = cloneLoc
if err = runCmd(remoteAdder); err != nil {
return
}
log.Println("Pushing ", mirrorRemoteHandle, normalized)
pusher := exec.CommandContext(ctx, "git", "push", mirrorRemoteHandle, normalized)
pusher.Dir = cloneLoc
err = runCmd(pusher)
return
}

Просмотреть файл

@ -1,10 +1,16 @@
package mirrorcat_test
import (
"context"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"testing"
"github.com/marstr/mirrorcat"
"github.com/marstr/randname"
)
func ExampleNormalizeRef() {
@ -35,3 +41,48 @@ func TestNormalizeRef(t *testing.T) {
})
}
}
func TestPush(t *testing.T) {
var err error
locPrefix := path.Join(os.TempDir(), "test_push")
originalLoc, mirrorLoc := path.Join(locPrefix, randname.Generate()), path.Join(locPrefix, randname.Generate())
t.Log("Original Repo Location: \t", originalLoc)
t.Log("Mirror Repo Location: \t", mirrorLoc)
runCmd := func(cmd *exec.Cmd) {
err = cmd.Run()
if err != nil {
output, _ := cmd.CombinedOutput()
t.Log(output)
t.Error(err)
t.FailNow()
}
}
runCmd(exec.Command("git", "init", originalLoc))
defer os.RemoveAll(originalLoc)
runCmd(exec.Command("git", "init", "--bare", mirrorLoc))
defer os.RemoveAll(mirrorLoc)
err = ioutil.WriteFile(path.Join(originalLoc, "content.txt"), []byte("Hello World!!!"), os.ModePerm)
if err != nil {
t.Error(err)
return
}
adder := exec.Command("git", "add", "--all")
adder.Dir = originalLoc
runCmd(adder)
commiter := exec.Command("git", "commit", "-m", `"This is only a test."`)
commiter.Dir = originalLoc
runCmd(commiter)
err = mirrorcat.Push(context.Background(), originalLoc, mirrorLoc, "master")
if err != nil {
t.Error(err)
return
}
}

2
testdata/examplePush.json поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
{
"ref": "refs/heads/master",
"ref": "refs/heads/current",
"before": "9049f1265b7d61be4a8904a9a27120d2064dab3b",
"after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
"created": false,