...

Source file src/github.com/xanzy/go-gitlab/repository_files.go

Documentation: github.com/xanzy/go-gitlab

     1  //
     2  // Copyright 2021, Sander van Harmelen
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package gitlab
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"net/http"
    23  	"strconv"
    24  	"time"
    25  )
    26  
    27  // RepositoryFilesService handles communication with the repository files
    28  // related methods of the GitLab API.
    29  //
    30  // GitLab API docs: https://docs.gitlab.com/ee/api/repository_files.html
    31  type RepositoryFilesService struct {
    32  	client *Client
    33  }
    34  
    35  // File represents a GitLab repository file.
    36  //
    37  // GitLab API docs: https://docs.gitlab.com/ee/api/repository_files.html
    38  type File struct {
    39  	FileName        string `json:"file_name"`
    40  	FilePath        string `json:"file_path"`
    41  	Size            int    `json:"size"`
    42  	Encoding        string `json:"encoding"`
    43  	Content         string `json:"content"`
    44  	ExecuteFilemode bool   `json:"execute_filemode"`
    45  	Ref             string `json:"ref"`
    46  	BlobID          string `json:"blob_id"`
    47  	CommitID        string `json:"commit_id"`
    48  	SHA256          string `json:"content_sha256"`
    49  	LastCommitID    string `json:"last_commit_id"`
    50  }
    51  
    52  func (r File) String() string {
    53  	return Stringify(r)
    54  }
    55  
    56  // GetFileOptions represents the available GetFile() options.
    57  //
    58  // GitLab API docs:
    59  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
    60  type GetFileOptions struct {
    61  	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
    62  }
    63  
    64  // GetFile allows you to receive information about a file in repository like
    65  // name, size, content. Note that file content is Base64 encoded.
    66  //
    67  // GitLab API docs:
    68  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
    69  func (s *RepositoryFilesService) GetFile(pid interface{}, fileName string, opt *GetFileOptions, options ...RequestOptionFunc) (*File, *Response, error) {
    70  	project, err := parseID(pid)
    71  	if err != nil {
    72  		return nil, nil, err
    73  	}
    74  	u := fmt.Sprintf(
    75  		"projects/%s/repository/files/%s",
    76  		PathEscape(project),
    77  		PathEscape(fileName),
    78  	)
    79  
    80  	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
    81  	if err != nil {
    82  		return nil, nil, err
    83  	}
    84  
    85  	f := new(File)
    86  	resp, err := s.client.Do(req, f)
    87  	if err != nil {
    88  		return nil, resp, err
    89  	}
    90  
    91  	return f, resp, nil
    92  }
    93  
    94  // GetFileMetaDataOptions represents the available GetFileMetaData() options.
    95  //
    96  // GitLab API docs:
    97  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
    98  type GetFileMetaDataOptions struct {
    99  	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
   100  }
   101  
   102  // GetFileMetaData allows you to receive meta information about a file in
   103  // repository like name, size.
   104  //
   105  // GitLab API docs:
   106  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
   107  func (s *RepositoryFilesService) GetFileMetaData(pid interface{}, fileName string, opt *GetFileMetaDataOptions, options ...RequestOptionFunc) (*File, *Response, error) {
   108  	project, err := parseID(pid)
   109  	if err != nil {
   110  		return nil, nil, err
   111  	}
   112  	u := fmt.Sprintf(
   113  		"projects/%s/repository/files/%s",
   114  		PathEscape(project),
   115  		PathEscape(fileName),
   116  	)
   117  
   118  	req, err := s.client.NewRequest(http.MethodHead, u, opt, options)
   119  	if err != nil {
   120  		return nil, nil, err
   121  	}
   122  
   123  	resp, err := s.client.Do(req, nil)
   124  	if err != nil {
   125  		return nil, resp, err
   126  	}
   127  
   128  	f := &File{
   129  		BlobID:          resp.Header.Get("X-Gitlab-Blob-Id"),
   130  		CommitID:        resp.Header.Get("X-Gitlab-Commit-Id"),
   131  		Encoding:        resp.Header.Get("X-Gitlab-Encoding"),
   132  		FileName:        resp.Header.Get("X-Gitlab-File-Name"),
   133  		FilePath:        resp.Header.Get("X-Gitlab-File-Path"),
   134  		ExecuteFilemode: resp.Header.Get("X-Gitlab-Execute-Filemode") == "true",
   135  		Ref:             resp.Header.Get("X-Gitlab-Ref"),
   136  		SHA256:          resp.Header.Get("X-Gitlab-Content-Sha256"),
   137  		LastCommitID:    resp.Header.Get("X-Gitlab-Last-Commit-Id"),
   138  	}
   139  
   140  	if sizeString := resp.Header.Get("X-Gitlab-Size"); sizeString != "" {
   141  		f.Size, err = strconv.Atoi(sizeString)
   142  		if err != nil {
   143  			return nil, resp, err
   144  		}
   145  	}
   146  
   147  	return f, resp, nil
   148  }
   149  
   150  // FileBlameRange represents one item of blame information.
   151  //
   152  // GitLab API docs: https://docs.gitlab.com/ee/api/repository_files.html
   153  type FileBlameRange struct {
   154  	Commit struct {
   155  		ID             string     `json:"id"`
   156  		ParentIDs      []string   `json:"parent_ids"`
   157  		Message        string     `json:"message"`
   158  		AuthoredDate   *time.Time `json:"authored_date"`
   159  		AuthorName     string     `json:"author_name"`
   160  		AuthorEmail    string     `json:"author_email"`
   161  		CommittedDate  *time.Time `json:"committed_date"`
   162  		CommitterName  string     `json:"committer_name"`
   163  		CommitterEmail string     `json:"committer_email"`
   164  	} `json:"commit"`
   165  	Lines []string `json:"lines"`
   166  }
   167  
   168  func (b FileBlameRange) String() string {
   169  	return Stringify(b)
   170  }
   171  
   172  // GetFileBlameOptions represents the available GetFileBlame() options.
   173  //
   174  // GitLab API docs:
   175  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-blame-from-repository
   176  type GetFileBlameOptions struct {
   177  	Ref        *string `url:"ref,omitempty" json:"ref,omitempty"`
   178  	RangeStart *int    `url:"range[start],omitempty" json:"range[start],omitempty"`
   179  	RangeEnd   *int    `url:"range[end],omitempty" json:"range[end],omitempty"`
   180  }
   181  
   182  // GetFileBlame allows you to receive blame information. Each blame range
   183  // contains lines and corresponding commit info.
   184  //
   185  // GitLab API docs:
   186  // https://docs.gitlab.com/ee/api/repository_files.html#get-file-blame-from-repository
   187  func (s *RepositoryFilesService) GetFileBlame(pid interface{}, file string, opt *GetFileBlameOptions, options ...RequestOptionFunc) ([]*FileBlameRange, *Response, error) {
   188  	project, err := parseID(pid)
   189  	if err != nil {
   190  		return nil, nil, err
   191  	}
   192  	u := fmt.Sprintf(
   193  		"projects/%s/repository/files/%s/blame",
   194  		PathEscape(project),
   195  		PathEscape(file),
   196  	)
   197  
   198  	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
   199  	if err != nil {
   200  		return nil, nil, err
   201  	}
   202  
   203  	var br []*FileBlameRange
   204  	resp, err := s.client.Do(req, &br)
   205  	if err != nil {
   206  		return nil, resp, err
   207  	}
   208  
   209  	return br, resp, nil
   210  }
   211  
   212  // GetRawFileOptions represents the available GetRawFile() options.
   213  //
   214  // GitLab API docs:
   215  // https://docs.gitlab.com/ee/api/repository_files.html#get-raw-file-from-repository
   216  type GetRawFileOptions struct {
   217  	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
   218  }
   219  
   220  // GetRawFile allows you to receive the raw file in repository.
   221  //
   222  // GitLab API docs:
   223  // https://docs.gitlab.com/ee/api/repository_files.html#get-raw-file-from-repository
   224  func (s *RepositoryFilesService) GetRawFile(pid interface{}, fileName string, opt *GetRawFileOptions, options ...RequestOptionFunc) ([]byte, *Response, error) {
   225  	project, err := parseID(pid)
   226  	if err != nil {
   227  		return nil, nil, err
   228  	}
   229  	u := fmt.Sprintf(
   230  		"projects/%s/repository/files/%s/raw",
   231  		PathEscape(project),
   232  		PathEscape(fileName),
   233  	)
   234  
   235  	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
   236  	if err != nil {
   237  		return nil, nil, err
   238  	}
   239  
   240  	var f bytes.Buffer
   241  	resp, err := s.client.Do(req, &f)
   242  	if err != nil {
   243  		return nil, resp, err
   244  	}
   245  
   246  	return f.Bytes(), resp, err
   247  }
   248  
   249  // FileInfo represents file details of a GitLab repository file.
   250  //
   251  // GitLab API docs: https://docs.gitlab.com/ee/api/repository_files.html
   252  type FileInfo struct {
   253  	FilePath string `json:"file_path"`
   254  	Branch   string `json:"branch"`
   255  }
   256  
   257  func (r FileInfo) String() string {
   258  	return Stringify(r)
   259  }
   260  
   261  // CreateFileOptions represents the available CreateFile() options.
   262  //
   263  // GitLab API docs:
   264  // https://docs.gitlab.com/ee/api/repository_files.html#create-new-file-in-repository
   265  type CreateFileOptions struct {
   266  	Branch          *string `url:"branch,omitempty" json:"branch,omitempty"`
   267  	StartBranch     *string `url:"start_branch,omitempty" json:"start_branch,omitempty"`
   268  	Encoding        *string `url:"encoding,omitempty" json:"encoding,omitempty"`
   269  	AuthorEmail     *string `url:"author_email,omitempty" json:"author_email,omitempty"`
   270  	AuthorName      *string `url:"author_name,omitempty" json:"author_name,omitempty"`
   271  	Content         *string `url:"content,omitempty" json:"content,omitempty"`
   272  	CommitMessage   *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
   273  	ExecuteFilemode *bool   `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"`
   274  }
   275  
   276  // CreateFile creates a new file in a repository.
   277  //
   278  // GitLab API docs:
   279  // https://docs.gitlab.com/ee/api/repository_files.html#create-new-file-in-repository
   280  func (s *RepositoryFilesService) CreateFile(pid interface{}, fileName string, opt *CreateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) {
   281  	project, err := parseID(pid)
   282  	if err != nil {
   283  		return nil, nil, err
   284  	}
   285  	u := fmt.Sprintf(
   286  		"projects/%s/repository/files/%s",
   287  		PathEscape(project),
   288  		PathEscape(fileName),
   289  	)
   290  
   291  	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
   292  	if err != nil {
   293  		return nil, nil, err
   294  	}
   295  
   296  	f := new(FileInfo)
   297  	resp, err := s.client.Do(req, f)
   298  	if err != nil {
   299  		return nil, resp, err
   300  	}
   301  
   302  	return f, resp, nil
   303  }
   304  
   305  // UpdateFileOptions represents the available UpdateFile() options.
   306  //
   307  // GitLab API docs:
   308  // https://docs.gitlab.com/ee/api/repository_files.html#update-existing-file-in-repository
   309  type UpdateFileOptions struct {
   310  	Branch          *string `url:"branch,omitempty" json:"branch,omitempty"`
   311  	StartBranch     *string `url:"start_branch,omitempty" json:"start_branch,omitempty"`
   312  	Encoding        *string `url:"encoding,omitempty" json:"encoding,omitempty"`
   313  	AuthorEmail     *string `url:"author_email,omitempty" json:"author_email,omitempty"`
   314  	AuthorName      *string `url:"author_name,omitempty" json:"author_name,omitempty"`
   315  	Content         *string `url:"content,omitempty" json:"content,omitempty"`
   316  	CommitMessage   *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
   317  	LastCommitID    *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"`
   318  	ExecuteFilemode *bool   `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"`
   319  }
   320  
   321  // UpdateFile updates an existing file in a repository
   322  //
   323  // GitLab API docs:
   324  // https://docs.gitlab.com/ee/api/repository_files.html#update-existing-file-in-repository
   325  func (s *RepositoryFilesService) UpdateFile(pid interface{}, fileName string, opt *UpdateFileOptions, options ...RequestOptionFunc) (*FileInfo, *Response, error) {
   326  	project, err := parseID(pid)
   327  	if err != nil {
   328  		return nil, nil, err
   329  	}
   330  	u := fmt.Sprintf(
   331  		"projects/%s/repository/files/%s",
   332  		PathEscape(project),
   333  		PathEscape(fileName),
   334  	)
   335  
   336  	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
   337  	if err != nil {
   338  		return nil, nil, err
   339  	}
   340  
   341  	f := new(FileInfo)
   342  	resp, err := s.client.Do(req, f)
   343  	if err != nil {
   344  		return nil, resp, err
   345  	}
   346  
   347  	return f, resp, nil
   348  }
   349  
   350  // DeleteFileOptions represents the available DeleteFile() options.
   351  //
   352  // GitLab API docs:
   353  // https://docs.gitlab.com/ee/api/repository_files.html#delete-existing-file-in-repository
   354  type DeleteFileOptions struct {
   355  	Branch        *string `url:"branch,omitempty" json:"branch,omitempty"`
   356  	StartBranch   *string `url:"start_branch,omitempty" json:"start_branch,omitempty"`
   357  	AuthorEmail   *string `url:"author_email,omitempty" json:"author_email,omitempty"`
   358  	AuthorName    *string `url:"author_name,omitempty" json:"author_name,omitempty"`
   359  	CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
   360  	LastCommitID  *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"`
   361  }
   362  
   363  // DeleteFile deletes an existing file in a repository
   364  //
   365  // GitLab API docs:
   366  // https://docs.gitlab.com/ee/api/repository_files.html#delete-existing-file-in-repository
   367  func (s *RepositoryFilesService) DeleteFile(pid interface{}, fileName string, opt *DeleteFileOptions, options ...RequestOptionFunc) (*Response, error) {
   368  	project, err := parseID(pid)
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  	u := fmt.Sprintf(
   373  		"projects/%s/repository/files/%s",
   374  		PathEscape(project),
   375  		PathEscape(fileName),
   376  	)
   377  
   378  	req, err := s.client.NewRequest(http.MethodDelete, u, opt, options)
   379  	if err != nil {
   380  		return nil, err
   381  	}
   382  
   383  	return s.client.Do(req, nil)
   384  }
   385  

View as plain text