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