repository_files.go 9.2 KB

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