You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
6.0 KiB
Go
214 lines
6.0 KiB
Go
// Copyright 2017 Drone.IO Inc. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package azure
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
|
|
"git.awesome-for.me/liuzhiguo/go-scm/scm"
|
|
)
|
|
|
|
type contentService struct {
|
|
client *wrapper
|
|
}
|
|
|
|
func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) {
|
|
// https://docs.microsoft.com/en-us/rest/api/azure/devops/git/items/get?view=azure-devops-rest-6.0
|
|
if s.client.project == "" {
|
|
return nil, nil, ProjectRequiredError()
|
|
}
|
|
endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?path=%s&includeContent=true&$format=json", s.client.owner, s.client.project, repo, path)
|
|
endpoint += generateURIFromRef(ref)
|
|
endpoint += "&api-version=6.0"
|
|
out := new(content)
|
|
res, err := s.client.do(ctx, "GET", endpoint, nil, out)
|
|
data := []byte(out.Content)
|
|
return &scm.Content{
|
|
Path: out.Path,
|
|
Data: data,
|
|
Sha: out.CommitID,
|
|
BlobID: out.ObjectID,
|
|
}, res, err
|
|
}
|
|
|
|
func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
|
|
if s.client.project == "" {
|
|
return nil, ProjectRequiredError()
|
|
}
|
|
endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo)
|
|
ref := refUpdate{
|
|
Name: SanitizeBranchName(params.Branch),
|
|
OldObjectID: params.Ref,
|
|
}
|
|
cha := change{
|
|
ChangeType: "add",
|
|
}
|
|
cha.Item.Path = path
|
|
cha.NewContent.Content = base64.StdEncoding.EncodeToString(params.Data)
|
|
cha.NewContent.ContentType = "base64encoded"
|
|
|
|
com := commit{
|
|
Comment: params.Message,
|
|
Changes: []change{cha},
|
|
}
|
|
in := &contentCreateUpdate{
|
|
RefUpdates: []refUpdate{ref},
|
|
Commits: []commit{com},
|
|
}
|
|
|
|
res, err := s.client.do(ctx, "POST", endpoint, in, nil)
|
|
return res, err
|
|
}
|
|
|
|
func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
|
|
if s.client.project == "" {
|
|
return nil, ProjectRequiredError()
|
|
}
|
|
endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo)
|
|
ref := refUpdate{
|
|
Name: SanitizeBranchName(params.Branch),
|
|
OldObjectID: params.Sha,
|
|
}
|
|
cha := change{
|
|
ChangeType: "edit",
|
|
}
|
|
cha.Item.Path = path
|
|
cha.NewContent.Content = base64.StdEncoding.EncodeToString(params.Data)
|
|
cha.NewContent.ContentType = "base64encoded"
|
|
|
|
com := commit{
|
|
Comment: params.Message,
|
|
Changes: []change{cha},
|
|
}
|
|
in := &contentCreateUpdate{
|
|
RefUpdates: []refUpdate{ref},
|
|
Commits: []commit{com},
|
|
}
|
|
|
|
res, err := s.client.do(ctx, "POST", endpoint, in, nil)
|
|
return res, err
|
|
}
|
|
|
|
func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) {
|
|
if s.client.project == "" {
|
|
return nil, ProjectRequiredError()
|
|
}
|
|
endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/pushes?api-version=6.0", s.client.owner, s.client.project, repo)
|
|
ref := refUpdate{
|
|
Name: SanitizeBranchName(params.Branch),
|
|
OldObjectID: params.Sha,
|
|
}
|
|
change1 := change{
|
|
ChangeType: "delete",
|
|
}
|
|
change1.Item.Path = path
|
|
com := commit{
|
|
Comment: params.Message,
|
|
Changes: []change{change1},
|
|
}
|
|
in := &contentCreateUpdate{
|
|
RefUpdates: []refUpdate{ref},
|
|
Commits: []commit{com},
|
|
}
|
|
|
|
res, err := s.client.do(ctx, "POST", endpoint, in, nil)
|
|
return res, err
|
|
}
|
|
|
|
func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) {
|
|
// https://docs.microsoft.com/en-us/rest/api/azure/devops/git/items/list?view=azure-devops-rest-6.0
|
|
if s.client.project == "" {
|
|
return nil, nil, ProjectRequiredError()
|
|
}
|
|
endpoint := fmt.Sprintf("%s/%s/_apis/git/repositories/%s/items?scopePath=%s&recursionLevel=Full&$format=json", s.client.owner, s.client.project, repo, path)
|
|
endpoint += generateURIFromRef(ref)
|
|
out := new(contentList)
|
|
res, err := s.client.do(ctx, "GET", endpoint, nil, &out)
|
|
return convertContentInfoList(out.Value), res, err
|
|
}
|
|
|
|
type content struct {
|
|
ObjectID string `json:"objectId"`
|
|
GitObjectType string `json:"gitObjectType"`
|
|
CommitID string `json:"commitId"`
|
|
Path string `json:"path"`
|
|
Content string `json:"content"`
|
|
URL string `json:"url"`
|
|
Links struct {
|
|
Self struct {
|
|
Href string `json:"href"`
|
|
} `json:"self"`
|
|
Repository struct {
|
|
Href string `json:"href"`
|
|
} `json:"repository"`
|
|
Blob struct {
|
|
Href string `json:"href"`
|
|
} `json:"blob"`
|
|
} `json:"_links"`
|
|
}
|
|
|
|
type contentList struct {
|
|
Count int `json:"count"`
|
|
Value []*content `json:"value"`
|
|
}
|
|
type refUpdate struct {
|
|
Name string `json:"name"`
|
|
OldObjectID string `json:"oldObjectId,omitempty"`
|
|
}
|
|
type change struct {
|
|
ChangeType string `json:"changeType"`
|
|
Item struct {
|
|
Path string `json:"path"`
|
|
} `json:"item"`
|
|
NewContent struct {
|
|
Content string `json:"content,omitempty"`
|
|
ContentType string `json:"contentType,omitempty"`
|
|
} `json:"newContent,omitempty"`
|
|
}
|
|
type commit struct {
|
|
Comment string `json:"comment"`
|
|
Changes []change `json:"changes"`
|
|
}
|
|
type contentCreateUpdate struct {
|
|
RefUpdates []refUpdate `json:"refUpdates"`
|
|
Commits []commit `json:"commits"`
|
|
}
|
|
|
|
func convertContentInfoList(from []*content) []*scm.ContentInfo {
|
|
to := []*scm.ContentInfo{}
|
|
for _, v := range from {
|
|
to = append(to, convertContentInfo(v))
|
|
}
|
|
return to
|
|
}
|
|
func convertContentInfo(from *content) *scm.ContentInfo {
|
|
to := &scm.ContentInfo{Path: from.Path}
|
|
switch from.GitObjectType {
|
|
case "blob":
|
|
to.Kind = scm.ContentKindFile
|
|
case "tree":
|
|
to.Kind = scm.ContentKindDirectory
|
|
default:
|
|
to.Kind = scm.ContentKindUnsupported
|
|
}
|
|
to.Path = from.Path
|
|
to.BlobID = from.ObjectID
|
|
to.Sha = from.CommitID
|
|
return to
|
|
}
|
|
|
|
func generateURIFromRef(ref string) (uri string) {
|
|
if ref != "" {
|
|
if len(ref) == 40 {
|
|
return fmt.Sprintf("&versionDescriptor.versionType=commit&versionDescriptor.version=%s", ref)
|
|
} else {
|
|
return fmt.Sprintf("&versionDescriptor.versionType=branch&versionDescriptor.version=%s", ref)
|
|
}
|
|
}
|
|
return ""
|
|
}
|