зеркало из https://github.com/Azure/mirrorcat.git
Reorganizing to improve test surface.
This commit is contained in:
Родитель
fa0b8235f4
Коммит
bc983ff9ff
|
@ -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
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
|
||||
}
|
||||
|
|
51
push_test.go
51
push_test.go
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"ref": "refs/heads/master",
|
||||
"ref": "refs/heads/current",
|
||||
"before": "9049f1265b7d61be4a8904a9a27120d2064dab3b",
|
||||
"after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c",
|
||||
"created": false,
|
||||
|
|
Загрузка…
Ссылка в новой задаче