repository_files.go

  1//
  2// Copyright 2017, 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
 17package gitlab
 18
 19import (
 20	"bytes"
 21	"fmt"
 22	"net/url"
 23	"strconv"
 24)
 25
 26// RepositoryFilesService handles communication with the repository files
 27// related methods of the GitLab API.
 28//
 29// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
 30type RepositoryFilesService struct {
 31	client *Client
 32}
 33
 34// File represents a GitLab repository file.
 35//
 36// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
 37type File struct {
 38	FileName string `json:"file_name"`
 39	FilePath string `json:"file_path"`
 40	Size     int    `json:"size"`
 41	Encoding string `json:"encoding"`
 42	Content  string `json:"content"`
 43	Ref      string `json:"ref"`
 44	BlobID   string `json:"blob_id"`
 45	CommitID string `json:"commit_id"`
 46}
 47
 48func (r File) String() string {
 49	return Stringify(r)
 50}
 51
 52// GetFileOptions represents the available GetFile() options.
 53//
 54// GitLab API docs:
 55// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
 56type GetFileOptions struct {
 57	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
 58}
 59
 60// GetFile allows you to receive information about a file in repository like
 61// name, size, content. Note that file content is Base64 encoded.
 62//
 63// GitLab API docs:
 64// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
 65func (s *RepositoryFilesService) GetFile(pid interface{}, fileName string, opt *GetFileOptions, options ...OptionFunc) (*File, *Response, error) {
 66	project, err := parseID(pid)
 67	if err != nil {
 68		return nil, nil, err
 69	}
 70	u := fmt.Sprintf(
 71		"projects/%s/repository/files/%s",
 72		pathEscape(project),
 73		url.PathEscape(fileName),
 74	)
 75
 76	req, err := s.client.NewRequest("GET", u, opt, options)
 77	if err != nil {
 78		return nil, nil, err
 79	}
 80
 81	f := new(File)
 82	resp, err := s.client.Do(req, f)
 83	if err != nil {
 84		return nil, resp, err
 85	}
 86
 87	return f, resp, err
 88}
 89
 90// GetFileMetaDataOptions represents the available GetFileMetaData() options.
 91//
 92// GitLab API docs:
 93// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
 94type GetFileMetaDataOptions struct {
 95	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
 96}
 97
 98// GetFileMetaData allows you to receive meta information about a file in
 99// repository like name, size.
