diff --git a/cmd/cli/root.go b/cmd/cli/root.go index 9d5356a..68e7296 100644 --- a/cmd/cli/root.go +++ b/cmd/cli/root.go @@ -57,7 +57,7 @@ func (o *option) runE(cmd *cobra.Command, args []string) (err error) { if resp.StatusCode == http.StatusOK { // Create the file - out, err := os.Create(binaryName) + out, err := os.OpenFile(binaryName, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0544) if err != nil { return err } diff --git a/cmd/server/root.go b/cmd/server/root.go index 52c3c1d..47752e4 100644 --- a/cmd/server/root.go +++ b/cmd/server/root.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/spf13/cobra" "io" "io/ioutil" @@ -34,6 +35,7 @@ func createServerCommand() (cmd *cobra.Command) { requestPath := strings.Split(r.RequestURI, "?")[0] dir := path.Join("tmp", strings.ReplaceAll(requestPath, "/github.com", "")) gitRepo := fmt.Sprintf("https:/%s", requestPath) + branch := getBranch(r.URL) if ok, _ := PathExists(dir); ok { var repo *git.Repository @@ -43,21 +45,30 @@ func createServerCommand() (cmd *cobra.Command) { if wd, err = repo.Worktree(); err == nil { if err = wd.Pull(&git.PullOptions{ Progress: cmd.OutOrStdout(), + ReferenceName: plumbing.NewBranchReferenceName(branch), Force: true, }); err != nil && err != git.NoErrAlreadyUpToDate { err = fmt.Errorf("failed to pull git repository '%s', error: %v", repo, err) - return + } else { + err = nil } - err = nil } } else { err = fmt.Errorf("failed to open git local repository, error: %v", err) } - } else if _, err = git.PlainClone(dir, false, &git.CloneOptions{ - URL: gitRepo, - Progress: cmd.OutOrStdout(), - }); err != nil { - fmt.Println(err) + } else { + _, err = git.PlainClone(dir, false, &git.CloneOptions{ + URL: gitRepo, + ReferenceName: plumbing.NewBranchReferenceName(branch), + Progress: cmd.OutOrStdout(), + }) + } + + if err == nil { + fmt.Println("get the desired git repository", gitRepo) + } else { + w.WriteHeader(http.StatusBadRequest) + fmt.Println(err.Error()) return } @@ -74,20 +85,28 @@ func createServerCommand() (cmd *cobra.Command) { env = append(env, "GOOS=darwin") } + fmt.Println("start to build", binaryName) if err := RunCommandInDir("go", dir, env, args...); err == nil { fmt.Println("success", binaryName) - - w.Header().Set("Content-Type", "application/octet-stream") - w.Header().Set("Content-Disposition", fmt.Sprintf("attachment;filename=%s", binaryName)) - w.Header().Set("Content-Transfer-Encoding", "binary") - w.Header().Set("Expires", "0") - w.WriteHeader(http.StatusOK) - - if data, err := ioutil.ReadFile(path.Join(dir, binaryName)); err == nil { - _, _ = w.Write(data) - return + binaryFilePath := path.Join(dir, binaryName) + + if binaryFileInfo, err := os.Stat(binaryFilePath); err == nil { + w.Header().Set("Content-Length", fmt.Sprintf("%d", binaryFileInfo.Size())) + w.Header().Set("Content-Type", "application/octet-stream") + w.Header().Set("Content-Disposition", fmt.Sprintf("attachment;filename=%s", binaryName)) + w.Header().Set("Content-Transfer-Encoding", "binary") + w.Header().Set("Expires", "0") + w.WriteHeader(http.StatusOK) + + if data, err := ioutil.ReadFile(binaryFilePath); err == nil { + _, _ = w.Write(data) + return + } + } else { + fmt.Println("cannot get info of file", binaryName) } } else { + fmt.Printf("failed to build, error: %v\n", err) _, _ = w.Write([]byte(err.Error())) } w.WriteHeader(http.StatusBadRequest) @@ -99,6 +118,13 @@ func createServerCommand() (cmd *cobra.Command) { return } +func getBranch(httpURL *url.URL) (branch string) { + if branch = httpURL.Query().Get("branch"); branch == "" { + branch = "master" + } + return +} + func pairFromQuery(httpURL *url.URL, key, pairKey string) string { if val := httpURL.Query().Get(key); val != "" { return pair(pairKey, val) diff --git a/cmd/server/root_test.go b/cmd/server/root_test.go new file mode 100644 index 0000000..7dcaab6 --- /dev/null +++ b/cmd/server/root_test.go @@ -0,0 +1,64 @@ +package main + +import ( + "net/url" + "testing" +) + +func Test_getBranch(t *testing.T) { + type args struct { + httpURL *url.URL + } + tests := []struct { + name string + args args + wantBranch string + }{{ + name: "no query", + args: args{ + httpURL: &url.URL{}, + }, + wantBranch: "master", + }, { + name: "with valid branch", + args: args{ + httpURL: &url.URL{ + RawQuery: "branch=test", + }, + }, + wantBranch: "test", + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotBranch := getBranch(tt.args.httpURL); gotBranch != tt.wantBranch { + t.Errorf("getBranch() = %v, want %v", gotBranch, tt.wantBranch) + } + }) + } +} + +func Test_pair(t *testing.T) { + type args struct { + key string + value string + } + tests := []struct { + name string + args args + want string + }{{ + name: "valid", + args: args{ + key: "key", + value: "value", + }, + want: "key=value", + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := pair(tt.args.key, tt.args.value); got != tt.want { + t.Errorf("pair() = %v, want %v", got, tt.want) + } + }) + } +}