Commit 6a9aed1e878bc8651243d645d0a9d2f7da33f248

Authored by Dmitriy Zaporozhets
2 parents 223d2640 381638b7

Merge branch 'master' into 6-0-dev

Conflicts:
	CHANGELOG
	VERSION
	app/views/admin/teams/projects/new.html.haml
	app/views/projects/teams/available.html.haml
	doc/install/installation.md
CHANGELOG
... ... @@ -17,6 +17,16 @@ v 6.0.0
17 17 - You an use arrows to navigate at tree view
18 18 - Apply user project limit only for personal projects
19 19  
  20 +v 5.4.0
  21 + - Ability to edit own comments
  22 + - Documentation improvements
  23 + - Improve dashboard projects page
  24 + - Fixed nav for empty repos
  25 + - GitLab Markdown help page
  26 + - Misspelling fixes
  27 + - Added suppoort of unicorn and fog gems
  28 + - Added client list to API doc
  29 +
20 30 v 5.3.0
21 31 - Refactored services
22 32 - Campfire service added
... ...
app/assets/stylesheets/gitlab_bootstrap/nav.scss
... ... @@ -71,3 +71,14 @@
71 71  
72 72 &.nav-small-tabs > li > a { padding: 6px 9px; }
73 73 }
  74 +
  75 +
  76 +
  77 +/**
  78 + * fix to keep tooltips position in top navigation bar
  79 + *
  80 + */
  81 +.navbar .nav > li {
  82 + position: relative;
  83 + white-space: nowrap;
  84 +}
... ...
doc/api/README.md
... ... @@ -69,18 +69,18 @@ When listing resources you can pass the following parameters:
69 69  
70 70 ## Contents
71 71  
72   -+ [Users](users.md)
73   -+ [Session](session.md)
74   -+ [Projects](projects.md)
75   -+ [Project Snippets](project_snippets.md)
76   -+ [Repositories](repositories.md)
77   -+ [Issues](issues.md)
78   -+ [Milestones](milestones.md)
79   -+ [Notes](notes.md)
80   -+ [Deploy Keys](deploy_keys.md)
81   -+ [System Hooks](system_hooks.md)
82   -+ [Groups](groups.md)
83   -+ [User Teams](user_teams.md)
  72 ++ [Users](api/users.md)
  73 ++ [Session](api/session.md)
  74 ++ [Projects](api/projects.md)
  75 ++ [Project Snippets](api/project_snippets.md)
  76 ++ [Repositories](api/repositories.md)
  77 ++ [Issues](api/issues.md)
  78 ++ [Milestones](api/milestones.md)
  79 ++ [Notes](api/notes.md)
  80 ++ [Deploy Keys](api/deploy_keys.md)
  81 ++ [System Hooks](api/system_hooks.md)
  82 ++ [Groups](api/groups.md)
  83 ++ [User Teams](api/user_teams.md)
84 84  
85 85 ## Clients
86 86  
... ...
doc/api/projects.md
... ... @@ -453,3 +453,28 @@ Parameters:
453 453 + `id` (required) - The ID of the project.
454 454 + `branch` (required) - The name of the branch.
455 455  
  456 +
  457 +## Admin fork relation
  458 +
  459 +Allows modification of the forked relationship between existing projects. . Available only for admins.
  460 +
  461 +### Create a forked from/to relation between existing projects.
  462 +
  463 +```
  464 +POST /projects/:id/fork/:forked_from_id
  465 +```
  466 +
  467 +Parameters:
  468 +
  469 ++ `id` (required) - The ID of the project
  470 ++ `forked_from_id:` (required) - The ID of the project that was forked from
  471 +
  472 +### Delete an existing forked from relationship
  473 +
  474 +```
  475 +DELETE /projects/:id/fork
  476 +```
  477 +
  478 +Parameter:
  479 +
  480 ++ `id` (required) - The ID of the project
456 481 \ No newline at end of file
... ...
doc/install/installation.md
... ... @@ -42,11 +42,13 @@ up-to-date and install it.
42 42 apt-get install sudo -y
43 43  
44 44 **Note:**
45   -Vim is an editor that is used here whenever there are files that need to be
46   -edited by hand. But, you can use any editor you like instead.
  45 +During this installation some files will need to be edited manually.
  46 +If you are familiar with vim set it as default editor with the commands below.
  47 +If you are not familiar with vim please skip this and keep using the default editor.
