Commit ddbe978041753d7851780165f8c6c66865570862

Authored by Dmitriy Zaporozhets
1 parent 87a449f2

Complete api files CRUD

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
app/models/repository.rb
... ... @@ -180,13 +180,13 @@ class Repository
180 180 end
181 181  
182 182 def blob_at_branch(branch_name, path)
183   - last_commit = commit(branch_name)
  183 + last_commit = commit(branch_name)
184 184  
185   - if last_commit
186   - blob_at(last_commit.sha, path)
187   - else
188   - nil
189   - end
  185 + if last_commit
  186 + blob_at(last_commit.sha, path)
  187 + else
  188 + nil
  189 + end
190 190 end
191 191  
192 192 # Returns url for submodule
... ...
app/views/help/_api_layout.html.haml
... ... @@ -5,7 +5,7 @@
5 5 %i.icon-angle-left
6 6 Back to help
7 7 %ul.nav.nav-pills.nav-stacked
8   - - %w(README projects project_snippets repositories deploy_keys users groups session issues milestones merge_requests notes system_hooks).each do |file|
  8 + - %w(README projects project_snippets repositories repository_files deploy_keys users groups session issues milestones merge_requests notes system_hooks).each do |file|
9 9 %li{class: file == @category ? 'active' : nil}
10 10 = link_to file.titleize, help_api_file_path(file)
11 11  
... ...
doc/api/README.md
... ... @@ -127,6 +127,7 @@ But when you want to create a link to web page - use `http:://host/project/issu
127 127 + [Projects](projects.md)
128 128 + [Project Snippets](project_snippets.md)
129 129 + [Repositories](repositories.md)
  130 ++ [Repository Files](repository_files.md)
130 131 + [Merge Requests](merge_requests.md)
131 132 + [Issues](issues.md)
132 133 + [Milestones](milestones.md)
... ...
doc/api/repositories.md
... ... @@ -388,44 +388,3 @@ GET /projects/:id/repository/archive
388 388 Parameters:
389 389 + `id` (required) - The ID of a project
390 390 + `sha` (optional) - The commit sha to download defaults to the tip of the default branch
391   -
392   -
393   -## Create new file in repository
394   -
395   -```
396   -POST /projects/:id/repository/files
397   -```
398   -
399   -Parameters:
400   -
401   -+ `file_path` (optional) - Full path to new file. Ex. lib/class.rb
402   -+ `branch_name` (required) - The name of branch
403   -+ `encoding` (optional) - 'text' or 'base64'. Text is default.
404   -+ `content` (required) - File content
405   -+ `commit_message` (required) - Commit message
406   -
407   -## Update existing file in repository
408   -
409   -```
410   -PUT /projects/:id/repository/files
411   -```
412   -
413   -Parameters:
414   -
415   -+ `file_path` (required) - Full path to file. Ex. lib/class.rb
416   -+ `branch_name` (required) - The name of branch
417   -+ `encoding` (optional) - 'text' or 'base64'. Text is default.
418   -+ `content` (required) - New file content
419   -+ `commit_message` (required) - Commit message
420   -
421   -## Delete existing file in repository
422   -
423   -```
424   -DELETE /projects/:id/repository/files
425   -```
426   -
427   -Parameters:
428   -
429   -+ `file_path` (required) - Full path to file. Ex. lib/class.rb
430   -+ `branch_name` (required) - The name of branch
431   -+ `commit_message` (required) - Commit message
... ...
doc/api/repository_files.md 0 → 100644
... ... @@ -0,0 +1,102 @@
  1 +# CRUD for repository files
  2 +
  3 +## Create, read, update and delete repository files using this API
  4 +
  5 +- - -
  6 +
  7 +## Get file from repository
  8 +
  9 +Allows you to receive information about file in repository like name, size, content.
  10 +Note that file content is Base64 encoded.
  11 +
  12 +```
  13 +GET /projects/:id/repository/files
  14 +```
  15 +
  16 +Example response:
  17 +
  18 +```json
  19 +{
  20 + "file_name": "key.rb",
  21 + "file_path": "app/models/key.rb",
  22 + "size": 1476,
  23 + "encoding": "base64",
  24 + "content": "IyA9PSBTY2hlbWEgSW5mb3...",
  25 + "ref": "master",
  26 + "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
  27 + "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
  28 +}
  29 +```
  30 +
  31 +Parameters:
  32 +
  33 ++ `file_path` (required) - Full path to new file. Ex. lib/class.rb
  34 ++ `ref` (required) - The name of branch, tag or commit
  35 +
  36 +## Create new file in repository
  37 +
  38 +```
  39 +POST /projects/:id/repository/files
  40 +```
  41 +
  42 +Example response:
  43 +
  44 +```json
  45 +{
  46 + "file_name": "app/project.rb",
  47 + "branch_name": "master",
  48 +}
  49 +```
  50 +
  51 +Parameters:
  52 +
  53 ++ `file_path` (required) - Full path to new file. Ex. lib/class.rb
  54 ++ `branch_name` (required) - The name of branch
  55 ++ `encoding` (optional) - 'text' or 'base64'. Text is default.
  56 ++ `content` (required) - File content
  57 ++ `commit_message` (required) - Commit message
  58 +
  59 +## Update existing file in repository
  60 +
  61 +```
  62 +PUT /projects/:id/repository/files
  63 +```
  64 +
  65 +Example response:
  66 +
  67 +```json
  68 +{
  69 + "file_name": "app/project.rb",
  70 + "branch_name": "master",
  71 +}
  72 +```
  73 +
  74 +Parameters:
  75 +
  76 ++ `file_path` (required) - Full path to file. Ex. lib/class.rb
  77 ++ `branch_name` (required) - The name of branch
  78 ++ `encoding` (optional) - 'text' or 'base64'. Text is default.
  79 ++ `content` (required) - New file content
  80 ++ `commit_message` (required) - Commit message
  81 +
  82 +## Delete existing file in repository
  83 +
  84 +```
  85 +DELETE /projects/:id/repository/files
  86 +```
  87 +
  88 +Example response:
  89 +
  90 +```json
  91 +{
  92 + "file_name": "app/project.rb",
  93 + "branch_name": "master",
  94 +}
  95 +```
  96 +
  97 +Parameters:
  98 +
  99 ++ `file_path` (required) - Full path to file. Ex. lib/class.rb
  100 ++ `branch_name` (required) - The name of branch
  101 ++ `commit_message` (required) - Commit message
  102 +
... ...
lib/api/files.rb
... ... @@ -5,10 +5,61 @@ module API
5 5 before { authorize! :push_code, user_project }
6 6  
7 7 resource :projects do
  8 + # Get file from repository
  9 + # File content is Base64 encoded
  10 + #
  11 + # Parameters:
  12 + # file_path (required) - The path to the file. Ex. lib/class.rb
  13 + # ref (required) - The name of branch, tag or commit
  14 + #
  15 + # Example Request:
  16 + # GET /projects/:id/repository/files
  17 + #
  18 + # Example response:
  19 + # {
  20 + # "file_name": "key.rb",
  21 + # "file_path": "app/models/key.rb",
  22 + # "size": 1476,
  23 + # "encoding": "base64",
  24 + # "content": "IyA9PSBTY2hlbWEgSW5mb3...",
  25 + # "ref": "master",
  26 + # "blob_id": "79f7bbd25901e8334750839545a9bd021f0e4c83",
  27 + # "commit_id": "d5a3ff139356ce33e37e73add446f16869741b50"
  28 + # }
  29 + #
  30 + get ":id/repository/files" do
  31 + required_attributes! [:file_path, :ref]
  32 + attrs = attributes_for_keys [:file_path, :ref]
  33 + ref = attrs.delete(:ref)
  34 + file_path = attrs.delete(:file_path)
  35 +
  36 + commit = user_project.repository.commit(ref)
  37 + not_found! "Commit" unless commit
  38 +
  39 + blob = user_project.repository.blob_at(commit.sha, file_path)
  40 +
  41 + if blob
  42 + status(200)
  43 +
  44 + {
  45 + file_name: blob.name,
  46 + file_path: blob.path,
  47 + size: blob.size,
  48 + encoding: "base64",
  49 + content: Base64.encode64(blob.data),
  50 + ref: ref,
  51 + blob_id: blob.id,
  52 + commit_id: commit.id,
  53 + }
  54 + else
  55 + render_api_error!('File not found', 404)
  56 + end
  57 + end
  58 +
8 59 # Create new file in repository
9 60 #
10 61 # Parameters:
11   - # file_path (optional) - The path to new file. Ex. lib/class.rb
  62 + # file_path (required) - The path to new file. Ex. lib/class.rb
12 63 # branch_name (required) - The name of branch
13 64 # content (required) - File content
14 65 # commit_message (required) - Commit message
... ...
spec/requests/api/files_spec.rb
... ... @@ -9,6 +9,36 @@ describe API::API do
9 9 let!(:project) { create(:project, namespace: user.namespace ) }
10 10 before { project.team << [user, :developer] }
11 11  
  12 + describe "GET /projects/:id/repository/files" do
  13 + it "should return file info" do
  14 + params = {
  15 + file_path: 'app/models/key.rb',
  16 + ref: 'master',
  17 + }
  18 +
  19 + get api("/projects/#{project.id}/repository/files", user), params
  20 + response.status.should == 200
  21 + json_response['file_path'].should == 'app/models/key.rb'
  22 + json_response['file_name'].should == 'key.rb'
  23 + Base64.decode64(json_response['content']).lines.first.should == "class Key < ActiveRecord::Base\n"
  24 + end
  25 +
  26 + it "should return a 400 bad request if no params given" do
  27 + get api("/projects/#{project.id}/repository/files", user)
  28 + response.status.should == 400
  29 + end
  30 +
  31 + it "should return a 404 if such file does not exist" do
  32 + params = {
  33 + file_path: 'app/models/application.rb',
  34 + ref: 'master',
  35 + }
  36 +
  37 + get api("/projects/#{project.id}/repository/files", user), params
  38 + response.status.should == 404
  39 + end
  40 + end
  41 +
12 42 describe "POST /projects/:id/repository/files" do
13 43 let(:valid_params) {
14 44 {
... ...