100//
101// GitLab API docs:
102// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-repository
103func (s *RepositoryFilesService) GetFileMetaData(pid interface{}, fileName string, opt *GetFileMetaDataOptions, options ...OptionFunc) (*File, *Response, error) {
104	project, err := parseID(pid)
105	if err != nil {
106		return nil, nil, err
107	}
108	u := fmt.Sprintf(
109		"projects/%s/repository/files/%s",
110		pathEscape(project),
111		url.PathEscape(fileName),
112	)
113
114	req, err := s.client.NewRequest("HEAD", u, opt, options)
115	if err != nil {
116		return nil, nil, err
117	}
118
119	resp, err := s.client.Do(req, nil)
120	if err != nil {
121		return nil, resp, err
122	}
123
124	f := &File{
125		BlobID:   resp.Header.Get("X-Gitlab-Blob-Id"),
126		CommitID: resp.Header.Get("X-Gitlab-Last-Commit-Id"),
127		Encoding: resp.Header.Get("X-Gitlab-Encoding"),
128		FileName: resp.Header.Get("X-Gitlab-File-Name"),
129		FilePath: resp.Header.Get("X-Gitlab-File-Path"),
130		Ref:      resp.Header.Get("X-Gitlab-Ref"),
131	}
132
133	if sizeString := resp.Header.Get("X-Gitlab-Size"); sizeString != "" {
134		f.Size, err = strconv.Atoi(sizeString)
135		if err != nil {
136			return nil, resp, err
137		}
138	}
139
140	return f, resp, err
141}
142
143// GetRawFileOptions represents the available GetRawFile() options.
144//
145// GitLab API docs:
146// https://docs.gitlab.com/ce/api/repository_files.html#get-raw-file-from-repository
147type GetRawFileOptions struct {
148	Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
149}
150
151// GetRawFile allows you to receive the raw file in repository.
152//
153// GitLab API docs:
154// https://docs.gitlab.com/ce/api/repository_files.html#get-raw-file-from-repository
155func (s *RepositoryFilesService) GetRawFile(pid interface{}, fileName string, opt *GetRawFileOptions, options ...OptionFunc) ([]byte, *Response, error) {
156	project, err := parseID(pid)
157	if err != nil {
158		return nil, nil, err
159	}
160	u := fmt.Sprintf(
161		"projects/%s/repository/files/%s/raw",
162		pathEscape(project),
163		url.PathEscape(fileName),
164	)
165
166	req, err := s.client.NewRequest("GET", u, opt, options)
167	if err != nil {
168		return nil, nil, err
169	}
170
171	var f bytes.Buffer
172	resp, err := s.client.Do(req, &f)
173	if err != nil {
174		return nil, resp, err
175	}
176
177	return f.Bytes(), resp, err
178}
179
180// FileInfo represents file details of a GitLab repository file.
181//
182// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
183type FileInfo struct {
184	FilePath string `json:"file_path"`
185	Branch   string `json:"branch"`
186}
187
188func (r FileInfo) String() string {
189	return Stringify(r)
190}
191
192// CreateFileOptions represents the available CreateFile() options.
193//
194// GitLab API docs:
195// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository
196type CreateFileOptions struct {
197	Branch        *string `url:"branch,omitempty" json:"branch,omitempty"`
198	Encoding      *string `url:"encoding,omitempty" json:"encoding,omitempty"`
199	AuthorEmail   *string `url:"author_email,omitempty" json:"author_email,omitempty"`
200	AuthorName    *string `url:"author_name,omitempty" json:"author_name,omitempty"`
201	Content       *string `url:"content,omitempty" json:"content,omitempty"`
202	CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
203}
204
205// CreateFile creates a new file in a repository.
206//
207// GitLab API docs:
208// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository
209func (s *RepositoryFilesService) CreateFile(pid interface{}, fileName string, opt *CreateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) {
210	project, err := parseID(pid)
211	if err != nil {
212		return nil, nil, err
213	}
214	u := fmt.Sprintf(
215		"projects/%s/repository/files/%s",
216		pathEscape(project),
217		url.PathEscape(fileName),
218	)
219
220	req, err := s.client.NewRequest("POST", u, opt, options)
221	if err != nil {
222		return nil, nil, err
223	}
224
225	f := new(FileInfo)
226	resp, err := s.client.Do(req, f)
227	if err != nil {
228		return nil, resp, err
229	}
230
231	return f, resp, err
232}
233
234// UpdateFileOptions represents the available UpdateFile() options.
235//
236// GitLab API docs:
237// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository
238type UpdateFileOptions struct {
239	Branch        *string `url:"branch,omitempty" json:"branch,omitempty"`
240	Encoding      *string `url:"encoding,omitempty" json:"encoding,omitempty"`
241	AuthorEmail   *string `url:"author_email,omitempty" json:"author_email,omitempty"`
242	AuthorName    *string `url:"author_name,omitempty" json:"author_name,omitempty"`
243	Content       *string `url:"content,omitempty" json:"content,omitempty"`
244	CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
245	LastCommitID  *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"`
246}
247
248// UpdateFile updates an existing file in a repository
249//
250// GitLab API docs:
251// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository
252func (s *RepositoryFilesService) UpdateFile(pid interface{}, fileName string, opt *UpdateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) {
253	project, err := parseID(pid)
254	if err != nil {
255		return nil, nil, err
256	}
257	u := fmt.Sprintf(
258		"projects/%s/repository/files/%s",
259		pathEscape(project),
260		url.PathEscape(fileName),
261	)
262
263	req, err := s.client.NewRequest("PUT", u, opt, options)
264	if err != nil {
265		return nil, nil, err
266	}
267
268	f := new(FileInfo)
269	resp, err := s.client.Do(req, f)
270	if err != nil {
271		return nil, resp, err
272	}
273
274	return f, resp, err
275}
276
277// DeleteFileOptions represents the available DeleteFile() options.
278//
279// GitLab API docs:
280// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository
281type DeleteFileOptions struct {
282	Branch        *string `url:"branch,omitempty" json:"branch,omitempty"`
283	AuthorEmail   *string `url:"author_email,omitempty" json:"author_email,omitempty"`
284	AuthorName    *string `url:"author_name,omitempty" json:"author_name,omitempty"`
285	CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
286}
287
288// DeleteFile deletes an existing file in a repository
289//
290// GitLab API docs:
291// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository
292func (s *RepositoryFilesService) DeleteFile(pid interface{}, fileName string, opt *DeleteFileOptions, options ...OptionFunc) (*Response, error) {
293	project, err := parseID(pid)
294	if err != nil {
295		return nil, err
296	}
297	u := fmt.Sprintf(
298		"projects/%s/repository/files/%s",
299		pathEscape(project),
300		url.PathEscape(fileName),
301	)
302
303	req, err := s.client.NewRequest("DELETE", u, opt, options)
304	if err != nil {
305		return nil, err
306	}
307
308	return s.client.Do(req, nil)
309}