github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/repo/sync/http.go (about)

     1  package sync
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"net/http"
     9  
    10  	"github.com/ungtb10d/cli/v2/api"
    11  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
    12  )
    13  
    14  type commit struct {
    15  	Ref    string `json:"ref"`
    16  	NodeID string `json:"node_id"`
    17  	URL    string `json:"url"`
    18  	Object struct {
    19  		Type string `json:"type"`
    20  		SHA  string `json:"sha"`
    21  		URL  string `json:"url"`
    22  	} `json:"object"`
    23  }
    24  
    25  func latestCommit(client *api.Client, repo ghrepo.Interface, branch string) (commit, error) {
    26  	var response commit
    27  	path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), branch)
    28  	err := client.REST(repo.RepoHost(), "GET", path, nil, &response)
    29  	return response, err
    30  }
    31  
    32  type upstreamMergeErr struct{ error }
    33  
    34  var upstreamMergeUnavailableErr = upstreamMergeErr{errors.New("upstream merge API is unavailable")}
    35  
    36  func triggerUpstreamMerge(client *api.Client, repo ghrepo.Interface, branch string) (string, error) {
    37  	var payload bytes.Buffer
    38  	if err := json.NewEncoder(&payload).Encode(map[string]interface{}{
    39  		"branch": branch,
    40  	}); err != nil {
    41  		return "", err
    42  	}
    43  
    44  	var response struct {
    45  		Message    string `json:"message"`
    46  		MergeType  string `json:"merge_type"`
    47  		BaseBranch string `json:"base_branch"`
    48  	}
    49  	path := fmt.Sprintf("repos/%s/%s/merge-upstream", repo.RepoOwner(), repo.RepoName())
    50  	var httpErr api.HTTPError
    51  	if err := client.REST(repo.RepoHost(), "POST", path, &payload, &response); err != nil {
    52  		if errors.As(err, &httpErr) {
    53  			switch httpErr.StatusCode {
    54  			case http.StatusUnprocessableEntity, http.StatusConflict:
    55  				return "", upstreamMergeErr{errors.New(httpErr.Message)}
    56  			case http.StatusNotFound:
    57  				return "", upstreamMergeUnavailableErr
    58  			}
    59  		}
    60  		return "", err
    61  	}
    62  	return response.BaseBranch, nil
    63  }
    64  
    65  func syncFork(client *api.Client, repo ghrepo.Interface, branch, SHA string, force bool) error {
    66  	path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), branch)
    67  	body := map[string]interface{}{
    68  		"sha":   SHA,
    69  		"force": force,
    70  	}
    71  	requestByte, err := json.Marshal(body)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	requestBody := bytes.NewReader(requestByte)
    76  	return client.REST(repo.RepoHost(), "PATCH", path, requestBody, nil)
    77  }