diff --git a/.gitignore b/.gitignore index 725f289db55e40875ff36c91214db145cbfa9391..760487ca9b31244fc0c16d7602822e08376ed712 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ config/database.yml config/initializers/omniauth.rb config/unicorn.rb db/data.yml +.idea +.DS_Store + diff --git a/Gemfile b/Gemfile index aa7cfad2934102a4ba9b9b96ef7a2c3230cb72fd..8db7d813f8e5e0f7cde499a9a202f07b581bee91 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git" gem 'grack', :git => "https://github.com/gitlabhq/grack.git" gem "linguist", "~> 1.0.0", :git => "https://github.com/gitlabhq/linguist.git" -gem "grape" +gem "grape", "~> 0.2.1" gem "stamp" gem "kaminari" gem "haml-rails" diff --git a/Gemfile.lock b/Gemfile.lock index 9c8ecdd456d1a8da10e36a7ede20a4a618cbb84c..f3a93096e48b99a9a27be53004b4def0f09bade6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,7 +170,7 @@ GEM gherkin (2.11.0) json (>= 1.4.6) git (1.2.5) - grape (0.2.0) + grape (0.2.1) hashie (~> 1.2) multi_json multi_xml @@ -392,7 +392,7 @@ DEPENDENCIES git gitolite! grack! - grape + grape (~> 0.2.1) grit! haml-rails httparty diff --git a/doc/api/projects.md b/doc/api/projects.md index cd94cd42328adb074eecc868e993062a47834480..ead310035121ba89142a83d1fcf90cb1692a7bc8 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -129,6 +129,43 @@ Parameters: ] ``` +Get a single project repository branch. + +``` +GET /projects/:id/repository/branches/:branch +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `branch` (required) - The name of the branch + +```json +{ + "name": "master", + "commit": { + "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", + "parents": [ + { + "id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8" + } + ], + "tree": "46e82de44b1061621357f24c05515327f2795a95", + "message": "add projects API", + "author": { + "name": "John Smith", + "email": "john@example.com" + }, + "committer": { + "name": "John Smith", + "email": "john@example.com" + }, + "authored_date": "2012-06-27T05:51:39-07:00", + "committed_date": "2012-06-28T03:44:20-07:00" + } +} +``` + ## Project repository tags Get a list of project repository tags sorted by name in reverse alphabetical order. @@ -268,3 +305,19 @@ Parameters: + `snippet_id` (required) - The ID of a project's snippet Status code `200` will be returned on success. + +## Raw blob content + +Get the raw file contents for a file. + +``` +GET /projects/:id/repository/commits/:sha/blob +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `sha` (required) - The commit or branch name ++ `filepath` (required) - The path the file + +Will return the raw file contents. diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 8edfa481c10cd4511d00a9a6b3d0f0f39a8b9337..0341facf9f83e9f7ae6f60114869e1a6f23ece04 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -33,6 +33,18 @@ module Gitlab present user_project.repo.heads.sort_by(&:name), :with => Entities::RepoObject end + # Get a single branch + # + # Parameters: + # id (required) - The ID or code name of a project + # branch_id (required) - The name of the branch + # Example Request: + # GET /projects/:id/repository/branches/:branch_id + get ":id/repository/branches/:branch_id" do + @branch = user_project.repo.heads.find { |item| item.name == params[:branch_id] } + present @branch, :with => Entities::RepoObject + end + # Get a project repository tags # # Parameters: @@ -131,6 +143,34 @@ module Gitlab @snippet = user_project.snippets.find(params[:snippet_id]) present @snippet.content end + + # Get a raw file contents + # + # Parameters: + # id (required) - The ID or code name of a project + # sha (required) - The commit or branch name + # filepath (required) - The path to the file to display + # Example Request: + # GET /projects/:id/repository/commits/:sha/blob + get ":id/repository/commits/:sha/blob" do + ref = params[:sha] + + commit = user_project.commit ref + error!('404 Commit Not Found', 404) unless commit + + tree = Tree.new commit.tree, user_project, ref, params[:filepath] + error!('404 File Not Found', 404) unless tree.try(:tree) + + if tree.text? + encoding = Gitlab::Encode.detect_encoding(tree.data) + content_type encoding ? "text/plain; charset=#{encoding}" : "text/plain" + else + content_type tree.mime_type + end + + present tree.data + end + end end end diff --git a/spec/api/projects_spec.rb b/spec/api/projects_spec.rb index 8852a0d346b5722cabaa24c30ba0fa3bed894499..2b50b6d0ec753b10613833ff78fd7f60469a94d3 100644 --- a/spec/api/projects_spec.rb +++ b/spec/api/projects_spec.rb @@ -53,6 +53,16 @@ describe Gitlab::API do end end + describe "GET /projects/:id/repository/branches/:branch" do + it "should return the branch information for a single branch" do + get "#{api_prefix}/projects/#{project.code}/repository/branches/new_design?private_token=#{user.private_token}" + response.status.should == 200 + + json_response['name'].should == 'new_design' + json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1' + end + end + describe "GET /projects/:id/repository/tags" do it "should return an array of project tags" do get "#{api_prefix}/projects/#{project.code}/repository/tags?private_token=#{user.private_token}" @@ -93,7 +103,7 @@ describe Gitlab::API do it "should delete existing project snippet" do expect { delete "#{api_prefix}/projects/#{project.code}/snippets/#{snippet.id}?private_token=#{user.private_token}" - }.should change { Snippet.count }.by(-1) + }.to change { Snippet.count }.by(-1) end end @@ -103,4 +113,24 @@ describe Gitlab::API do response.status.should == 200 end end + + describe "GET /projects/:id/:sha/blob" do + it "should get the raw file contents" do + get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.md&private_token=#{user.private_token}" + + response.status.should == 200 + end + + it "should return 404 for invalid branch_name" do + get "#{api_prefix}/projects/#{project.code}/repository/commits/invalid_branch_name/blob?filepath=README.md&private_token=#{user.private_token}" + + response.status.should == 404 + end + + it "should return 404 for invalid file" do + get "#{api_prefix}/projects/#{project.code}/repository/commits/master/blob?filepath=README.invalid&private_token=#{user.private_token}" + + response.status.should == 404 + end + end end