47 48  
48   - # Install vim
  49 + # Install vim and set as default editor
49 50 sudo apt-get install -y vim
  51 + sudo update-alternatives --set editor /usr/bin/vim.basic
50 52  
51 53 Install the required packages:
52 54  
... ... @@ -123,7 +125,7 @@ GitLab Shell is a ssh access and repository management software developed specia
123 125  
124 126 # Edit config and replace gitlab_url
125 127 # with something like 'http://domain.com/'
126   - sudo -u git -H vim config.yml
  128 + sudo -u git -H editor config.yml
127 129  
128 130 # Do setup
129 131 sudo -u git -H ./bin/install
... ... @@ -162,7 +164,7 @@ You can change `5-3-stable` to `master` if you want the *bleeding edge* version,
162 164  
163 165 # Make sure to change "localhost" to the fully-qualified domain name of your
164 166 # host serving GitLab where necessary
165   - sudo -u git -H vim config/gitlab.yml
  167 + sudo -u git -H editor config/gitlab.yml
166 168  
167 169 # Make sure GitLab can write to the log/ and tmp/ directories
168 170 sudo chown -R git log/
... ... @@ -214,7 +216,7 @@ Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup.
214 216 # Change 'root' to 'gitlab'
215 217 # Change 'secure password' with the value you have given to $password
216 218 # You can keep the double quotes around the password
217   - sudo -u git -H vim config/database.yml
  219 + sudo -u git -H editor config/database.yml
218 220  
219 221 # Make config/database.yml readable to git only
220 222 sudo -u git -H chmod o-rwx config/database.yml
... ... @@ -295,7 +297,7 @@ Make sure to edit the config file to match your setup:
295 297  
296 298 # Change YOUR_SERVER_FQDN to the fully-qualified
297 299 # domain name of your host serving GitLab.
298   - sudo vim /etc/nginx/sites-available/gitlab
  300 + sudo editor /etc/nginx/sites-available/gitlab
299 301  
300 302 ## Restart
301 303  
... ...
lib/api/entities.rb
... ... @@ -25,6 +25,12 @@ module API
25 25 expose :id, :url, :created_at
26 26 end
27 27  
  28 + class ForkedFromProject < Grape::Entity
  29 + expose :id
  30 + expose :name, :name_with_namespace
  31 + expose :path, :path_with_namespace
  32 + end
  33 +
28 34 class Project < Grape::Entity
29 35 expose :id, :description, :default_branch, :public, :ssh_url_to_repo, :http_url_to_repo, :web_url
30 36 expose :owner, using: Entities::UserBasic
... ... @@ -32,6 +38,7 @@ module API
32 38 expose :path, :path_with_namespace
33 39 expose :issues_enabled, :merge_requests_enabled, :wall_enabled, :wiki_enabled, :created_at, :last_activity_at
34 40 expose :namespace
  41 + expose :forked_from_project, using: Entities::ForkedFromProject, :if => lambda{ | project, options | project.forked? }
35 42 end
36 43  
37 44 class ProjectMember < UserBasic
... ...
lib/api/helpers.rb
... ... @@ -5,12 +5,12 @@ module API
5 5 end
6 6  
7 7 def user_project
8   - @project ||= find_project
  8 + @project ||= find_project(params[:id])
9 9 @project || not_found!
10 10 end
11 11  
12   - def find_project
13   - project = Project.find_by_id(params[:id]) || Project.find_with_namespace(params[:id])
  12 + def find_project(id)
  13 + project = Project.find_by_id(id) || Project.find_with_namespace(id)
