Commit d63706d72c8a52625bf1e892484261378936e240
Exists in
master
and in
4 other branches
Merge pull request #1157 from CodeAdept/api_blob_contents
API blob contents
Showing
6 changed files
with
130 additions
and
4 deletions
Show diff stats
.gitignore
Gemfile
| @@ -18,7 +18,7 @@ gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git" | @@ -18,7 +18,7 @@ gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git" | ||
| 18 | gem 'grack', :git => "https://github.com/gitlabhq/grack.git" | 18 | gem 'grack', :git => "https://github.com/gitlabhq/grack.git" |
| 19 | gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git" | 19 | gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git" |
| 20 | 20 | ||
| 21 | -gem "grape" | 21 | +gem "grape", "~> 0.2.1" |
| 22 | gem "stamp" | 22 | gem "stamp" |
| 23 | gem "kaminari" | 23 | gem "kaminari" |
| 24 | gem "haml-rails" | 24 | gem "haml-rails" |
Gemfile.lock
| @@ -170,7 +170,7 @@ GEM | @@ -170,7 +170,7 @@ GEM | ||
| 170 | gherkin (2.11.0) | 170 | gherkin (2.11.0) |
| 171 | json (>= 1.4.6) | 171 | json (>= 1.4.6) |
| 172 | git (1.2.5) | 172 | git (1.2.5) |
| 173 | - grape (0.2.0) | 173 | + grape (0.2.1) |
| 174 | hashie (~> 1.2) | 174 | hashie (~> 1.2) |
| 175 | multi_json | 175 | multi_json |
| 176 | multi_xml | 176 | multi_xml |
| @@ -392,7 +392,7 @@ DEPENDENCIES | @@ -392,7 +392,7 @@ DEPENDENCIES | ||
| 392 | git | 392 | git |
| 393 | gitolite! | 393 | gitolite! |
| 394 | grack! | 394 | grack! |
| 395 | - grape | 395 | + grape (~> 0.2.1) |
| 396 | grit! | 396 | grit! |
| 397 | haml-rails | 397 | haml-rails |
| 398 | httparty | 398 | httparty |
doc/api/projects.md
| @@ -129,6 +129,43 @@ Parameters: | @@ -129,6 +129,43 @@ Parameters: | ||
| 129 | ] | 129 | ] |
| 130 | ``` | 130 | ``` |
| 131 | 131 | ||
| 132 | +Get a single project repository branch. | ||
| 133 | + | ||
| 134 | +``` | ||
| 135 | +GET /projects/:id/repository/branches/:branch | ||
| 136 | +``` | ||
| 137 | + | ||
| 138 | +Parameters: | ||
| 139 | + | ||
| 140 | ++ `id` (required) - The ID or code name of a project | ||
| 141 | ++ `branch` (required) - The name of the branch | ||
| 142 | + | ||
| 143 | +```json | ||
| 144 | +{ | ||
| 145 | + "name": "master", | ||
| 146 | + "commit": { | ||
| 147 | + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", | ||
| 148 | + "parents": [ | ||
| 149 | + { | ||
| 150 | + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" | ||
| 151 | + } | ||
| 152 | + ], | ||
| 153 | + "tree": "46e82de44b1061621357f24c05515327f2795a95", | ||
| 154 | + "message": "add projects API", | ||
| 155 | + "author": { | ||
| 156 | + "name": "John Smith", | ||
| 157 | + "email": "john@example.com" | ||
| 158 | + }, | ||
| 159 | + "committer": { | ||
| 160 | + "name": "John Smith", | ||
| 161 | + "email": "john@example.com" | ||
| 162 | + }, | ||
| 163 | + "authored_date": "2012-06-27T05:51:39-07:00", | ||
| 164 | + "committed_date": "2012-06-28T03:44:20-07:00" | ||
| 165 | + } | ||
| 166 | +} | ||
| 167 | +``` | ||
| 168 | + | ||
| 132 | ## Project repository tags | 169 | ## Project repository tags |
| 133 | 170 | ||
| 134 | Get a list of project repository tags sorted by name in reverse alphabetical order. | 171 | Get a list of project repository tags sorted by name in reverse alphabetical order. |
| @@ -268,3 +305,19 @@ Parameters: | @@ -268,3 +305,19 @@ Parameters: | ||
| 268 | + `snippet_id` (required) - The ID of a project's snippet | 305 | + `snippet_id` (required) - The ID of a project's snippet |
| 269 | 306 | ||
| 270 | Status code `200` will be returned on success. | 307 | Status code `200` will be returned on success. |
| 308 | + | ||
| 309 | +## Raw blob content | ||
| 310 | + | ||
| 311 | +Get the raw file contents for a file. | ||
| 312 | + | ||
| 313 | +``` | ||
| 314 | +GET /projects/:id/repository/commits/:sha/blob | ||
| 315 | +``` | ||
| 316 | + | ||
| 317 | +Parameters: | ||
| 318 | + | ||
| 319 | ++ `id` (required) - The ID or code name of a project | ||
| 320 | ++ `sha` (required) - The commit or branch name | ||
| 321 | ++ `filepath` (required) - The path the file | ||
| 322 | + | ||
| 323 | +Will return the raw file contents. |
lib/api/projects.rb
| @@ -33,6 +33,18 @@ module Gitlab | @@ -33,6 +33,18 @@ module Gitlab | ||
| 33 | present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject | 33 | present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject |
| 34 | end | 34 | end |
| 35 | 35 | ||
| 36 | + # Get a single branch | ||
| 37 | + # | ||
| 38 | + # Parameters: | ||
| 39 | + # id (required) - The ID or code name of a project | ||
| 40 | + # branch_id (required) - The name of the branch | ||
| 41 | + # Example Request: | ||
| 42 | + # GET /projects/:id/repository/branches/:branch_id | ||
| 43 | + get ":id/repository/branches/:branch_id" do | ||
| 44 | + @branch = user_project.repo.heads.find { |item| item.name == params[:branch_id] } | ||
| 45 | + present @branch, :with => Entities::RepoObject | ||
| 46 | + end | ||
| 47 | + | ||
| 36 | # Get a project repository tags | 48 | # Get a project repository tags |
| 37 | # | 49 | # |
| 38 | # Parameters: | 50 | # Parameters: |
| @@ -131,6 +143,34 @@ module Gitlab | @@ -131,6 +143,34 @@ module Gitlab | ||
| 131 | @snippet = user_project.snippets.find(params[:snippet_id]) | 143 | @snippet = user_project.snippets.find(params[:snippet_id]) |
| 132 | present @snippet.content | 144 | present @snippet.content |
| 133 | end | 145 | end |
| 146 | + | ||
| 147 | + # Get a raw file contents | ||
| 148 | + # | ||
| 149 | + # Parameters: | ||
| 150 | + # id (required) - The ID or code name of a project | ||
| 151 | + # sha (required) - The commit or branch name | ||
| 152 | + # filepath (required) - The path to the file to display | ||
| 153 | + # Example Request: | ||
| 154 | + # GET /projects/:id/repository/commits/:sha/blob | ||
| 155 | + get ":id/repository/commits/:sha/blob" do | ||
| 156 | + ref = params[:sha] | ||
| 157 | + | ||
| 158 | + commit = user_project.commit ref | ||
| 159 | + error!('404 Commit Not Found', 404) unless commit | ||
| 160 | + | ||
| 161 | + tree = Tree.new commit.tree, user_project, ref, params[:filepath] | ||
| 162 | + error!('404 File Not Found', 404) unless tree.try(:tree) | ||
| 163 | + | ||
| 164 | + if tree.text? | ||
| 165 | + encoding = Gitlab::Encode.detect_encoding(tree.data) | ||
| 166 | + content_type encoding ? "text/plain; charset=#{encoding}" : "text/plain" | ||
| 167 | + else | ||
| 168 | + content_type tree.mime_type | ||
| 169 | + end | ||
| 170 | + | ||
| 171 | + present tree.data | ||
| 172 | + end | ||
| 173 | + | ||
| 134 | end | 174 | end |
| 135 | end | 175 | end |
| 136 | end | 176 | end |
spec/api/projects_spec.rb
| @@ -53,6 +53,16 @@ describe Gitlab::API do | @@ -53,6 +53,16 @@ describe Gitlab::API do | ||
| 53 | end | 53 | end |
| 54 | end | 54 | end |
| 55 | 55 | ||
| 56 | + describe "GET /projects/:id/repository/branches/:branch" do | ||
| 57 | + it "should return the branch information for a single branch" do | ||
| 58 | + get "#{api_prefix}/projects/#{project.code}/repository/branches/new_design?private_token=#{user.private_token}" | ||
| 59 | + response.status.should == 200 | ||
| 60 | + | ||
| 61 | + json_response['name'].should == 'new_design' | ||
| 62 | + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' | ||
| 63 | + end | ||
| 64 | + end | ||
| 65 | + | ||
| 56 | describe "GET /projects/:id/repository/tags" do | 66 | describe "GET /projects/:id/repository/tags" do |
| 57 | it "should return an array of project tags" do | 67 | it "should return an array of project tags" do |
| 58 | get "#{api_prefix}/projects/#{project.code}/repository/tags?private_token=#{user.private_token}" | 68 | get "#{api_prefix}/projects/#{project.code}/repository/tags?private_token=#{user.private_token}" |
| @@ -93,7 +103,7 @@ describe Gitlab::API do | @@ -93,7 +103,7 @@ describe Gitlab::API do | ||
| 93 | it "should delete existing project snippet" do | 103 | it "should delete existing project snippet" do |
| 94 | expect { | 104 | expect { |
| 95 | delete "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}" | 105 | delete "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}" |
| 96 | - }.should change { Snippet.count }.by(-1) | 106 | + }.to change { Snippet.count }.by(-1) |
| 97 | end | 107 | end |
| 98 | end | 108 | end |
| 99 | 109 | ||
| @@ -103,4 +113,24 @@ describe Gitlab::API do | @@ -103,4 +113,24 @@ describe Gitlab::API do | ||
| 103 | response.status.should == 200 | 113 | response.status.should == 200 |
| 104 | end | 114 | end |
| 105 | end | 115 | end |
| 116 | + | ||
| 117 | + describe "GET /projects/:id/:sha/blob" do | ||
| 118 | + it "should get the raw file contents" do | ||
| 119 | + get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.md&private_token=#{user.private_token}" | ||
| 120 | + | ||
| 121 | + response.status.should == 200 | ||
| 122 | + end | ||
| 123 | + | ||
| 124 | + it "should return 404 for invalid branch_name" do | ||
| 125 | + get "#{api_prefix}/projects/#{project.code}/repository/commits/invalid_branch_name/blob?filepath=README.md&private_token=#{user.private_token}" | ||
| 126 | + | ||
| 127 | + response.status.should == 404 | ||
| 128 | + end | ||
| 129 | + | ||
| 130 | + it "should return 404 for invalid file" do | ||
| 131 | + get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.invalid&private_token=#{user.private_token}" | ||
| 132 | + | ||
| 133 | + response.status.should == 404 | ||
| 134 | + end | ||
| 135 | + end | ||
| 106 | end | 136 | end |