Commit 10d3a30b255cd85b2cf7af39814fd7418eecd838
1 parent
4cc169d3
Exists in
master
and in
4 other branches
APi for commits. Better api docs
Showing
10 changed files
with
199 additions
and
79 deletions
Show diff stats
Guardfile
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do | 4 | guard 'rspec', :version => 2, :all_on_start => false, :all_after_pass => false do |
5 | watch(%r{^spec/.+_spec\.rb$}) | 5 | watch(%r{^spec/.+_spec\.rb$}) |
6 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } | 6 | watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" } |
7 | + watch(%r{^lib/api/(.+)\.rb$}) { |m| "spec/requests/api/#{m[1]}_spec.rb" } | ||
7 | watch('spec/spec_helper.rb') { "spec" } | 8 | watch('spec/spec_helper.rb') { "spec" } |
8 | 9 | ||
9 | # Rails example | 10 | # Rails example |
app/views/help/api.html.haml
1 | -%h3 API | 1 | +%h3.page_title API |
2 | .back_link | 2 | .back_link |
3 | = link_to help_path do | 3 | = link_to help_path do |
4 | ← to index | 4 | ← to index |
5 | -%hr | 5 | +%br |
6 | 6 | ||
7 | -%ol | 7 | +%ul.nav.nav-tabs.log-tabs |
8 | + %li.active | ||
9 | + = link_to "README", "#README", 'data-toggle' => 'tab' | ||
8 | %li | 10 | %li |
9 | - %a{href: "#README"} README | 11 | + = link_to "Projects", "#projects", 'data-toggle' => 'tab' |
10 | %li | 12 | %li |
11 | - %a{href: "#projects"} Projects | 13 | + = link_to "Snippets", "#snippets", 'data-toggle' => 'tab' |
12 | %li | 14 | %li |
13 | - %a{href: "#snippets"} Snippets | 15 | + = link_to "Users", "#users", 'data-toggle' => 'tab' |
14 | %li | 16 | %li |
15 | - %a{href: "#users"} Users | 17 | + = link_to "Session", "#session", 'data-toggle' => 'tab' |
16 | %li | 18 | %li |
17 | - %a{href: "#session"} Session | 19 | + = link_to "Issues", "#issues", 'data-toggle' => 'tab' |
18 | %li | 20 | %li |
19 | - %a{href: "#issues"} Issues | 21 | + = link_to "Milestones", "#milestones", 'data-toggle' => 'tab' |
20 | %li | 22 | %li |
21 | - %a{href: "#milestones"} Milestones | ||
22 | - | ||
23 | -.file_holder#README | ||
24 | - .file_title | ||
25 | - %i.icon-file | ||
26 | - README | ||
27 | - .file_content.wiki | ||
28 | - = preserve do | ||
29 | - = markdown File.read(Rails.root.join("doc", "api", "README.md")) | ||
30 | - | ||
31 | -%br | ||
32 | - | ||
33 | -.file_holder#projects | ||
34 | - .file_title | ||
35 | - %i.icon-file | ||
36 | - Projects | ||
37 | - .file_content.wiki | ||
38 | - = preserve do | ||
39 | - = markdown File.read(Rails.root.join("doc", "api", "projects.md")) | ||
40 | - | ||
41 | -%br | ||
42 | - | ||
43 | -.file_holder#snippets | ||
44 | - .file_title | ||
45 | - %i.icon-file | ||
46 | - Projects Snippets | ||
47 | - .file_content.wiki | ||
48 | - = preserve do | ||
49 | - = markdown File.read(Rails.root.join("doc", "api", "snippets.md")) | 23 | + = link_to "Commits", "#commits", 'data-toggle' => 'tab' |
50 | 24 | ||
51 | -%br | 25 | +.tab-content |
26 | + .tab-pane.active#README | ||
27 | + .file_holder | ||
28 | + .file_title | ||
29 | + %i.icon-file | ||
30 | + README | ||
31 | + .file_content.wiki | ||
32 | + = preserve do | ||
33 | + = markdown File.read(Rails.root.join("doc", "api", "README.md")) | ||
52 | 34 | ||
53 | -.file_holder#users | ||
54 | - .file_title | ||
55 | - %i.icon-file | ||
56 | - Users | ||
57 | - .file_content.wiki | ||
58 | - = preserve do | ||
59 | - = markdown File.read(Rails.root.join("doc", "api", "users.md")) | 35 | + .tab-pane#projects |
36 | + .file_holder | ||
37 | + .file_title | ||
38 | + %i.icon-file | ||
39 | + Projects | ||
40 | + .file_content.wiki | ||
41 | + = preserve do | ||
42 | + = markdown File.read(Rails.root.join("doc", "api", "projects.md")) | ||
60 | 43 | ||
61 | -%br | 44 | + .tab-pane#snippets |
45 | + .file_holder | ||
46 | + .file_title | ||
47 | + %i.icon-file | ||
48 | + Projects Snippets | ||
49 | + .file_content.wiki | ||
50 | + = preserve do | ||
51 | + = markdown File.read(Rails.root.join("doc", "api", "snippets.md")) | ||
62 | 52 | ||
63 | -.file_holder#session | ||
64 | - .file_title | ||
65 | - %i.icon-file | ||
66 | - Session | ||
67 | - .file_content.wiki | ||
68 | - = preserve do | ||
69 | - = markdown File.read(Rails.root.join("doc", "api", "session.md")) | 53 | + .tab-pane#users |
54 | + .file_holder | ||
55 | + .file_title | ||
56 | + %i.icon-file | ||
57 | + Users | ||
58 | + .file_content.wiki | ||
59 | + = preserve do | ||
60 | + = markdown File.read(Rails.root.join("doc", "api", "users.md")) | ||
70 | 61 | ||
71 | -%br | 62 | + .tab-pane#session |
63 | + .file_holder | ||
64 | + .file_title | ||
65 | + %i.icon-file | ||
66 | + Session | ||
67 | + .file_content.wiki | ||
68 | + = preserve do | ||
69 | + = markdown File.read(Rails.root.join("doc", "api", "session.md")) | ||
72 | 70 | ||
73 | -.file_holder#issues | ||
74 | - .file_title | ||
75 | - %i.icon-file | ||
76 | - Issues | ||
77 | - .file_content.wiki | ||
78 | - = preserve do | ||
79 | - = markdown File.read(Rails.root.join("doc", "api", "issues.md")) | 71 | + .tab-pane#issues |
72 | + .file_holder | ||
73 | + .file_title | ||
74 | + %i.icon-file | ||
75 | + Issues | ||
76 | + .file_content.wiki | ||
77 | + = preserve do | ||
78 | + = markdown File.read(Rails.root.join("doc", "api", "issues.md")) | ||
80 | 79 | ||
81 | -%br | 80 | + .tab-pane#milestones |
81 | + .file_holder | ||
82 | + .file_title | ||
83 | + %i.icon-file | ||
84 | + Milestones | ||
85 | + .file_content.wiki | ||
86 | + = preserve do | ||
87 | + = markdown File.read(Rails.root.join("doc", "api", "milestones.md")) | ||
82 | 88 | ||
83 | -.file_holder#milestones | ||
84 | - .file_title | ||
85 | - %i.icon-file | ||
86 | - Milestones | ||
87 | - .file_content.wiki | ||
88 | - = preserve do | ||
89 | - = markdown File.read(Rails.root.join("doc", "api", "milestones.md")) | 89 | + .tab-pane#commits |
90 | + .file_holder | ||
91 | + .file_title | ||
92 | + %i.icon-file | ||
93 | + Commits | ||
94 | + .file_content.wiki | ||
95 | + = preserve do | ||
96 | + = markdown File.read(Rails.root.join("doc", "api", "commits.md")) |
@@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
1 | +## List Commits | ||
2 | + | ||
3 | +Get a list of project commits. | ||
4 | + | ||
5 | +``` | ||
6 | +GET /projects/:id/commits | ||
7 | +``` | ||
8 | + | ||
9 | +Parameters: | ||
10 | + | ||
11 | ++ `id` (required) - The ID or code name of a project | ||
12 | ++ `ref_name` (optional) - branch/tag name | ||
13 | ++ `page` (optional) | ||
14 | ++ `per_page` (optional) | ||
15 | + | ||
16 | + | ||
17 | +```json | ||
18 | + | ||
19 | +[ | ||
20 | + { | ||
21 | + "id": "ed899a2f4b50b4370feeea94676502b42383c746", | ||
22 | + "short_id": "ed899a2f4b5", | ||
23 | + "title": "Replace sanitize with escape once", | ||
24 | + "author_name": "Dmitriy Zaporozhets", | ||
25 | + "author_email": "dzaporozhets@sphereconsultinginc.com", | ||
26 | + "created_at": "2012-09-20T11:50:22+03:00" | ||
27 | + }, | ||
28 | + { | ||
29 | + "id": "6104942438c14ec7bd21c6cd5bd995272b3faff6", | ||
30 | + "short_id": "6104942438c", | ||
31 | + "title": "Sanitize for network graph", | ||
32 | + "author_name": "randx", | ||
33 | + "author_email": "dmitriy.zaporozhets@gmail.com", | ||
34 | + "created_at": "2012-09-20T09:06:12+03:00" | ||
35 | + } | ||
36 | +] | ||
37 | + | ||
38 | +``` |
lib/api.rb
@@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
1 | +module Gitlab | ||
2 | + # Commits API | ||
3 | + class Commits < Grape::API | ||
4 | + before { authenticate! } | ||
5 | + | ||
6 | + resource :projects do | ||
7 | + # Get a list of project commits | ||
8 | + # | ||
9 | + # Parameters: | ||
10 | + # id (required) - The ID or code name of a project | ||
11 | + # ref_name (optional) - Name of branch or tag | ||
12 | + # page (optional) - default is 0 | ||
13 | + # per_page (optional) - default is 20 | ||
14 | + # Example Request: | ||
15 | + # GET /projects/:id/commits | ||
16 | + get ":id/commits" do | ||
17 | + authorize! :download_code, user_project | ||
18 | + | ||
19 | + page = params[:page] || 0 | ||
20 | + per_page = params[:per_page] || 20 | ||
21 | + ref = params[:ref_name] || user_project.try(:default_branch) || 'master' | ||
22 | + | ||
23 | + commits = user_project.commits(ref, nil, per_page, page * per_page) | ||
24 | + | ||
25 | + present CommitDecorator.decorate(commits), with: Entities::Commit | ||
26 | + end | ||
27 | + end | ||
28 | + end | ||
29 | +end |
lib/api/entities.rb
@@ -17,6 +17,11 @@ module Gitlab | @@ -17,6 +17,11 @@ module Gitlab | ||
17 | expose :id, :url | 17 | expose :id, :url |
18 | end | 18 | end |
19 | 19 | ||
20 | + class Commit < Grape::Entity | ||
21 | + expose :id, :short_id, :title, | ||
22 | + :author_name, :author_email, :created_at | ||
23 | + end | ||
24 | + | ||
20 | class Project < Grape::Entity | 25 | class Project < Grape::Entity |
21 | expose :id, :code, :name, :description, :path, :default_branch | 26 | expose :id, :code, :name, :description, :path, :default_branch |
22 | expose :owner, using: Entities::UserBasic | 27 | expose :owner, using: Entities::UserBasic |
lib/api/helpers.rb
lib/api/milestones.rb
@@ -11,6 +11,8 @@ module Gitlab | @@ -11,6 +11,8 @@ module Gitlab | ||
11 | # Example Request: | 11 | # Example Request: |
12 | # GET /projects/:id/milestones | 12 | # GET /projects/:id/milestones |
13 | get ":id/milestones" do | 13 | get ":id/milestones" do |
14 | + authorize! :read_milestone, user_project | ||
15 | + | ||
14 | present paginate(user_project.milestones), with: Entities::Milestone | 16 | present paginate(user_project.milestones), with: Entities::Milestone |
15 | end | 17 | end |
16 | 18 | ||
@@ -22,6 +24,8 @@ module Gitlab | @@ -22,6 +24,8 @@ module Gitlab | ||
22 | # Example Request: | 24 | # Example Request: |
23 | # GET /projects/:id/milestones/:milestone_id | 25 | # GET /projects/:id/milestones/:milestone_id |
24 | get ":id/milestones/:milestone_id" do | 26 | get ":id/milestones/:milestone_id" do |
27 | + authorize! :read_milestone, user_project | ||
28 | + | ||
25 | @milestone = user_project.milestones.find(params[:milestone_id]) | 29 | @milestone = user_project.milestones.find(params[:milestone_id]) |
26 | present @milestone, with: Entities::Milestone | 30 | present @milestone, with: Entities::Milestone |
27 | end | 31 | end |
@@ -36,6 +40,8 @@ module Gitlab | @@ -36,6 +40,8 @@ module Gitlab | ||
36 | # Example Request: | 40 | # Example Request: |
37 | # POST /projects/:id/milestones | 41 | # POST /projects/:id/milestones |
38 | post ":id/milestones" do | 42 | post ":id/milestones" do |
43 | + authorize! :admin_milestone, user_project | ||
44 | + | ||
39 | attrs = attributes_for_keys [:title, :description, :due_date] | 45 | attrs = attributes_for_keys [:title, :description, :due_date] |
40 | @milestone = user_project.milestones.new attrs | 46 | @milestone = user_project.milestones.new attrs |
41 | if @milestone.save | 47 | if @milestone.save |
lib/api/projects.rb
@@ -40,14 +40,14 @@ module Gitlab | @@ -40,14 +40,14 @@ module Gitlab | ||
40 | post do | 40 | post do |
41 | params[:code] ||= params[:name] | 41 | params[:code] ||= params[:name] |
42 | params[:path] ||= params[:name] | 42 | params[:path] ||= params[:name] |
43 | - attrs = attributes_for_keys [:code, | ||
44 | - :path, | ||
45 | - :name, | ||
46 | - :description, | ||
47 | - :default_branch, | ||
48 | - :issues_enabled, | ||
49 | - :wall_enabled, | ||
50 | - :merge_requests_enabled, | 43 | + attrs = attributes_for_keys [:code, |
44 | + :path, | ||
45 | + :name, | ||
46 | + :description, | ||
47 | + :default_branch, | ||
48 | + :issues_enabled, | ||
49 | + :wall_enabled, | ||
50 | + :merge_requests_enabled, | ||
51 | :wiki_enabled] | 51 | :wiki_enabled] |
52 | @project = Project.create_by_user(attrs, current_user) | 52 | @project = Project.create_by_user(attrs, current_user) |
53 | if @project.saved? | 53 | if @project.saved? |
@@ -207,6 +207,8 @@ module Gitlab | @@ -207,6 +207,8 @@ module Gitlab | ||
207 | # Example Request: | 207 | # Example Request: |
208 | # POST /projects/:id/snippets | 208 | # POST /projects/:id/snippets |
209 | post ":id/snippets" do | 209 | post ":id/snippets" do |
210 | + authorize! :write_snippet, user_project | ||
211 | + | ||
210 | attrs = attributes_for_keys [:title, :file_name] | 212 | attrs = attributes_for_keys [:title, :file_name] |
211 | attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? | 213 | attrs[:expires_at] = params[:lifetime] if params[:lifetime].present? |
212 | attrs[:content] = params[:code] if params[:code].present? | 214 | attrs[:content] = params[:code] if params[:code].present? |
@@ -282,6 +284,8 @@ module Gitlab | @@ -282,6 +284,8 @@ module Gitlab | ||
282 | # Example Request: | 284 | # Example Request: |
283 | # GET /projects/:id/repository/commits/:sha/blob | 285 | # GET /projects/:id/repository/commits/:sha/blob |
284 | get ":id/repository/commits/:sha/blob" do | 286 | get ":id/repository/commits/:sha/blob" do |
287 | + authorize! :download_code, user_project | ||
288 | + | ||
285 | ref = params[:sha] | 289 | ref = params[:sha] |
286 | 290 | ||
287 | commit = user_project.commit ref | 291 | commit = user_project.commit ref |
@@ -0,0 +1,29 @@ | @@ -0,0 +1,29 @@ | ||
1 | +require 'spec_helper' | ||
2 | + | ||
3 | +describe Gitlab::API do | ||
4 | + include ApiHelpers | ||
5 | + | ||
6 | + let(:user) { Factory :user } | ||
7 | + let!(:project) { Factory :project, owner: user } | ||
8 | + | ||
9 | + describe "GET /projects/:id/commits" do | ||
10 | + context "authorized user" do | ||
11 | + before { project.add_access(user, :read) } | ||
12 | + | ||
13 | + it "should return project commits" do | ||
14 | + get api("/projects/#{project.code}/commits", user) | ||
15 | + response.status.should == 200 | ||
16 | + | ||
17 | + json_response.should be_an Array | ||
18 | + json_response.first['id'].should == project.commit.id | ||
19 | + end | ||
20 | + end | ||
21 | + | ||
22 | + context "unauthorized user" do | ||
23 | + it "should return project commits" do | ||
24 | + get api("/projects/#{project.code}/commits") | ||
25 | + response.status.should == 401 | ||
26 | + end | ||
27 | + end | ||
28 | + end | ||
29 | +end |