14 14  
15 15 if project && can?(current_user, :read_project, project)
16 16 project
... ...
lib/api/projects.rb
... ... @@ -121,6 +121,42 @@ module API
121 121 end
122 122  
123 123  
  124 + # Mark this project as forked from another
  125 + #
  126 + # Parameters:
  127 + # id: (required) - The ID of the project being marked as a fork
  128 + # forked_from_id: (required) - The ID of the project it was forked from
  129 + # Example Request:
  130 + # POST /projects/:id/fork/:forked_from_id
  131 + post ":id/fork/:forked_from_id" do
  132 + authenticated_as_admin!
  133 + forked_from_project = find_project(params[:forked_from_id])
  134 + unless forked_from_project.nil?
  135 + if user_project.forked_from_project.nil?
  136 + user_project.create_forked_project_link(forked_to_project_id: user_project.id, forked_from_project_id: forked_from_project.id)
  137 + else
  138 + render_api_error!("Project already forked", 409)
  139 + end
  140 + else
  141 + not_found!
  142 + end
  143 +
  144 + end
  145 +
  146 + # Remove a forked_from relationship
  147 + #
  148 + # Parameters:
  149 + # id: (required) - The ID of the project being marked as a fork
  150 + # Example Request:
  151 + # DELETE /projects/:id/fork
  152 + delete ":id/fork" do
  153 + authenticated_as_admin!
  154 + unless user_project.forked_project_link.nil?
  155 + user_project.forked_project_link.destroy
  156 + end
  157 + end
  158 +
  159 +
124 160 # Get a project team members
125 161 #
126 162 # Parameters:
... ...
lib/redcarpet/render/gitlab_html.rb
... ... @@ -12,7 +12,7 @@ class Redcarpet::Render::GitlabHTML &lt; Redcarpet::Render::HTML
12 12 def block_code(code, language)
13 13 options = { options: {encoding: 'utf-8'} }
14 14 lexer = Pygments::Lexer.find(language) # language can be an alias
15   - options.merge!(lexer: lexer.name.downcase) if lexer # downcase is required
  15 + options.merge!(lexer: lexer.aliases[0].downcase) if lexer # downcase is required
16 16  
17 17 # New lines are placed to fix an rendering issue
18 18 # with code wrapped inside <h1> tag for next case:
... ...
spec/requests/api/projects_spec.rb
... ... @@ -595,4 +595,71 @@ describe API::API do
595 595 end
596 596 end
597 597 end
  598 +
  599 + describe :fork_admin do
  600 + let(:project_fork_target) { create(:project) }
  601 + let(:project_fork_source) { create(:project, public: true) }
  602 +
  603 + describe "POST /projects/:id/fork/:forked_from_id" do
  604 + let(:new_project_fork_source) { create(:project, public: true) }
  605 +
  606 + it "shouldn't available for non admin users" do
  607 + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
  608 + response.status.should == 403
  609 + end
  610 +
  611 + it "should allow project to be forked from an existing project" do
  612 + project_fork_target.forked?.should_not be_true
  613 + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
  614 + response.status.should == 201
  615 + project_fork_target.reload
  616 + project_fork_target.forked_from_project.id.should == project_fork_source.id
  617 + project_fork_target.forked_project_link.should_not be_nil
  618 + project_fork_target.forked?.should be_true
  619 + end
  620 +
  621 + it "should fail if forked_from project which does not exist" do
  622 + post api("/projects/#{project_fork_target.id}/fork/9999", admin)
  623 + response.status.should == 404
  624 + end
  625 +
  626 + it "should fail with 409 if already forked" do
  627 + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
  628 + project_fork_target.reload
  629 + project_fork_target.forked_from_project.id.should == project_fork_source.id
  630 + post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
  631 + response.status.should == 409
  632 + project_fork_target.reload
  633 + project_fork_target.forked_from_project.id.should == project_fork_source.id
  634 + project_fork_target.forked?.should be_true
  635 + end
  636 + end
  637 +
  638 + describe "DELETE /projects/:id/fork" do
  639 +
  640 + it "shouldn't available for non admin users" do
  641 + delete api("/projects/#{project_fork_target.id}/fork", user)
  642 + response.status.should == 403
  643 + end
  644 +
  645 + it "should make forked project unforked" do
  646 + post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
  647 + project_fork_target.reload
  648 + project_fork_target.forked_from_project.should_not be_nil
  649 + project_fork_target.forked?.should be_true
  650 + delete api("/projects/#{project_fork_target.id}/fork", admin)
  651 + response.status.should == 200
  652 + project_fork_target.reload
  653 + project_fork_target.forked_from_project.should be_nil
  654 + project_fork_target.forked?.should_not be_true
  655 + end
  656 +
  657 + it "should be idempotent if not forked" do
  658 + project_fork_target.forked_from_project.should be_nil
  659 + delete api("/projects/#{project_fork_target.id}/fork", admin)
  660 + response.status.should == 200
  661 + project_fork_target.reload.forked_from_project.should be_nil
  662 + end
  663 + end
  664 + end
598 665 end
... ...