From e6524a919ee4c92d82518c2520d5c0cabc32eb47 Mon Sep 17 00:00:00 2001 From: Ilya Baryshev Date: Tue, 16 Oct 2012 23:05:11 +0400 Subject: [PATCH 001/122] Wiki search Very basic, using LIKE, and no search snippets. --- app/contexts/search_context.rb | 4 +++- app/controllers/search_controller.rb | 1 + app/models/wiki.rb | 6 ++++++ app/views/search/show.html.haml | 19 ++++++++++++++++++- features/dashboard/search.feature | 5 +++++ features/steps/dashboard/dashboard_search.rb | 17 +++++++++++++++++ 6 files changed, 50 insertions(+), 2 deletions(-) diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb index 6e5e8c5e..9becb8d6 100644 --- a/app/contexts/search_context.rb +++ b/app/contexts/search_context.rb @@ -13,6 +13,7 @@ class SearchContext result[:projects] = Project.where(id: project_ids).search(query).limit(10) result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10) result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10) + result[:wiki_pages] = Wiki.where(project_id: project_ids).search(query).limit(10) result end @@ -20,7 +21,8 @@ class SearchContext @result ||= { projects: [], merge_requests: [], - issues: [] + issues: [], + wiki_pages: [] } end end diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 1dc8507e..4f45f9dd 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -5,5 +5,6 @@ class SearchController < ApplicationController @projects = result[:projects] @merge_requests = result[:merge_requests] @issues = result[:issues] + @wiki_pages = result[:wiki_pages] end end diff --git a/app/models/wiki.rb b/app/models/wiki.rb index b1f41d63..895c2896 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -15,6 +15,12 @@ class Wiki < ActiveRecord::Base slug end + class << self + def search(query) + where("title like :query OR content like :query", query: "%#{query}%") + end + end + protected def self.regenerate_from wiki diff --git a/app/views/search/show.html.haml b/app/views/search/show.html.haml index d85c24ec..0d5f5458 100644 --- a/app/views/search/show.html.haml +++ b/app/views/search/show.html.haml @@ -9,7 +9,7 @@ %br %h3 Search results - %small (#{@projects.count + @merge_requests.count + @issues.count}) + %small (#{@projects.count + @merge_requests.count + @issues.count + @wiki_pages.count}) %hr .search_results .row @@ -69,6 +69,23 @@ %tr %td %h4.nothing_here_message No Issues + .span6 + %table + %thead + %tr + %th Wiki + %tbody + - @wiki_pages.each do |wiki_page| + %tr + %td + = link_to project_wiki_path(wiki_page.project, wiki_page) do + %strong.term= truncate wiki_page.title, length: 40 + %strong.right + %span.label= wiki_page.project.name + - if @wiki_pages.blank? + %tr + %td + %h4.nothing_here_message No wiki pages :javascript $(function() { $(".search_results .term").highlight("#{params[:search]}"); diff --git a/features/dashboard/search.feature b/features/dashboard/search.feature index 91d870f4..9813d9d1 100644 --- a/features/dashboard/search.feature +++ b/features/dashboard/search.feature @@ -2,8 +2,13 @@ Feature: Dashboard Search Background: Given I sign in as a user And I own project "Shop" + And Project "Shop" has wiki page "Contibuting guide" And I visit dashboard search page Scenario: I should see project I am looking for Given I search for "Sho" Then I should see "Shop" project link + + Scenario: I should see wiki page I am looking for + Given I search for "Contibuting" + Then I should see "Contibuting guide" wiki link \ No newline at end of file diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb index e3585898..e902e404 100644 --- a/features/steps/dashboard/dashboard_search.rb +++ b/features/steps/dashboard/dashboard_search.rb @@ -15,4 +15,21 @@ class DashboardSearch < Spinach::FeatureSteps @project = Factory :project, :name => "Shop" @project.add_access(@user, :admin) end + + Given 'I search for "Contibuting"' do + fill_in "dashboard_search", :with => "Contibuting" + click_button "Search" + end + + And 'Project "Shop" has wiki page "Contibuting guide"' do + @wiki_page = Factory :wiki, :project => @project, + :title => "Contibuting guide", + :slug => "contributing" + end + + Then 'I should see "Contibuting guide" wiki link' do + page.should have_link "Contibuting guide" + end + + end From 770ec3359d9c4bb3a53d7e44719cc4fa51b6b174 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:09:34 -0700 Subject: [PATCH 002/122] fix ambiguous entry in changelog --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 69683756..c365a55b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,7 +4,7 @@ master - Fixed bug with gitolite keys - [API] list one project hook - [API] edit project hook - - [API] add project snippets list + - [API] list project snippets - [API] allow to authorize using private token in HTTP header - [API] add user creation From c61020632147e0855cf229bce81aa080ca1e5992 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:23:10 -0700 Subject: [PATCH 003/122] fix mass-assignment error in user create API --- lib/api/users.rb | 4 ++-- spec/requests/api/users_spec.rb | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/api/users.rb b/lib/api/users.rb index 7f548aaa..108a3f12 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -23,7 +23,7 @@ module Gitlab @user = User.find(params[:id]) present @user, with: Entities::User end - + # Create user. Available only for admin # # Parameters: @@ -40,7 +40,7 @@ module Gitlab post do authenticated_as_admin! attrs = attributes_for_keys [:email, :name, :password, :password_confirmation, :skype, :linkedin, :twitter, :projects_limit] - user = User.new attrs + user = User.new attrs, as: :admin if user.save present user, with: Entities::User else diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index e3049e09..4c2e6ada 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -4,7 +4,7 @@ describe Gitlab::API do include ApiHelpers let(:user) { Factory :user } - let(:admin) {Factory :admin} + let(:admin) { Factory :admin } let(:key) { Factory :key, user: user } describe "GET /users" do @@ -42,9 +42,9 @@ describe Gitlab::API do end it "should create user" do - expect{ - post api("/users", admin), Factory.attributes(:user) - }.to change{User.count}.by(1) + expect { + post api("/users", admin), Factory.attributes(:user, projects_limit: 3) + }.to change { User.count }.by(1) end it "shouldn't available for non admin users" do From 2dc0f098fdfe1d07e557f7da92b3cff9d7351276 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:25:39 -0700 Subject: [PATCH 004/122] fix typos in specs --- spec/requests/api/projects_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 51526f89..a6c270aa 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -46,7 +46,7 @@ describe Gitlab::API do response.status.should == 201 end - it "should repsond with 404 on failure" do + it "should respond with 404 on failure" do post api("/projects", user) response.status.should == 404 end @@ -188,7 +188,7 @@ describe Gitlab::API do }.to change {project.hooks.count}.by(1) end end - + describe "PUT /projects/:id/hooks/:hook_id" do it "should update an existing project hook" do put api("/projects/#{project.code}/hooks/#{hook.id}", user), @@ -197,7 +197,7 @@ describe Gitlab::API do json_response['url'].should == 'http://example.com' end end - + describe "DELETE /projects/:id/hooks" do it "should delete hook from project" do @@ -239,7 +239,7 @@ describe Gitlab::API do end describe "GET /projects/:id/snippets" do - it "should return a project snippet" do + it "should return an array of project snippets" do get api("/projects/#{project.code}/snippets", user) response.status.should == 200 json_response.should be_an Array From 0369c74e581ed7f3c2e6576be3f1afcd20b54022 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:28:26 -0700 Subject: [PATCH 005/122] fix wrong test case --- spec/requests/api/projects_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index a6c270aa..5f9a587d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -192,9 +192,9 @@ describe Gitlab::API do describe "PUT /projects/:id/hooks/:hook_id" do it "should update an existing project hook" do put api("/projects/#{project.code}/hooks/#{hook.id}", user), - url: 'http://example.com' + url: 'http://example.org' response.status.should == 200 - json_response['url'].should == 'http://example.com' + json_response['url'].should == 'http://example.org' end end From 00325a733a76d8388a64e4a38c8f4e70f2a49938 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:34:18 -0700 Subject: [PATCH 006/122] name and password_confirmation not required to create a user via API --- lib/api/users.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/api/users.rb b/lib/api/users.rb index 108a3f12..57e0aa10 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -28,18 +28,17 @@ module Gitlab # # Parameters: # email (required) - Email - # name (required) - Name # password (required) - Password - # password_confirmation (required) - Password confirmation + # name - Name # skype - Skype ID # linkedin - Linkedin # twitter - Twitter account - # projects_limit - Limit projects wich user can create + # projects_limit - Number of projects user can create # Example Request: # POST /users post do authenticated_as_admin! - attrs = attributes_for_keys [:email, :name, :password, :password_confirmation, :skype, :linkedin, :twitter, :projects_limit] + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit] user = User.new attrs, as: :admin if user.save present user, with: Entities::User From cf70439e0a61637a8ad12360c53df08320b937b9 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Fri, 19 Oct 2012 03:39:02 -0700 Subject: [PATCH 007/122] update API docs --- doc/api/users.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/api/users.md b/doc/api/users.md index 63271ee8..c116144d 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -74,14 +74,12 @@ POST /users Parameters: + `email` (required) - Email -+ `name` (required) - Name + `password` (required) - Password -+ `password_confirmation` (required) - Password confirmation ++ `name` - Name + `skype` - Skype ID + `linkedin` - Linkedin + `twitter` - Twitter account -+ `projects_limit` - Limit projects wich user can create - ++ `projects_limit` - Number of projects user can create Will return created user with status `201 Created` on success, or `404 Not found` on fail. From b1ef7d7a44dc135faa179c6223eabb7bb8822f0b Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Wed, 10 Oct 2012 05:11:40 -0700 Subject: [PATCH 008/122] fix typo in spec --- spec/requests/api/projects_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 51526f89..88bd8196 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -239,7 +239,7 @@ describe Gitlab::API do end describe "GET /projects/:id/snippets" do - it "should return a project snippet" do + it "should return an array of project snippets" do get api("/projects/#{project.code}/snippets", user) response.status.should == 200 json_response.should be_an Array From 46921e690ec95fdfb4c38ea1a2dd65261719ba23 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Wed, 10 Oct 2012 06:41:20 -0700 Subject: [PATCH 009/122] cleanup main.coffee --- app/assets/javascripts/main.js.coffee | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 86b19162..93b122d9 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -7,7 +7,7 @@ window.slugify = (text) -> window.ajaxGet = (url) -> $.ajax({type: "GET", url: url, dataType: "script"}) - # Disable button if text field is empty +# Disable button if text field is empty window.disableButtonIfEmptyField = (field_selector, button_selector) -> field = $(field_selector) closest_submit = field.closest("form").find(button_selector) @@ -15,21 +15,21 @@ window.disableButtonIfEmptyField = (field_selector, button_selector) -> closest_submit.disable() if field.val() is "" field.on "keyup", -> - if $(this).val() is "" + if $(@).val() is "" closest_submit.disable() else closest_submit.enable() $ -> # Click a .one_click_select field, select the contents - $(".one_click_select").live 'click', -> $(this).select() + $(".one_click_select").on 'click', -> $(@).select() # Initialize chosen selects $('select.chosen').chosen() # Disable form buttons while a form is submitting $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> - buttons = $('[type="submit"]', this) + buttons = $('[type="submit"]', @) switch e.type when 'ajax:beforeSend', 'submit' @@ -38,7 +38,7 @@ $ -> buttons.enable() # Show/Hide the profile menu when hovering the account box - $('.account-box').hover -> $(this).toggleClass('hover') + $('.account-box').hover -> $(@).toggleClass('hover') # Focus search field by pressing 's' key $(document).keypress (e) -> @@ -52,22 +52,22 @@ $ -> # Commit show suppressed diff $(".supp_diff_link").bind "click", -> - $(this).next('table').show() - $(this).remove() + $(@).next('table').show() + $(@).remove() # Note markdown preview $(document).on 'click', '#preview-link', (e) -> - $('#preview-note').text('Loading...') + $('#preview-note').text 'Loading...' - previewLinkText = if $(this).text() == 'Preview' then 'Edit' else 'Preview' - $(this).text(previewLinkText) + previewLinkText = if $(@).text() is 'Preview' then 'Edit' else 'Preview' + $(@).text previewLinkText note = $('#note_note').val() - if note.trim().length == 0 - $('#preview-note').text("Nothing to preview.") + if note.trim().length is 0 + $('#preview-note').text 'Nothing to preview.' else - $.post $(this).attr('href'), {note: note}, (data) -> + $.post $(@).attr('href'), {note: note}, (data) -> $('#preview-note').html(data) $('#preview-note, #note_note').toggle() @@ -79,14 +79,14 @@ $ -> $.fn.extend chosen: (options) -> default_options = search_contains: "true" $.extend default_options, options - _chosen.apply this, [default_options] + _chosen.apply @, [default_options] # Disable an element and add the 'disabled' Bootstrap class $.fn.extend disable: -> - $(this).attr('disabled', 'disabled').addClass('disabled') + $(@).attr('disabled', 'disabled').addClass('disabled') # Enable an element and remove the 'disabled' Bootstrap class $.fn.extend enable: -> - $(this).removeAttr('disabled').removeClass('disabled') + $(@).removeAttr('disabled').removeClass('disabled') )(jQuery) From ec1bccb26173640387124567e9ef748ae220ff37 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Thu, 11 Oct 2012 23:19:34 -0700 Subject: [PATCH 010/122] use 'js-' prefix for behavioral 'gfm-input' class --- app/assets/javascripts/gfm_auto_complete.js.coffee | 8 ++++---- app/views/issues/_form.html.haml | 4 ++-- app/views/merge_requests/_form.html.haml | 8 ++++---- app/views/notes/_common_form.html.haml | 2 +- app/views/notes/_per_line_form.html.haml | 2 +- app/views/wikis/_form.html.haml | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 203a5b67..f68a029d 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -22,14 +22,14 @@ window.setupGfmAutoComplete = -> ### Emoji ### - $('.gfm-input').atWho ':', + $('.js-gfm-input').atWho ':', data: autocompleteEmojiData, tpl: autocompleteEmojiTemplate ### Team Members ### - $('.gfm-input').atWho '@', (query, callback) -> + $('.js-gfm-input').atWho '@', (query, callback) -> (getMoreMembers = -> $.getJSON(autocompleteMembersUrl, autocompleteMembersParams) .success (members) -> @@ -45,7 +45,7 @@ window.setupGfmAutoComplete = -> # are we past the last page? if newMembersData.length == 0 # set static data and stop callbacks - $('.gfm-input').atWho '@', + $('.js-gfm-input').atWho '@', data: autocompleteMembersData callback: null else @@ -54,4 +54,4 @@ window.setupGfmAutoComplete = -> # so the next request gets the next page autocompleteMembersParams.page += 1; - ).call(); \ No newline at end of file + ).call(); diff --git a/app/views/issues/_form.html.haml b/app/views/issues/_form.html.haml index ec3edce0..3e2cacbb 100644 --- a/app/views/issues/_form.html.haml +++ b/app/views/issues/_form.html.haml @@ -12,7 +12,7 @@ = f.label :title do %strong= "Subject *" .input - = f.text_field :title, maxlength: 255, class: "xxlarge gfm-input" + = f.text_field :title, maxlength: 255, class: "xxlarge js-gfm-input" .issue_middle_block .issue_assignee = f.label :assignee_id do @@ -37,7 +37,7 @@ .clearfix = f.label :description, "Details" .input - = f.text_area :description, maxlength: 2000, class: "xxlarge gfm-input", rows: 14 + = f.text_area :description, maxlength: 2000, class: "xxlarge js-gfm-input", rows: 14 %p.hint Issues are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml index 30f88102..c420fac2 100644 --- a/app/views/merge_requests/_form.html.haml +++ b/app/views/merge_requests/_form.html.haml @@ -30,12 +30,12 @@ .clearfix .main_box .top_box_content - = f.label :title do + = f.label :title do %strong= "Title *" - .input= f.text_field :title, class: "input-xxlarge pad gfm-input", maxlength: 255, rows: 5 + .input= f.text_field :title, class: "input-xxlarge pad js-gfm-input", maxlength: 255, rows: 5 .middle_box_content - = f.label :assignee_id do - %i.icon-user + = f.label :assignee_id do + %i.icon-user Assign to .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'}) diff --git a/app/views/notes/_common_form.html.haml b/app/views/notes/_common_form.html.haml index a9f2907b..0725082d 100644 --- a/app/views/notes/_common_form.html.haml +++ b/app/views/notes/_common_form.html.haml @@ -8,7 +8,7 @@ = f.hidden_field :noteable_id = f.hidden_field :noteable_type - = f.text_area :note, size: 255, class: 'note-text gfm-input' + = f.text_area :note, size: 255, class: 'note-text js-gfm-input' #preview-note.preview_note.hide .hint .right Comments are parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}. diff --git a/app/views/notes/_per_line_form.html.haml b/app/views/notes/_per_line_form.html.haml index ee0cde4b..c8d79850 100644 --- a/app/views/notes/_per_line_form.html.haml +++ b/app/views/notes/_per_line_form.html.haml @@ -13,7 +13,7 @@ = f.hidden_field :noteable_id = f.hidden_field :noteable_type = f.hidden_field :line_code - = f.text_area :note, size: 255, class: 'line-note-text gfm-input' + = f.text_area :note, size: 255, class: 'line-note-text js-gfm-input' .note_actions .buttons = f.submit 'Add note', class: "btn save-btn submit_note submit_inline_note", id: "submit_note" diff --git a/app/views/wikis/_form.html.haml b/app/views/wikis/_form.html.haml index 89bbe2ea..83b16b13 100644 --- a/app/views/wikis/_form.html.haml +++ b/app/views/wikis/_form.html.haml @@ -21,7 +21,7 @@ .bottom_box_content = f.label :content - .input= f.text_area :content, class: 'span8 gfm-input' + .input= f.text_area :content, class: 'span8 js-gfm-input' .actions = f.submit 'Save', class: "save-btn btn" = link_to "Cancel", project_wiki_path(@project, :index), class: "btn cancel-btn" From 57c134c39a106a3e9b9de776c06fe971b83a8224 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Tue, 16 Oct 2012 04:01:40 -0700 Subject: [PATCH 011/122] cleanup coffeescript code for mentions auto-complete --- .../javascripts/gfm_auto_complete.js.coffee | 78 ++++++++----------- .../layouts/_init_auto_complete.html.haml | 8 +- 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index f68a029d..6c0c8886 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -1,57 +1,47 @@ +# Creates the variables for setting up GFM auto-completion -### - Creates the variables for setting up GFM auto-completion -### # Emoji -window.autocompleteEmojiData = []; -window.autocompleteEmojiTemplate = "
  • ${name} ${name}
  • "; +data = [] +template = "
  • ${name} ${name}
  • " +window.autocompleteEmoji = {data, template} # Team Members -window.autocompleteMembersUrl = ""; -window.autocompleteMembersParams = - private_token: "" - page: 1 -window.autocompleteMembersData = []; +url = ''; +params = {private_token: '', page: 1} +window.autocompleteMembers = {data, url, params} - - -### - Add GFM auto-completion to all input fields, that accept GFM input. -### +# Add GFM auto-completion to all input fields, that accept GFM input. window.setupGfmAutoComplete = -> - ### - Emoji - ### - $('.js-gfm-input').atWho ':', - data: autocompleteEmojiData, - tpl: autocompleteEmojiTemplate + $input = $('.js-gfm-input') - ### - Team Members - ### - $('.js-gfm-input').atWho '@', (query, callback) -> + # Emoji + $input.atWho ':', + data: autocompleteEmoji.data, + tpl: autocompleteEmoji.template + + # Team Members + $input.atWho '@', (query, callback) -> (getMoreMembers = -> - $.getJSON(autocompleteMembersUrl, autocompleteMembersParams) - .success (members) -> - # pick the data we need - newMembersData = $.map members, (m) -> m.name + $.getJSON(autocompleteMembers.url, autocompleteMembers.params).success (members) -> + # pick the data we need + newMembersData = $.map members, (m) -> m.name - # add the new page of data to the rest - $.merge autocompleteMembersData, newMembersData + # add the new page of data to the rest + $.merge autocompleteMembers.data, newMembersData - # show the pop-up with a copy of the current data - callback autocompleteMembersData[..] + # show the pop-up with a copy of the current data + callback autocompleteMembers.data[..] - # are we past the last page? - if newMembersData.length == 0 - # set static data and stop callbacks - $('.js-gfm-input').atWho '@', - data: autocompleteMembersData - callback: null - else - # get next page - getMoreMembers() + # are we past the last page? + if newMembersData.length is 0 + # set static data and stop callbacks + $input.atWho '@', + data: autocompleteMembers.data + callback: null + else + # get next page + getMoreMembers() # so the next request gets the next page - autocompleteMembersParams.page += 1; - ).call(); + autocompleteMembers.params.page += 1 + ).call() diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 87a74655..9eadc18c 100644 --- a/app/views/layouts/_init_auto_complete.html.haml +++ b/app/views/layouts/_init_auto_complete.html.haml @@ -1,11 +1,11 @@ :javascript $(function() { - autocompleteMembersUrl = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; - autocompleteMembersParams.private_token = "#{current_user.authentication_token}"; + autocompleteMembers.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; + autocompleteMembers.params.private_token = "#{current_user.private_token}"; - autocompleteEmojiData = #{raw emoji_autocomplete_source}; + autocompleteEmoji.data = #{raw emoji_autocomplete_source}; // convert the list so that the items have the right format for completion - autocompleteEmojiData = $.map(autocompleteEmojiData, function(value) { + autocompleteEmoji.data = $.map(autocompleteEmoji.data, function(value) { return { name: value, insert: value+':', From 41ec5400336a55254716309738c6c4d523b6ce02 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Tue, 16 Oct 2012 04:41:49 -0700 Subject: [PATCH 012/122] remove unnecessary loader.js --- app/assets/javascripts/loader.js.coffee | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 app/assets/javascripts/loader.js.coffee diff --git a/app/assets/javascripts/loader.js.coffee b/app/assets/javascripts/loader.js.coffee deleted file mode 100644 index 66f8e8b1..00000000 --- a/app/assets/javascripts/loader.js.coffee +++ /dev/null @@ -1,5 +0,0 @@ -Loader = - html: (width) -> - $('').attr src: '/assets/ajax-loader.gif', width: width - -window.Loader = Loader From c28722689d54eb0a69c72e8258e189ccd8ce7964 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Tue, 16 Oct 2012 04:57:13 -0700 Subject: [PATCH 013/122] merge graph.js into projects.js --- app/assets/javascripts/graph.js.coffee | 10 ---------- app/assets/javascripts/projects.js.coffee | 7 +++++++ app/views/projects/graph.html.haml | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) delete mode 100644 app/assets/javascripts/graph.js.coffee diff --git a/app/assets/javascripts/graph.js.coffee b/app/assets/javascripts/graph.js.coffee deleted file mode 100644 index 5fe8ae3f..00000000 --- a/app/assets/javascripts/graph.js.coffee +++ /dev/null @@ -1,10 +0,0 @@ -initGraphNav = -> - $('.graph svg').css 'position', 'relative' - - $('body').bind 'keyup', (e) -> - if e.keyCode is 37 # left - $('.graph svg').animate left: '+=400' - else if e.keyCode is 39 # right - $('.graph svg').animate left: '-=400' - -window.initGraphNav = initGraphNav diff --git a/app/assets/javascripts/projects.js.coffee b/app/assets/javascripts/projects.js.coffee index 008fa8e9..3059723d 100644 --- a/app/assets/javascripts/projects.js.coffee +++ b/app/assets/javascripts/projects.js.coffee @@ -22,3 +22,10 @@ $ -> # Ref switcher $('.project-refs-select').on 'change', -> $(@).parents('form').submit() + +class @GraphNav + @init: -> + $('.graph svg').css 'position', 'relative' + $('body').bind 'keyup', (e) -> + $('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left + $('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right diff --git a/app/views/projects/graph.html.haml b/app/views/projects/graph.html.haml index 76ada998..07f038d2 100644 --- a/app/views/projects/graph.html.haml +++ b/app/views/projects/graph.html.haml @@ -10,5 +10,5 @@ initGraph(); $(function(){ branchGraph($("#holder")[0]); - initGraphNav(); + GraphNav.init(); }); From 414080cb0300e924ec2c994495349f4f93cdf1c4 Mon Sep 17 00:00:00 2001 From: Nihad Abbasov Date: Tue, 16 Oct 2012 05:09:09 -0700 Subject: [PATCH 014/122] remove unnecessary snippets.js --- app/assets/javascripts/snippets.js.coffee | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 app/assets/javascripts/snippets.js.coffee diff --git a/app/assets/javascripts/snippets.js.coffee b/app/assets/javascripts/snippets.js.coffee deleted file mode 100644 index af4385de..00000000 --- a/app/assets/javascripts/snippets.js.coffee +++ /dev/null @@ -1,6 +0,0 @@ -$ -> - $('#snippets-table .snippet').live 'click', (e) -> - if e.target.nodeName isnt 'A' and e.target.nodeName isnt 'INPUT' - location.href = $(@).attr 'url' - e.stopPropagation() - false From bd049e5e7c80259689eb4494a3e7eea4bd5a66b0 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 14:00:27 +0300 Subject: [PATCH 015/122] API:merge request show && list --- lib/api.rb | 1 + lib/api/entities.rb | 6 ++++++ lib/api/merge_requests.rb | 31 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 lib/api/merge_requests.rb diff --git a/lib/api.rb b/lib/api.rb index 2890a8cc..7a184544 100644 --- a/lib/api.rb +++ b/lib/api.rb @@ -18,5 +18,6 @@ module Gitlab mount Issues mount Milestones mount Session + mount MergeRequests end end diff --git a/lib/api/entities.rb b/lib/api/entities.rb index ee693de6..8c405f29 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -63,5 +63,11 @@ module Gitlab class SSHKey < Grape::Entity expose :id, :title, :key end + + class MergeRequest < Grape::Entity + expose :id, :target_branch, :source_branch, :project_id, + :title, :closed, :merged + expose :author, :assignee, using: Entities::UserBasic + end end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb new file mode 100644 index 00000000..12c9647b --- /dev/null +++ b/lib/api/merge_requests.rb @@ -0,0 +1,31 @@ +module Gitlab + # Issues API + class MergeRequests < Grape::API + before { authenticate! } + + resource :projects do + #list + get ":id/merge_requests" do + project = current_user.projects.find(params[:id]) + present project.merge_requests, with: Entities::MergeRequest + end + + #show + get ":id/merge_request/:merge_request_id" do + project = current_user.projects.find(params[:id]) + present project.merge_requests.find(params[:merge_request_id]), with: Entities::MergeRequest + end + + #create merge_request + post ":id/merge_requests" do + + end + + #update merge_request + put ":id/merge_request/:merge_request_id" do + + end + + end + end +end From fe59547ae5b272a183253c31e5273d52d0a02381 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 14:41:06 +0300 Subject: [PATCH 016/122] API: create merge request --- lib/api/merge_requests.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 12c9647b..fd741585 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -18,7 +18,17 @@ module Gitlab #create merge_request post ":id/merge_requests" do - + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title] + project = current_user.projects.find(params[:id]) + merge_request = project.merge_requests.new(attrs) + merge_request.author = current_user + + if merge_request.save + merge_request.reload_code + present merge_request, with: Entities::MergeRequest + else + not_found! + end end #update merge_request From 5a89934af8bd09d40c01c940b2305f95374be1bd Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 14:59:50 +0300 Subject: [PATCH 017/122] API: update merge request call --- lib/api/merge_requests.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index fd741585..92ff4937 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -33,7 +33,17 @@ module Gitlab #update merge_request put ":id/merge_request/:merge_request_id" do - + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :closed] + project = current_user.projects.find(params[:id]) + merge_request = project.merge_requests.find(params[:merge_request_id]) + + if merge_request.update_attributes attrs + merge_request.reload_code + merge_request.mark_as_unchecked + present merge_request, with: Entities::MergeRequest + else + not_found! + end end end From 524b907042c36d832b82d980c9fee85e6d92b6da Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 15:33:02 +0300 Subject: [PATCH 018/122] API: MergeRequest refactoring --- lib/api/merge_requests.rb | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 92ff4937..f1d8d6a9 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -6,21 +6,18 @@ module Gitlab resource :projects do #list get ":id/merge_requests" do - project = current_user.projects.find(params[:id]) - present project.merge_requests, with: Entities::MergeRequest + present user_project.merge_requests, with: Entities::MergeRequest end #show get ":id/merge_request/:merge_request_id" do - project = current_user.projects.find(params[:id]) - present project.merge_requests.find(params[:merge_request_id]), with: Entities::MergeRequest + present user_project.merge_requests.find(params[:merge_request_id]), with: Entities::MergeRequest end #create merge_request post ":id/merge_requests" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title] - project = current_user.projects.find(params[:id]) - merge_request = project.merge_requests.new(attrs) + merge_request = user_project.merge_requests.new(attrs) merge_request.author = current_user if merge_request.save @@ -34,8 +31,7 @@ module Gitlab #update merge_request put ":id/merge_request/:merge_request_id" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :closed] - project = current_user.projects.find(params[:id]) - merge_request = project.merge_requests.find(params[:merge_request_id]) + merge_request = user_project.merge_requests.find(params[:merge_request_id]) if merge_request.update_attributes attrs merge_request.reload_code From b32a8eea939930cd49141526b5fec19c747c561d Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 16:13:39 +0300 Subject: [PATCH 019/122] API: MergeRequest: authorization --- lib/api/merge_requests.rb | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index f1d8d6a9..14d9d92a 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -6,12 +6,18 @@ module Gitlab resource :projects do #list get ":id/merge_requests" do + authorize! :read_merge_request, user_project + present user_project.merge_requests, with: Entities::MergeRequest end #show get ":id/merge_request/:merge_request_id" do - present user_project.merge_requests.find(params[:merge_request_id]), with: Entities::MergeRequest + merge_request = user_project.merge_requests.find(params[:merge_request_id]) + + authorize! :read_merge_request, merge_request + + present merge_request, with: Entities::MergeRequest end #create merge_request @@ -20,6 +26,8 @@ module Gitlab merge_request = user_project.merge_requests.new(attrs) merge_request.author = current_user + authorize! :write_merge_request, merge_request + if merge_request.save merge_request.reload_code present merge_request, with: Entities::MergeRequest @@ -33,6 +41,8 @@ module Gitlab attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :closed] merge_request = user_project.merge_requests.find(params[:merge_request_id]) + authorize! :modify_merge_request, merge_request + if merge_request.update_attributes attrs merge_request.reload_code merge_request.mark_as_unchecked From 93e8d426c5efc21b73627110ebed08b82a7031ce Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 21 Oct 2012 19:48:56 +0300 Subject: [PATCH 020/122] API: merge request: post comment call --- lib/api/entities.rb | 5 +++++ lib/api/merge_requests.rb | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 8c405f29..5804e943 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -69,5 +69,10 @@ module Gitlab :title, :closed, :merged expose :author, :assignee, using: Entities::UserBasic end + + class Note < Grape::Entity + expose :author, using: Entities::UserBasic + expose :note + end end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 14d9d92a..1fd153d4 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -52,6 +52,18 @@ module Gitlab end end + #post comment to merge request + post ":id/merge_request/:merge_request_id/comments" do + merge_request = user_project.merge_requests.find(params[:merge_request_id]) + note = merge_request.notes.new(note: params[:note], project_id: user_project.id) + note.author = current_user + if note.save + present note, with: Entities::Note + else + not_found! + end + end + end end end From 6ffd2f3db61a9213677c765eb9f6e76e644a9a2f Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Mon, 22 Oct 2012 21:59:46 +0300 Subject: [PATCH 021/122] Changes after review --- lib/api/merge_requests.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 1fd153d4..e701339b 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -1,5 +1,5 @@ module Gitlab - # Issues API + # MergeRequest API class MergeRequests < Grape::API before { authenticate! } @@ -26,7 +26,7 @@ module Gitlab merge_request = user_project.merge_requests.new(attrs) merge_request.author = current_user - authorize! :write_merge_request, merge_request + authorize! :write_merge_request, user_project if merge_request.save merge_request.reload_code From 77bc1101074fe6458f0b0beaf19ef6663f735806 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Mon, 22 Oct 2012 22:53:06 +0300 Subject: [PATCH 022/122] API: help page and comment --- doc/api/merge_requests.md | 194 ++++++++++++++++++++++++++++++++++++++ lib/api/merge_requests.rb | 60 ++++++++++-- 2 files changed, 248 insertions(+), 6 deletions(-) create mode 100644 doc/api/merge_requests.md diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md new file mode 100644 index 00000000..2f7c93eb --- /dev/null +++ b/doc/api/merge_requests.md @@ -0,0 +1,194 @@ +## List merge requests + +Get all MR for this project. + +``` +GET /:id/merge_requests +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project + +```json +[ + { + "id":1, + "target_branch":"master", + "source_branch":"test1", + "project_id":3, + "title":"test1", + "closed":true, + "merged":false, + "author":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + }, + "assignee":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + } + } +] +``` + +## Show MR + +Show information about MR. + +``` +GET /:id/merge_request/:merge_request_id +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `merge_request_id` (required) - The ID of MR + +```json +{ + "id":1, + "target_branch":"master", + "source_branch":"test1", + "project_id":3, + "title":"test1", + "closed":true, + "merged":false, + "author":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + }, + "assignee":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + } +} +``` + + +## Create MR + +Create MR. + +``` +POST /:id/merge_requests +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `source_branch` (required) - The source branch ++ `target_branch` (required) - The target branch ++ `assignee_id` - Assignee user ID ++ `title` (required) - Title of MR + +```json +{ + "id":1, + "target_branch":"master", + "source_branch":"test1", + "project_id":3, + "title":"test1", + "closed":true, + "merged":false, + "author":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + }, + "assignee":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + } +} +``` + +## Update MR + +Update MR. You can change branches, title, or even close the MR. + +``` +PUT /:id/merge_request/:merge_request_id +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `merge_request_id` (required) - ID of MR ++ `source_branch` - The source branch ++ `target_branch` - The target branch ++ `assignee_id` - Assignee user ID ++ `title` - Title of MR ++ `closed` - Status of MR. true - closed + + +```json +{ + "id":1, + "target_branch":"master", + "source_branch":"test1", + "project_id":3, + "title":"test1", + "closed":true, + "merged":false, + "author":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + }, + "assignee":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + } +} +``` +## Post comment to MR + +Post comment to MR + +``` +POST /:id/merge_request/:merge_request_id/comments +``` + +Parameters: + ++ `id` (required) - The ID or code name of a project ++ `merge_request_id` (required) - ID of MR ++ `note` (required) - Text of comment + +Will return created note with status `201 Created` on success, or `404 Not found` on fail. + +```json +{ + "author":{ + "id":1, + "email":"admin@local.host", + "name":"Administrator", + "blocked":false, + "created_at":"2012-04-29T08:46:00Z" + }, + "note":"text1" +} +``` diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index e701339b..c9377ad2 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -4,14 +4,30 @@ module Gitlab before { authenticate! } resource :projects do - #list + + # List merge requests + # + # Parameters: + # id (required) - The ID or code name of a project + # + # Example: + # GET /:id/merge_requests + # get ":id/merge_requests" do authorize! :read_merge_request, user_project - present user_project.merge_requests, with: Entities::MergeRequest + present paginate(user_project.merge_requests), with: Entities::MergeRequest end - #show + # Show MR + # + # Parameters: + # id (required) - The ID or code name of a project + # merge_request_id (required) - The ID of MR + # + # Example: + # GET /:id/merge_request/:merge_request_id + # get ":id/merge_request/:merge_request_id" do merge_request = user_project.merge_requests.find(params[:merge_request_id]) @@ -20,7 +36,19 @@ module Gitlab present merge_request, with: Entities::MergeRequest end - #create merge_request + # Create MR + # + # Parameters: + # + # id (required) - The ID or code name of a project + # source_branch (required) - The source branch + # target_branch (required) - The target branch + # assignee_id - Assignee user ID + # title (required) - Title of MR + # + # Example: + # POST /:id/merge_requests + # post ":id/merge_requests" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title] merge_request = user_project.merge_requests.new(attrs) @@ -36,7 +64,19 @@ module Gitlab end end - #update merge_request + # Update MR + # + # Parameters: + # id (required) - The ID or code name of a project + # merge_request_id (required) - ID of MR + # source_branch - The source branch + # target_branch - The target branch + # assignee_id - Assignee user ID + # title - Title of MR + # closed - Status of MR. true - closed + # Example: + # PUT /:id/merge_request/:merge_request_id + # put ":id/merge_request/:merge_request_id" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :closed] merge_request = user_project.merge_requests.find(params[:merge_request_id]) @@ -52,7 +92,15 @@ module Gitlab end end - #post comment to merge request + # Post comment to merge request + # + # Parameters: + # id (required) - The ID or code name of a project + # merge_request_id (required) - ID of MR + # note (required) - Text of comment + # Examples: + # POST /:id/merge_request/:merge_request_id/comments + # post ":id/merge_request/:merge_request_id/comments" do merge_request = user_project.merge_requests.find(params[:merge_request_id]) note = merge_request.notes.new(note: params[:note], project_id: user_project.id) From bcd001f2953d7a358be02d74df1b00dace68648f Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Wed, 24 Oct 2012 16:45:18 +0200 Subject: [PATCH 023/122] Refer developers to the vagrant vm and remove out of date documentation. --- CONTRIBUTING.md | 22 +++++++++------------- doc/development.md | 43 +++++++++++++++++-------------------------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b87ac4c..5f831446 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -## Contribute to GitLab +## Contribute to GitLab If you want to contribute to GitLab, follow this process: @@ -7,24 +7,20 @@ If you want to contribute to GitLab, follow this process: 3. Code 4. Create a pull request -We will only accept pull requests if: +We will only accept pull requests if: * Your code has proper tests and all tests pass -* Your code can be merged w/o problems +* Your code can be merged w/o problems * It won't break existing functionality * It's quality code * We like it :) -## [You may need a developer VM](https://github.com/gitlabhq/developer-vm) +For examples of feedback on pull requests please look at the [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed). + +## Installation + +Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing. ## Running tests -To run the specs for GitLab, you need to run seeds for test db. - - cd gitlabhq - rake db:seed_fu RAILS_ENV=test - -Then you can run the test suite with rake: - - rake gitlab:test - +For more information on running the tests please read the [development tips](https://github.com/gitlabhq/gitlabhq/blob/master/doc/development.md) diff --git a/doc/development.md b/doc/development.md index 67bcb8e1..ef6a9b02 100644 --- a/doc/development.md +++ b/doc/development.md @@ -1,45 +1,36 @@ -## Development tips: +## Development tips: + + +### Installation + +Install the Gitlab development in a virtual machine with the [Gitlab Vagrant virtual machine](https://github.com/gitlabhq/gitlab-vagrant-vm). Installing it in a virtual machine makes it much easier to set up all the dependencies for integration testing. + ### Start application in development mode -#### 1. Via foreman - - bundle exec foreman -p 3000 - -#### 2. Via gitlab cli +#### 1. Via gitlab cli ./gitlab start -#### 3. Manually +#### 2. Manually - bundle exec rails s - bundle exec rake environment resque:work QUEUE=* VVERBOSE=1 + bundle exec rails s + bundle exec rake environment resque:work QUEUE=* VVERBOSE=1 -### Run tests: - -#### 1. Packages - - # ubuntu - sudo apt-get install libqt4-dev libqtwebkit-dev - sudo apt-get install xvfb - - # Mac - brew install qt - brew install xvfb - -#### 2. DB & seeds +### Test DB seutup & seed bundle exec rake db:setup RAILS_ENV=test bundle exec rake db:seed_fu RAILS_ENV=test -### 3. Run Tests + +### Run the Tests # All in one bundle exec rake gitlab:test - - # Rspec + + # Rspec bundle exec rake spec - + # Spinach bundle exec rake spinach From 2335d7b9cf577fb03ed4efc660b8e3e706c1c01b Mon Sep 17 00:00:00 2001 From: Scott Holden Date: Wed, 24 Oct 2012 21:54:15 -0700 Subject: [PATCH 024/122] Fix broken Note scopes with lambdas, 4.0 compat Without lambdas, Date.today will be evaluated in the class body. For it to have a running scope of last week etc, it will need to be evaluated each time the scope is called. In Rails 4.0, lambdas will be required for all scopes, so not a bad idea to go ahead and change them all now. --- app/models/note.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/note.rb b/app/models/note.rb index e2f4a89d..d7701c38 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -23,13 +23,13 @@ class Note < ActiveRecord::Base mount_uploader :attachment, AttachmentUploader # Scopes - scope :common, where(noteable_id: nil) - scope :today, where("created_at >= :date", date: Date.today) - scope :last_week, where("created_at >= :date", date: (Date.today - 7.days)) + scope :common, ->{ where(noteable_id: nil) } + scope :today, ->{ where("created_at >= :date", date: Date.today) } + scope :last_week, ->{ where("created_at >= :date", date: (Date.today - 7.days)) } scope :since, ->(day) { where("created_at >= :date", date: (day)) } - scope :fresh, order("created_at ASC, id ASC") - scope :inc_author_project, includes(:project, :author) - scope :inc_author, includes(:author) + scope :fresh, ->{ order("created_at ASC, id ASC") } + scope :inc_author_project, ->{ includes(:project, :author) } + scope :inc_author, ->{ includes(:author) } def self.create_status_change_note(noteable, author, status) create({ From 8f3adf9f03465c8610800a63e7d7e05adea36e29 Mon Sep 17 00:00:00 2001 From: randx Date: Wed, 24 Oct 2012 20:42:55 +0300 Subject: [PATCH 025/122] Improved installation manual --- doc/installation.md | 258 ++++++++++++++++++++++++-------------------- 1 file changed, 143 insertions(+), 115 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index b04a324d..de388fdf 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -30,14 +30,6 @@ We recommend to use server with at least 1GB RAM for gitlab instance. ## This installation guide created for Debian/Ubuntu and properly tested. -The installation consists of 6 steps: - -1. Install packages / dependencies -2. Install ruby -3. Install Gitolite -4. Install and configure GitLab. -5. Start the web front-end -6. Start a Resque worker (for background processing) ### IMPORTANT @@ -47,6 +39,26 @@ Only create a GitHub Issue if you want a specific part of this installation guid Also read the [Read this before you submit an issue](https://github.com/gitlabhq/gitlabhq/wiki/Read-this-before-you-submit-an-issue) wiki page. + +# Basic setup + +The basic installation will provide you a GitLab setup with options: + +1. ruby 1.9.3 +2. mysql as main db +3. gitolite v3 fork by gitlab +4. nginx + unicorn + +The installation consists of next steps: + +1. Install packages / dependencies +2. Install ruby +3. Install Gitolite +4. Install mysql and create db +5. Install and configure GitLab. +6. nginx + unicorn +7. service gitlab + > - - - > The first 3 steps of this guide can be easily skipped by executing an install script: > @@ -65,6 +77,7 @@ Also read the [Read this before you submit an issue](https://github.com/gitlabhq > for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) > - - - + # 1. Install packages *Keep in mind that `sudo` is not installed on Debian by default. You should install it as root:* @@ -78,54 +91,6 @@ Now install the required packages: sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix libpq-dev - -# Database - -## SQLite - - sudo apt-get install -y sqlite3 libsqlite3-dev - -## MySQL - - sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev - - # Login to MySQL - $ mysql -u root -p - - # Create the GitLab production database - mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; - - # Create the MySQL User change $password to a real password - mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; - - # Grant proper permissions to the MySQL User - mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; - - -## PostgreSQL - - sudo apt-get install -y postgresql-9.2 postgresql-server-dev-9.2 - - # Connect to database server - sudo -u postgres psql -d template1 - - # Add a user called gitlab. Change $password to a real password - template1=# CREATE USER gitlab WITH PASSWORD '$password'; - - # Create the GitLab production database - template1=# CREATE DATABASE IF NOT EXISTS gitlabhq_production; - - # Grant all privileges on database - template1=# GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab; - - # Quit from PostgreSQL server - template1=# \q - - # Try connect to new database - $ su - gitlab - $ psql -d gitlabhq_production -U gitlab - - # 2. Install Ruby wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz @@ -201,7 +166,25 @@ Permissions: Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) and ensure you have followed all of the above steps carefully. -# 4. Clone GitLab source and install prerequisites + +# 4. Mysql database + + sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + + # Login to MySQL + $ mysql -u root -p + + # Create the GitLab production database + mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; + + # Create the MySQL User change $password to a real password + mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; + + # Grant proper permissions to the MySQL User + mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; + + +# 5. Clone GitLab source and install prerequisites sudo gem install charlock_holmes --version '0.6.8' sudo pip install pygments @@ -220,30 +203,15 @@ and ensure you have followed all of the above steps carefully. # Rename config files sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml -#### Select the database you want to use - - # SQLite - sudo -u gitlab cp config/database.yml.sqlite config/database.yml - - # Mysql - sudo -u gitlab cp config/database.yml.mysql config/database.yml - - # PostgreSQL - sudo -u gitlab cp config/database.yml.postgres config/database.yml - + # Copy mysql db config # make sure to update username/password in config/database.yml + sudo -u gitlab cp config/database.yml.mysql config/database.yml #### Install gems # mysql sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment - # or postgres - sudo -u gitlab -H bundle install --without development test sqlite mysql --deployment - - # or sqlite - sudo -u gitlab -H bundle install --without development test mysql postgres --deployment - #### Setup database sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production @@ -277,49 +245,12 @@ Checking status: If you got all YES - congratulations! You can go to the next step. -# 5. Start the web server - -Application can be started with next command: - - # For test purposes - sudo -u gitlab bundle exec rails s -e production - - # As daemon - sudo -u gitlab bundle exec rails s -e production -d - -You can login via web using admin generated with setup: - - admin@local.host - 5iveL!fe - -# 6. Run Resque process (for processing job queue). - - # Manually - sudo -u gitlab bundle exec rake environment resque:work QUEUE=* RAILS_ENV=production BACKGROUND=yes - - # GitLab start script - sudo -u gitlab ./resque.sh - # if you run this as root /home/gitlab/gitlab/tmp/pids/resque_worker.pid will be owned by root - # causing the resque worker not to start via init script on next boot/service restart - -## Customizing Resque's Redis connection - -If you'd like Resque to connect to a Redis server on a non-standard port or on -a different host, you can configure its connection string in the -**config/resque.yml** file: - - production: redis.example.com:6379 - -**Ok - we have a working application now. ** -**But keep going - there are some things that should be done ** - -# Nginx && Unicorn +# 6. nginx + unicorn ## 1. Unicorn cd /home/gitlab/gitlab sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb - sudo -u gitlab bundle exec unicorn_rails -c config/unicorn.rb -E production -D ## 2. Nginx @@ -338,7 +269,9 @@ a different host, you can configure its connection string in the # Restart nginx: sudo /etc/init.d/nginx restart -## 3. Init script + + +# 7. service gitlab Create init script in /etc/init.d/gitlab: @@ -349,6 +282,101 @@ GitLab autostart: sudo update-rc.d gitlab defaults 21 -Now you can start/restart/stop GitLab like: +Now you can start GitLab like: - sudo /etc/init.d/gitlab restart + sudo service gitlab start + + +You can login via web using admin generated with setup: + + admin@local.host + 5iveL!fe + + + +# Advanced setup tips: + + +## Customizing Resque's Redis connection + +If you'd like Resque to connect to a Redis server on a non-standard port or on +a different host, you can configure its connection string in the +**config/resque.yml** file: + + production: redis.example.com:6379 + +**Ok - we have a working application now. ** +**But keep going - there are some things that should be done ** + + +# Database + +## SQLite + + sudo apt-get install -y sqlite3 libsqlite3-dev + +## MySQL + + sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + + # Login to MySQL + $ mysql -u root -p + + # Create the GitLab production database + mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; + + # Create the MySQL User change $password to a real password + mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; + + # Grant proper permissions to the MySQL User + mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; + + +## PostgreSQL + + sudo apt-get install -y postgresql-9.2 postgresql-server-dev-9.2 + + # Connect to database server + sudo -u postgres psql -d template1 + + # Add a user called gitlab. Change $password to a real password + template1=# CREATE USER gitlab WITH PASSWORD '$password'; + + # Create the GitLab production database + template1=# CREATE DATABASE IF NOT EXISTS gitlabhq_production; + + # Grant all privileges on database + template1=# GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab; + + # Quit from PostgreSQL server + template1=# \q + + # Try connect to new database + $ su - gitlab + $ psql -d gitlabhq_production -U gitlab + + + +#### Select the database you want to use + + # SQLite + sudo -u gitlab cp config/database.yml.sqlite config/database.yml + + # Mysql + sudo -u gitlab cp config/database.yml.mysql config/database.yml + + # PostgreSQL + sudo -u gitlab cp config/database.yml.postgres config/database.yml + + # make sure to update username/password in config/database.yml + +#### Install gems + + # mysql + sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment + + # or postgres + sudo -u gitlab -H bundle install --without development test sqlite mysql --deployment + + # or sqlite + sudo -u gitlab -H bundle install --without development test mysql postgres --deployment From c8fe07ed322eaa2f6d093d73d8c9ae6b36dbd758 Mon Sep 17 00:00:00 2001 From: randx Date: Wed, 24 Oct 2012 20:50:34 +0300 Subject: [PATCH 026/122] version 2 --- doc/installation.md | 91 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index de388fdf..7a88165e 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -51,31 +51,12 @@ The basic installation will provide you a GitLab setup with options: The installation consists of next steps: -1. Install packages / dependencies -2. Install ruby -3. Install Gitolite -4. Install mysql and create db -5. Install and configure GitLab. -6. nginx + unicorn -7. service gitlab - -> - - - -> The first 3 steps of this guide can be easily skipped by executing an install script: -> -> # Install curl and sudo -> apt-get install curl sudo -> -> # 3 steps in 1 command :) -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh | sh -> -> Now you can go to [Step 4](#4-install-gitlab-and-configuration-check-status-configuration) -> -> Or if you are installing on Amazon Web Services using Ubuntu 12.04 you can do all steps (1 to 6) at once with: -> -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu_aws.sh | sh -> -> for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) -> - - - +1. packages / dependencies +2. ruby +3. gitolite +4. mysql +5. GitLab. +6. nginx # 1. Install packages @@ -216,6 +197,11 @@ and ensure you have followed all of the above steps carefully. sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production +#### Copy unicorn config + + cd /home/gitlab/gitlab + sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb + #### Setup GitLab hooks sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive @@ -243,16 +229,25 @@ Checking status: UMASK for .gitolite.rc is 0007? ............YES /home/git/share/gitolite/hooks/common/post-receive exists? ............YES -If you got all YES - congratulations! You can go to the next step. +If you got all YES - congratulations! You can run a GitLab app. -# 6. nginx + unicorn +### init script -## 1. Unicorn +Create init script in /etc/init.d/gitlab: - cd /home/gitlab/gitlab - sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb + sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/ + sudo chmod +x /etc/init.d/gitlab -## 2. Nginx +GitLab autostart: + + sudo update-rc.d gitlab defaults 21 + +### Now you should start GitLab application: + + sudo service gitlab start + + +# 7. Nginx # Install first sudo apt-get install nginx @@ -270,22 +265,7 @@ If you got all YES - congratulations! You can go to the next step. sudo /etc/init.d/nginx restart - -# 7. service gitlab - -Create init script in /etc/init.d/gitlab: - - sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/ - sudo chmod +x /etc/init.d/gitlab - -GitLab autostart: - - sudo update-rc.d gitlab defaults 21 - -Now you can start GitLab like: - - sudo service gitlab start - +# Done! Visit **YOUR_SERVER_FQDN** for gitlab instance You can login via web using admin generated with setup: @@ -296,6 +276,23 @@ You can login via web using admin generated with setup: # Advanced setup tips: +> - - - +> The first 3 steps of this guide can be easily skipped by executing an install script: +> +> # Install curl and sudo +> apt-get install curl sudo +> +> # 3 steps in 1 command :) +> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh | sh +> +> Now you can go to [Step 4](#4-install-gitlab-and-configuration-check-status-configuration) +> +> Or if you are installing on Amazon Web Services using Ubuntu 12.04 you can do all steps (1 to 6) at once with: +> +> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu_aws.sh | sh +> +> for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) +> - - - ## Customizing Resque's Redis connection From 5ff6fadcc1fc4588485d34a06c7e27d8b6f302c4 Mon Sep 17 00:00:00 2001 From: randx Date: Wed, 24 Oct 2012 20:59:48 +0300 Subject: [PATCH 027/122] refactor installation doc --- doc/installation.md | 52 ++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index 7a88165e..fe09f5ea 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -51,12 +51,13 @@ The basic installation will provide you a GitLab setup with options: The installation consists of next steps: -1. packages / dependencies -2. ruby -3. gitolite -4. mysql -5. GitLab. -6. nginx +1. Packages / dependencies +2. Ruby +3. Users +4. Gitolite +5. Mysql +6. GitLab. +7. Nginx # 1. Install packages @@ -72,6 +73,9 @@ Now install the required packages: sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix libpq-dev + sudo pip install pygments + + # 2. Install Ruby wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz @@ -81,7 +85,7 @@ Now install the required packages: make sudo make install -# 3. Install Gitolite +# 3. Users Create user for git: @@ -111,6 +115,9 @@ Generate key: sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa + +# 4. Gitolite + Clone GitLab's fork of the Gitolite source code: sudo -H -u git git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite @@ -134,8 +141,6 @@ Permissions: sudo chmod -R g+rwX /home/git/repositories/ sudo chown -R git:git /home/git/repositories/ -#### CHECK: Logout & login again to apply git group to your user - # clone admin repo to add localhost to known_hosts # & be sure your user has access to gitolite sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin @@ -148,7 +153,7 @@ Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wik and ensure you have followed all of the above steps carefully. -# 4. Mysql database +# 5. Mysql database sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev @@ -165,13 +170,13 @@ and ensure you have followed all of the above steps carefully. mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; -# 5. Clone GitLab source and install prerequisites +# 6. GitLab - sudo gem install charlock_holmes --version '0.6.8' - sudo pip install pygments - sudo gem install bundler cd /home/gitlab + +#### Get source code + # Get gitlab code. Use this for stable setup sudo -H -u gitlab git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab @@ -179,6 +184,9 @@ and ensure you have followed all of the above steps carefully. # Master branch (recent changes, less stable) sudo -H -u gitlab git clone -b master https://github.com/gitlabhq/gitlabhq.git gitlab + +#### Copy configs + cd gitlab # Rename config files @@ -190,16 +198,18 @@ and ensure you have followed all of the above steps carefully. #### Install gems - # mysql + cd /home/gitlab/gitlab + + sudo gem install charlock_holmes --version '0.6.8' + sudo gem install bundler sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment -#### Setup database +#### Setup application sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production #### Copy unicorn config - cd /home/gitlab/gitlab sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb #### Setup GitLab hooks @@ -231,7 +241,7 @@ Checking status: If you got all YES - congratulations! You can run a GitLab app. -### init script +#### init script Create init script in /etc/init.d/gitlab: @@ -242,7 +252,7 @@ GitLab autostart: sudo update-rc.d gitlab defaults 21 -### Now you should start GitLab application: +#### Now you should start GitLab application: sudo service gitlab start @@ -276,6 +286,9 @@ You can login via web using admin generated with setup: # Advanced setup tips: + +## Quick setup + > - - - > The first 3 steps of this guide can be easily skipped by executing an install script: > @@ -294,6 +307,7 @@ You can login via web using admin generated with setup: > for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) > - - - + ## Customizing Resque's Redis connection If you'd like Resque to connect to a Redis server on a non-standard port or on From fd86bf4ae9ccfaab6cf4dfba38de6c7e0b80ec9f Mon Sep 17 00:00:00 2001 From: randx Date: Thu, 25 Oct 2012 11:13:11 +0300 Subject: [PATCH 028/122] Decouple requirements and install --- doc/databases.md | 75 ++++++++++++++++++++++++++ doc/installation.md | 126 +++++--------------------------------------- doc/requirements.md | 28 ++++++++++ 3 files changed, 117 insertions(+), 112 deletions(-) create mode 100644 doc/databases.md create mode 100644 doc/requirements.md diff --git a/doc/databases.md b/doc/databases.md new file mode 100644 index 00000000..8ca3d8fe --- /dev/null +++ b/doc/databases.md @@ -0,0 +1,75 @@ +# Databases: + +GitLab use mysql as default database but you are free to use PostgreSQL or SQLite. + + +## SQLite + + sudo apt-get install -y sqlite3 libsqlite3-dev + +## MySQL + + sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + + # Login to MySQL + $ mysql -u root -p + + # Create the GitLab production database + mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; + + # Create the MySQL User change $password to a real password + mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; + + # Grant proper permissions to the MySQL User + mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; + + +## PostgreSQL + + sudo apt-get install -y postgresql-9.2 postgresql-server-dev-9.2 + + # Connect to database server + sudo -u postgres psql -d template1 + + # Add a user called gitlab. Change $password to a real password + template1=# CREATE USER gitlab WITH PASSWORD '$password'; + + # Create the GitLab production database + template1=# CREATE DATABASE IF NOT EXISTS gitlabhq_production; + + # Grant all privileges on database + template1=# GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab; + + # Quit from PostgreSQL server + template1=# \q + + # Try connect to new database + $ su - gitlab + $ psql -d gitlabhq_production -U gitlab + + + +#### Select the database you want to use + + # SQLite + sudo -u gitlab cp config/database.yml.sqlite config/database.yml + + # Mysql + sudo -u gitlab cp config/database.yml.mysql config/database.yml + + # PostgreSQL + sudo -u gitlab cp config/database.yml.postgres config/database.yml + + # make sure to update username/password in config/database.yml + +#### Install gems + + # mysql + sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment + + # or postgres + sudo -u gitlab -H bundle install --without development test sqlite mysql --deployment + + # or sqlite + sudo -u gitlab -H bundle install --without development test mysql postgres --deployment + diff --git a/doc/installation.md b/doc/installation.md index fe09f5ea..9030d9ea 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -1,35 +1,6 @@ -## Platform requirements: - -**The project is designed for the Linux operating system.** - -It may work on FreeBSD and Mac OS, but we don't test our application for these systems and can't guarantee stability and full functionality. - -We officially support (recent versions of) these Linux distributions: - -- Ubuntu Linux -- Debian/GNU Linux - -It should work on: - -- Fedora -- CentOs -- RedHat - -You might have some luck using these, but no guarantees: - - - MacOS X - - FreeBSD - -GitLab does **not** run on Windows and we have no plans of making GitLab compatible. - - -## Hardware: - -We recommend to use server with at least 1GB RAM for gitlab instance. - - -## This installation guide created for Debian/Ubuntu and properly tested. +_This installation guide created for Debian/Ubuntu and properly tested._ +_Checkout requirements before setup_ ### IMPORTANT @@ -39,6 +10,7 @@ Only create a GitHub Issue if you want a specific part of this installation guid Also read the [Read this before you submit an issue](https://github.com/gitlabhq/gitlabhq/wiki/Read-this-before-you-submit-an-issue) wiki page. +- - - # Basic setup @@ -103,12 +75,9 @@ Create user for GitLab: # ubuntu/debian sudo adduser --disabled-login --gecos 'gitlab system' gitlab -Add your user to the `git` group: +Add your users to groups: sudo usermod -a -G git gitlab - -Add `git` user to `gitlab` group: - sudo usermod -a -G gitlab git Generate key: @@ -190,12 +159,19 @@ and ensure you have followed all of the above steps carefully. cd gitlab # Rename config files + # sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml # Copy mysql db config + # # make sure to update username/password in config/database.yml + # sudo -u gitlab cp config/database.yml.mysql config/database.yml + # Copy unicorn config + # + sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb + #### Install gems cd /home/gitlab/gitlab @@ -208,9 +184,6 @@ and ensure you have followed all of the above steps carefully. sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production -#### Copy unicorn config - - sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb #### Setup GitLab hooks @@ -275,7 +248,7 @@ GitLab autostart: sudo /etc/init.d/nginx restart -# Done! Visit **YOUR_SERVER_FQDN** for gitlab instance +# Done! Visit YOUR_SERVER for gitlab instance You can login via web using admin generated with setup: @@ -283,6 +256,8 @@ You can login via web using admin generated with setup: 5iveL!fe +- - - + # Advanced setup tips: @@ -318,76 +293,3 @@ a different host, you can configure its connection string in the **Ok - we have a working application now. ** **But keep going - there are some things that should be done ** - - -# Database - -## SQLite - - sudo apt-get install -y sqlite3 libsqlite3-dev - -## MySQL - - sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev - - # Login to MySQL - $ mysql -u root -p - - # Create the GitLab production database - mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; - - # Create the MySQL User change $password to a real password - mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; - - # Grant proper permissions to the MySQL User - mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; - - -## PostgreSQL - - sudo apt-get install -y postgresql-9.2 postgresql-server-dev-9.2 - - # Connect to database server - sudo -u postgres psql -d template1 - - # Add a user called gitlab. Change $password to a real password - template1=# CREATE USER gitlab WITH PASSWORD '$password'; - - # Create the GitLab production database - template1=# CREATE DATABASE IF NOT EXISTS gitlabhq_production; - - # Grant all privileges on database - template1=# GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab; - - # Quit from PostgreSQL server - template1=# \q - - # Try connect to new database - $ su - gitlab - $ psql -d gitlabhq_production -U gitlab - - - -#### Select the database you want to use - - # SQLite - sudo -u gitlab cp config/database.yml.sqlite config/database.yml - - # Mysql - sudo -u gitlab cp config/database.yml.mysql config/database.yml - - # PostgreSQL - sudo -u gitlab cp config/database.yml.postgres config/database.yml - - # make sure to update username/password in config/database.yml - -#### Install gems - - # mysql - sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment - - # or postgres - sudo -u gitlab -H bundle install --without development test sqlite mysql --deployment - - # or sqlite - sudo -u gitlab -H bundle install --without development test mysql postgres --deployment diff --git a/doc/requirements.md b/doc/requirements.md new file mode 100644 index 00000000..955f99a5 --- /dev/null +++ b/doc/requirements.md @@ -0,0 +1,28 @@ +## Platform requirements: + +**The project is designed for the Linux operating system.** + +It may work on FreeBSD and Mac OS, but we don't test our application for these systems and can't guarantee stability and full functionality. + +We officially support (recent versions of) these Linux distributions: + +- Ubuntu Linux +- Debian/GNU Linux + +It should work on: + +- Fedora +- CentOs +- RedHat + +You might have some luck using these, but no guarantees: + + - MacOS X + - FreeBSD + +GitLab does **not** run on Windows and we have no plans of making GitLab compatible. + + +## Hardware: + +We recommend to use server with at least 1GB RAM for gitlab instance. From f9def67981f34c843124b71823c6b1f41cf529e6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 25 Oct 2012 11:49:31 +0300 Subject: [PATCH 029/122] move installation docs under separate dir --- doc/README_FOR_APP | 2 - doc/install/:w | 295 ++++++++++++++++++++++++++++++ doc/{ => install}/databases.md | 0 doc/{ => install}/installation.md | 3 +- doc/{ => install}/requirements.md | 0 5 files changed, 297 insertions(+), 3 deletions(-) delete mode 100644 doc/README_FOR_APP create mode 100644 doc/install/:w rename doc/{ => install}/databases.md (100%) rename doc/{ => install}/installation.md (99%) rename doc/{ => install}/requirements.md (100%) diff --git a/doc/README_FOR_APP b/doc/README_FOR_APP deleted file mode 100644 index fe41f5cc..00000000 --- a/doc/README_FOR_APP +++ /dev/null @@ -1,2 +0,0 @@ -Use this README file to introduce your application and point to useful places in the API for learning more. -Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. diff --git a/doc/install/:w b/doc/install/:w new file mode 100644 index 00000000..9bc0c211 --- /dev/null +++ b/doc/install/:w @@ -0,0 +1,295 @@ +_This installation guide created for Debian/Ubuntu and properly tested._ + +_Checkout requirements before setup_ + +### IMPORTANT + +Please make sure you have followed all the steps below before posting to the mailing list with installation and configuration questions. + +Only create a GitHub Issue if you want a specific part of this installation guide updated. + +Also read the [Read this before you submit an issue](https://github.com/gitlabhq/gitlabhq/wiki/Read-this-before-you-submit-an-issue) wiki page. + +- - - + +# Basic setup + +The basic installation will provide you a GitLab setup with options: + +1. ruby 1.9.3 +2. mysql as main db +3. gitolite v3 fork by gitlab +4. nginx + unicorn + +The installation consists of next steps: + +1. Packages / dependencies +2. Ruby +3. Users +4. Gitolite +5. Mysql +6. GitLab. +7. Nginx + + +# 1. Packages / dependencies + +*Keep in mind that `sudo` is not installed on Debian by default. You should install it as root:* + + apt-get update && apt-get upgrade && apt-get install sudo + +Now install the required packages: + + sudo apt-get update + sudo apt-get upgrade + + sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix libpq-dev + + sudo pip install pygments + + +# 2. Install Ruby + + wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz + tar xfvz ruby-1.9.3-p194.tar.gz + cd ruby-1.9.3-p194 + ./configure + make + sudo make install + +# 3. Users + +Create user for git: + + sudo adduser \ + --system \ + --shell /bin/sh \ + --gecos 'git version control' \ + --group \ + --disabled-password \ + --home /home/git \ + git + +Create user for GitLab: + + # ubuntu/debian + sudo adduser --disabled-login --gecos 'gitlab system' gitlab + +Add your users to groups: + + sudo usermod -a -G git gitlab + sudo usermod -a -G gitlab git + +Generate key: + + sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa + + +# 4. Gitolite + +Clone GitLab's fork of the Gitolite source code: + + sudo -H -u git git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite + +Setup: + + cd /home/git + sudo -u git -H mkdir bin + sudo -u git sh -c 'echo -e "PATH=\$PATH:/home/git/bin\nexport PATH" >> /home/git/.profile' + sudo -u git sh -c 'gitolite/install -ln /home/git/bin' + + sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub + sudo chmod 0444 /home/git/gitlab.pub + + sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" + sudo -u git -H sed -i 's/0077/0007/g' /home/git/.gitolite.rc + sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\1'\.\*'/g" /home/git/.gitolite.rc + +Permissions: + + sudo chmod -R g+rwX /home/git/repositories/ + sudo chown -R git:git /home/git/repositories/ + + # clone admin repo to add localhost to known_hosts + # & be sure your user has access to gitolite + sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin + + # if succeed you can remove it + sudo rm -rf /tmp/gitolite-admin + +**IMPORTANT! If you can't clone `gitolite-admin` repository - DO NOT PROCEED WITH INSTALLATION** +Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) +and ensure you have followed all of the above steps carefully. + + +# 5. Mysql database + + sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + + # Login to MySQL + $ mysql -u root -p + + # Create the GitLab production database + mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; + + # Create the MySQL User change $password to a real password + mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; + + # Grant proper permissions to the MySQL User + mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; + + +# 6. GitLab + + cd /home/gitlab + + +#### Get source code + + # Get gitlab code. Use this for stable setup + sudo -H -u gitlab git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab + + # Skip this for stable setup. + # Master branch (recent changes, less stable) + sudo -H -u gitlab git clone -b master https://github.com/gitlabhq/gitlabhq.git gitlab + + +#### Copy configs + + cd gitlab + + # Rename config files + # + sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml + + # Copy mysql db config + # + # make sure to update username/password in config/database.yml + # + sudo -u gitlab cp config/database.yml.mysql config/database.yml + + # Copy unicorn config + # + sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb + +#### Install gems + + cd /home/gitlab/gitlab + + sudo gem install charlock_holmes --version '0.6.8' + sudo gem install bundler + sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment + +#### Setup application + + sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production + + +#### Setup GitLab hooks + + sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive + sudo chown git:git /home/git/.gitolite/hooks/common/post-receive + +#### Check application status + +Checking status: + + sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production + + + # OUTPUT EXAMPLE + Starting diagnostic + config/database.yml............exists + config/gitlab.yml............exists + /home/git/repositories/............exists + /home/git/repositories/ is writable?............YES + remote: Counting objects: 603, done. + remote: Compressing objects: 100% (466/466), done. + remote: Total 603 (delta 174), reused 0 (delta 0) + Receiving objects: 100% (603/603), 53.29 KiB, done. + Resolving deltas: 100% (174/174), done. + Can clone gitolite-admin?............YES + UMASK for .gitolite.rc is 0007? ............YES + /home/git/share/gitolite/hooks/common/post-receive exists? ............YES + +If you got all YES - congratulations! You can run a GitLab app. + +#### init script + +Create init script in /etc/init.d/gitlab: + + sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/ + sudo chmod +x /etc/init.d/gitlab + +GitLab autostart: + + sudo update-rc.d gitlab defaults 21 + +#### Now you should start GitLab application: + + sudo service gitlab start + + +# 7. Nginx + + # Install first + sudo apt-get install nginx + + # Add GitLab to nginx sites & change with your host specific settings + sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab -P /etc/nginx/sites-available/ + sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab + + # Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN** + # to the IP address and fully-qualified domain name + # of the host serving GitLab. + sudo vim /etc/nginx/sites-enabled/gitlab + + # Restart nginx: + sudo /etc/init.d/nginx restart + + +# Done! Visit YOUR_SERVER for gitlab instance + +You can login via web using admin generated with setup: + + admin@local.host + 5iveL!fe + + +- - - + + +# Advanced setup tips: + + +## Quick setup + +> - - - +> The first 3 steps of this guide can be easily skipped by executing an install script: +> +> # Install curl and sudo +> apt-get install curl sudo +> +> # 3 steps in 1 command :) +> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh | sh +> +> Now you can go to [Step 4](#4-install-gitlab-and-configuration-check-status-configuration) +> +> Or if you are installing on Amazon Web Services using Ubuntu 12.04 you can do all steps (1 to 6) at once with: +> +> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu_aws.sh | sh +> +> for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) +> - - - + + +## Customizing Resque's Redis connection + +If you'd like Resque to connect to a Redis server on a non-standard port or on +a different host, you can configure its connection string in the +**config/resque.yml** file: + + production: redis.example.com:6379 + +**Ok - we have a working application now. ** +**But keep going - there are some things that should be done ** diff --git a/doc/databases.md b/doc/install/databases.md similarity index 100% rename from doc/databases.md rename to doc/install/databases.md diff --git a/doc/installation.md b/doc/install/installation.md similarity index 99% rename from doc/installation.md rename to doc/install/installation.md index 9030d9ea..5e631288 100644 --- a/doc/installation.md +++ b/doc/install/installation.md @@ -2,6 +2,7 @@ _This installation guide created for Debian/Ubuntu and properly tested._ _Checkout requirements before setup_ + ### IMPORTANT Please make sure you have followed all the steps below before posting to the mailing list with installation and configuration questions. @@ -32,7 +33,7 @@ The installation consists of next steps: 7. Nginx -# 1. Install packages +# 1. Packages / dependencies *Keep in mind that `sudo` is not installed on Debian by default. You should install it as root:* diff --git a/doc/requirements.md b/doc/install/requirements.md similarity index 100% rename from doc/requirements.md rename to doc/install/requirements.md From 03f43291cdf60c6a185383d7d218fd87196d6231 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 25 Oct 2012 11:52:34 +0300 Subject: [PATCH 030/122] Remove easy script cause its should be improved --- doc/install/:w | 295 ------------------------------------ doc/install/installation.md | 22 +-- 2 files changed, 1 insertion(+), 316 deletions(-) delete mode 100644 doc/install/:w diff --git a/doc/install/:w b/doc/install/:w deleted file mode 100644 index 9bc0c211..00000000 --- a/doc/install/:w +++ /dev/null @@ -1,295 +0,0 @@ -_This installation guide created for Debian/Ubuntu and properly tested._ - -_Checkout requirements before setup_ - -### IMPORTANT - -Please make sure you have followed all the steps below before posting to the mailing list with installation and configuration questions. - -Only create a GitHub Issue if you want a specific part of this installation guide updated. - -Also read the [Read this before you submit an issue](https://github.com/gitlabhq/gitlabhq/wiki/Read-this-before-you-submit-an-issue) wiki page. - -- - - - -# Basic setup - -The basic installation will provide you a GitLab setup with options: - -1. ruby 1.9.3 -2. mysql as main db -3. gitolite v3 fork by gitlab -4. nginx + unicorn - -The installation consists of next steps: - -1. Packages / dependencies -2. Ruby -3. Users -4. Gitolite -5. Mysql -6. GitLab. -7. Nginx - - -# 1. Packages / dependencies - -*Keep in mind that `sudo` is not installed on Debian by default. You should install it as root:* - - apt-get update && apt-get upgrade && apt-get install sudo - -Now install the required packages: - - sudo apt-get update - sudo apt-get upgrade - - sudo apt-get install -y wget curl gcc checkinstall libxml2-dev libxslt-dev libcurl4-openssl-dev libreadline6-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server openssh-server git-core python-dev python-pip libyaml-dev postfix libpq-dev - - sudo pip install pygments - - -# 2. Install Ruby - - wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz - tar xfvz ruby-1.9.3-p194.tar.gz - cd ruby-1.9.3-p194 - ./configure - make - sudo make install - -# 3. Users - -Create user for git: - - sudo adduser \ - --system \ - --shell /bin/sh \ - --gecos 'git version control' \ - --group \ - --disabled-password \ - --home /home/git \ - git - -Create user for GitLab: - - # ubuntu/debian - sudo adduser --disabled-login --gecos 'gitlab system' gitlab - -Add your users to groups: - - sudo usermod -a -G git gitlab - sudo usermod -a -G gitlab git - -Generate key: - - sudo -H -u gitlab ssh-keygen -q -N '' -t rsa -f /home/gitlab/.ssh/id_rsa - - -# 4. Gitolite - -Clone GitLab's fork of the Gitolite source code: - - sudo -H -u git git clone -b gl-v304 https://github.com/gitlabhq/gitolite.git /home/git/gitolite - -Setup: - - cd /home/git - sudo -u git -H mkdir bin - sudo -u git sh -c 'echo -e "PATH=\$PATH:/home/git/bin\nexport PATH" >> /home/git/.profile' - sudo -u git sh -c 'gitolite/install -ln /home/git/bin' - - sudo cp /home/gitlab/.ssh/id_rsa.pub /home/git/gitlab.pub - sudo chmod 0444 /home/git/gitlab.pub - - sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" - sudo -u git -H sed -i 's/0077/0007/g' /home/git/.gitolite.rc - sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\1'\.\*'/g" /home/git/.gitolite.rc - -Permissions: - - sudo chmod -R g+rwX /home/git/repositories/ - sudo chown -R git:git /home/git/repositories/ - - # clone admin repo to add localhost to known_hosts - # & be sure your user has access to gitolite - sudo -u gitlab -H git clone git@localhost:gitolite-admin.git /tmp/gitolite-admin - - # if succeed you can remove it - sudo rm -rf /tmp/gitolite-admin - -**IMPORTANT! If you can't clone `gitolite-admin` repository - DO NOT PROCEED WITH INSTALLATION** -Check the [Trouble Shooting Guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) -and ensure you have followed all of the above steps carefully. - - -# 5. Mysql database - - sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev - - # Login to MySQL - $ mysql -u root -p - - # Create the GitLab production database - mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`; - - # Create the MySQL User change $password to a real password - mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; - - # Grant proper permissions to the MySQL User - mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `gitlabhq_production`.* TO 'gitlab'@'localhost'; - - -# 6. GitLab - - cd /home/gitlab - - -#### Get source code - - # Get gitlab code. Use this for stable setup - sudo -H -u gitlab git clone -b stable https://github.com/gitlabhq/gitlabhq.git gitlab - - # Skip this for stable setup. - # Master branch (recent changes, less stable) - sudo -H -u gitlab git clone -b master https://github.com/gitlabhq/gitlabhq.git gitlab - - -#### Copy configs - - cd gitlab - - # Rename config files - # - sudo -u gitlab cp config/gitlab.yml.example config/gitlab.yml - - # Copy mysql db config - # - # make sure to update username/password in config/database.yml - # - sudo -u gitlab cp config/database.yml.mysql config/database.yml - - # Copy unicorn config - # - sudo -u gitlab cp config/unicorn.rb.example config/unicorn.rb - -#### Install gems - - cd /home/gitlab/gitlab - - sudo gem install charlock_holmes --version '0.6.8' - sudo gem install bundler - sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment - -#### Setup application - - sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production - - -#### Setup GitLab hooks - - sudo cp ./lib/hooks/post-receive /home/git/.gitolite/hooks/common/post-receive - sudo chown git:git /home/git/.gitolite/hooks/common/post-receive - -#### Check application status - -Checking status: - - sudo -u gitlab bundle exec rake gitlab:app:status RAILS_ENV=production - - - # OUTPUT EXAMPLE - Starting diagnostic - config/database.yml............exists - config/gitlab.yml............exists - /home/git/repositories/............exists - /home/git/repositories/ is writable?............YES - remote: Counting objects: 603, done. - remote: Compressing objects: 100% (466/466), done. - remote: Total 603 (delta 174), reused 0 (delta 0) - Receiving objects: 100% (603/603), 53.29 KiB, done. - Resolving deltas: 100% (174/174), done. - Can clone gitolite-admin?............YES - UMASK for .gitolite.rc is 0007? ............YES - /home/git/share/gitolite/hooks/common/post-receive exists? ............YES - -If you got all YES - congratulations! You can run a GitLab app. - -#### init script - -Create init script in /etc/init.d/gitlab: - - sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab -P /etc/init.d/ - sudo chmod +x /etc/init.d/gitlab - -GitLab autostart: - - sudo update-rc.d gitlab defaults 21 - -#### Now you should start GitLab application: - - sudo service gitlab start - - -# 7. Nginx - - # Install first - sudo apt-get install nginx - - # Add GitLab to nginx sites & change with your host specific settings - sudo wget https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab -P /etc/nginx/sites-available/ - sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab - - # Change **YOUR_SERVER_IP** and **YOUR_SERVER_FQDN** - # to the IP address and fully-qualified domain name - # of the host serving GitLab. - sudo vim /etc/nginx/sites-enabled/gitlab - - # Restart nginx: - sudo /etc/init.d/nginx restart - - -# Done! Visit YOUR_SERVER for gitlab instance - -You can login via web using admin generated with setup: - - admin@local.host - 5iveL!fe - - -- - - - - -# Advanced setup tips: - - -## Quick setup - -> - - - -> The first 3 steps of this guide can be easily skipped by executing an install script: -> -> # Install curl and sudo -> apt-get install curl sudo -> -> # 3 steps in 1 command :) -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh | sh -> -> Now you can go to [Step 4](#4-install-gitlab-and-configuration-check-status-configuration) -> -> Or if you are installing on Amazon Web Services using Ubuntu 12.04 you can do all steps (1 to 6) at once with: -> -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu_aws.sh | sh -> -> for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) -> - - - - - -## Customizing Resque's Redis connection - -If you'd like Resque to connect to a Redis server on a non-standard port or on -a different host, you can configure its connection string in the -**config/resque.yml** file: - - production: redis.example.com:6379 - -**Ok - we have a working application now. ** -**But keep going - there are some things that should be done ** diff --git a/doc/install/installation.md b/doc/install/installation.md index 5e631288..b9b82a72 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -262,27 +262,7 @@ You can login via web using admin generated with setup: # Advanced setup tips: - -## Quick setup - -> - - - -> The first 3 steps of this guide can be easily skipped by executing an install script: -> -> # Install curl and sudo -> apt-get install curl sudo -> -> # 3 steps in 1 command :) -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu.sh | sh -> -> Now you can go to [Step 4](#4-install-gitlab-and-configuration-check-status-configuration) -> -> Or if you are installing on Amazon Web Services using Ubuntu 12.04 you can do all steps (1 to 6) at once with: -> -> curl https://raw.github.com/gitlabhq/gitlab-recipes/master/install/debian_ubuntu_aws.sh | sh -> -> for more detailed instructions read the HOWTO section of [the script](https://github.com/gitlabhq/gitlab-recipes/blob/master/install/debian_ubuntu_aws.sh) -> - - - - +_Checkout databases.md for postgres or sqlite_ ## Customizing Resque's Redis connection From 1ea0dd0ffc37232d27f4fa1350af6ebb3b5439f2 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 25 Oct 2012 11:59:41 +0300 Subject: [PATCH 031/122] App docs --- doc/app/Ability.html | 570 ++++++ doc/app/Account.html | 881 +++++++++ doc/app/ActivityObserver.html | 531 +++++ doc/app/Admin.html | 432 ++++ doc/app/Admin/DashboardController.html | 488 +++++ doc/app/Admin/GroupsController.html | 771 ++++++++ doc/app/Admin/HooksController.html | 603 ++++++ doc/app/Admin/LogsController.html | 439 +++++ doc/app/Admin/ProjectsController.html | 733 +++++++ doc/app/Admin/ResqueController.html | 484 +++++ doc/app/Admin/TeamMembersController.html | 558 ++++++ doc/app/Admin/UsersController.html | 839 ++++++++ doc/app/AdminController.html | 490 +++++ doc/app/ApplicationController.html | 1015 ++++++++++ doc/app/ApplicationDecorator.html | 439 +++++ doc/app/ApplicationHelper.html | 1018 ++++++++++ doc/app/AttachmentUploader.html | 486 +++++ doc/app/Authority.html | 782 ++++++++ doc/app/BaseContext.html | 605 ++++++ doc/app/BlameController.html | 500 +++++ doc/app/BlobController.html | 519 +++++ doc/app/Commit.html | 1191 +++++++++++ doc/app/CommitController.html | 509 +++++ doc/app/CommitDecorator.html | 663 +++++++ doc/app/CommitLoadContext.html | 513 +++++ doc/app/CommitsController.html | 507 +++++ doc/app/CommitsHelper.html | 625 ++++++ doc/app/CompareController.html | 556 ++++++ doc/app/DashboardController.html | 569 ++++++ doc/app/DeployKeysController.html | 626 ++++++ doc/app/ErrorsController.html | 485 +++++ doc/app/Event.html | 1222 ++++++++++++ doc/app/EventDecorator.html | 578 ++++++ doc/app/EventsHelper.html | 566 ++++++ doc/app/ExtractsPath.html | 614 ++++++ doc/app/ExtractsPath/InvalidPathError.html | 441 +++++ doc/app/FileSizeValidator.html | 652 ++++++ doc/app/FileSizeValidator/Helper.html | 455 +++++ doc/app/GitHost.html | 479 +++++ doc/app/Gitlab.html | 454 +++++ doc/app/Gitlab/API.html | 452 +++++ doc/app/Gitlab/APIHelpers.html | 846 ++++++++ doc/app/Gitlab/AppLogger.html | 523 +++++ doc/app/Gitlab/Auth.html | 630 ++++++ doc/app/Gitlab/Encode.html | 537 +++++ doc/app/Gitlab/Entities.html | 433 ++++ doc/app/Gitlab/Entities/Hook.html | 439 +++++ doc/app/Gitlab/Entities/Issue.html | 439 +++++ doc/app/Gitlab/Entities/Milestone.html | 439 +++++ doc/app/Gitlab/Entities/Project.html | 439 +++++ doc/app/Gitlab/Entities/ProjectMember.html | 439 +++++ doc/app/Gitlab/Entities/ProjectSnippet.html | 439 +++++ doc/app/Gitlab/Entities/RepoCommit.html | 439 +++++ doc/app/Gitlab/Entities/RepoObject.html | 439 +++++ doc/app/Gitlab/Entities/SSHKey.html | 439 +++++ doc/app/Gitlab/Entities/User.html | 439 +++++ doc/app/Gitlab/Entities/UserBasic.html | 439 +++++ doc/app/Gitlab/Entities/UserLogin.html | 439 +++++ doc/app/Gitlab/FileEditor.html | 647 ++++++ doc/app/Gitlab/GitLogger.html | 523 +++++ doc/app/Gitlab/Gitolite.html | 716 +++++++ doc/app/Gitlab/Gitolite/AccessDenied.html | 439 +++++ doc/app/Gitlab/GitoliteConfig.html | 994 ++++++++++ doc/app/Gitlab/GitoliteConfig/PullError.html | 439 +++++ doc/app/Gitlab/GitoliteConfig/PushError.html | 439 +++++ doc/app/Gitlab/GraphCommit.html | 967 +++++++++ doc/app/Gitlab/InlineDiff.html | 611 ++++++ doc/app/Gitlab/Issues.html | 441 +++++ doc/app/Gitlab/Logger.html | 583 ++++++ doc/app/Gitlab/Markdown.html | 580 ++++++ doc/app/Gitlab/Merge.html | 628 ++++++ doc/app/Gitlab/Milestones.html | 441 +++++ doc/app/Gitlab/Projects.html | 441 +++++ doc/app/Gitlab/Satellite.html | 664 +++++++ doc/app/Gitlab/Session.html | 441 +++++ doc/app/Gitlab/Theme.html | 493 +++++ doc/app/Gitlab/Users.html | 441 +++++ doc/app/GitlabMarkdownHelper.html | 559 ++++++ doc/app/Grack.html | 433 ++++ doc/app/Grack/Auth.html | 734 +++++++ doc/app/Group.html | 555 ++++++ doc/app/GroupsController.html | 735 +++++++ doc/app/HelpController.html | 484 +++++ doc/app/HooksController.html | 595 ++++++ doc/app/Issue.html | 501 +++++ doc/app/IssueCommonality.html | 641 ++++++ doc/app/IssueCommonality/ClassMethods.html | 479 +++++ doc/app/IssueObserver.html | 571 ++++++ doc/app/IssuesBulkUpdateContext.html | 503 +++++ doc/app/IssuesController.html | 996 ++++++++++ doc/app/IssuesHelper.html | 698 +++++++ doc/app/IssuesListContext.html | 537 +++++ doc/app/Key.html | 700 +++++++ doc/app/KeyObserver.html | 530 +++++ doc/app/KeysController.html | 624 ++++++ doc/app/LabelsController.html | 523 +++++ doc/app/MergeRequest.html | 1478 ++++++++++++++ doc/app/MergeRequestObserver.html | 569 ++++++ doc/app/MergeRequestsController.html | 1114 +++++++++++ doc/app/MergeRequestsHelper.html | 599 ++++++ doc/app/MergeRequestsLoadContext.html | 496 +++++ doc/app/Milestone.html | 589 ++++++ doc/app/MilestonesController.html | 816 ++++++++ doc/app/Note.html | 777 ++++++++ doc/app/NoteObserver.html | 603 ++++++ doc/app/Notes.html | 434 ++++ doc/app/Notes/CreateContext.html | 490 +++++ doc/app/Notes/LoadContext.html | 513 +++++ doc/app/NotesController.html | 636 ++++++ doc/app/NotesHelper.html | 581 ++++++ doc/app/Notify.html | 883 +++++++++ doc/app/OmniauthCallbacksController.html | 527 +++++ doc/app/PostReceive.html | 495 +++++ doc/app/ProfileController.html | 683 +++++++ doc/app/ProfileHelper.html | 481 +++++ doc/app/Project.html | 1202 +++++++++++ doc/app/ProjectHook.html | 439 +++++ doc/app/ProjectObserver.html | 589 ++++++ doc/app/ProjectResourceController.html | 439 +++++ doc/app/ProjectsController.html | 785 ++++++++ doc/app/ProjectsHelper.html | 543 +++++ doc/app/ProtectedBranch.html | 529 +++++ doc/app/ProtectedBranchesController.html | 556 ++++++ doc/app/PushEvent.html | 1105 +++++++++++ doc/app/PushObserver.html | 699 +++++++ doc/app/Redcarpet.html | 432 ++++ doc/app/Redcarpet/Render.html | 432 ++++ doc/app/Redcarpet/Render/GitlabHTML.html | 594 ++++++ doc/app/RefsController.html | 638 ++++++ doc/app/RepositoriesController.html | 593 ++++++ doc/app/Repository.html | 1566 +++++++++++++++ doc/app/SearchContext.html | 599 ++++++ doc/app/SearchController.html | 489 +++++ doc/app/Snippet.html | 667 +++++++ doc/app/SnippetsController.html | 833 ++++++++ doc/app/SnippetsHelper.html | 485 +++++ doc/app/StaticModel.html | 648 ++++++ doc/app/StaticModel/ClassMethods.html | 511 +++++ doc/app/SystemHook.html | 525 +++++ doc/app/SystemHookObserver.html | 573 ++++++ doc/app/SystemHookWorker.html | 485 +++++ doc/app/TabHelper.html | 621 ++++++ doc/app/TagsHelper.html | 516 +++++ doc/app/Team.html | 710 +++++++ doc/app/TeamMembersController.html | 698 +++++++ doc/app/TestHookContext.html | 488 +++++ doc/app/Tree.html | 663 +++++++ doc/app/TreeController.html | 583 ++++++ doc/app/TreeDecorator.html | 597 ++++++ doc/app/TreeHelper.html | 736 +++++++ doc/app/User.html | 755 +++++++ doc/app/UserObserver.html | 557 ++++++ doc/app/UsersProject.html | 904 +++++++++ doc/app/UsersProjectObserver.html | 558 ++++++ doc/app/Votes.html | 615 ++++++ doc/app/WebHook.html | 506 +++++ doc/app/Wiki.html | 567 ++++++ doc/app/WikisController.html | 676 +++++++ doc/app/created.rid | 135 ++ doc/app/doc/README_FOR_APP.html | 399 ++++ doc/app/images/add.png | Bin 0 -> 733 bytes doc/app/images/brick.png | Bin 0 -> 452 bytes doc/app/images/brick_link.png | Bin 0 -> 764 bytes doc/app/images/bug.png | Bin 0 -> 774 bytes doc/app/images/bullet_black.png | Bin 0 -> 211 bytes doc/app/images/bullet_toggle_minus.png | Bin 0 -> 207 bytes doc/app/images/bullet_toggle_plus.png | Bin 0 -> 209 bytes doc/app/images/date.png | Bin 0 -> 626 bytes doc/app/images/delete.png | Bin 0 -> 715 bytes doc/app/images/find.png | Bin 0 -> 659 bytes doc/app/images/loadingAnimation.gif | Bin 0 -> 5886 bytes doc/app/images/macFFBgHack.png | Bin 0 -> 207 bytes doc/app/images/package.png | Bin 0 -> 853 bytes doc/app/images/page_green.png | Bin 0 -> 621 bytes doc/app/images/page_white_text.png | Bin 0 -> 342 bytes doc/app/images/page_white_width.png | Bin 0 -> 309 bytes doc/app/images/plugin.png | Bin 0 -> 591 bytes doc/app/images/ruby.png | Bin 0 -> 592 bytes doc/app/images/tag_blue.png | Bin 0 -> 1880 bytes doc/app/images/tag_green.png | Bin 0 -> 613 bytes doc/app/images/transparent.png | Bin 0 -> 97 bytes doc/app/images/wrench.png | Bin 0 -> 610 bytes doc/app/images/wrench_orange.png | Bin 0 -> 584 bytes doc/app/images/zoom.png | Bin 0 -> 692 bytes doc/app/index.html | 392 ++++ doc/app/js/darkfish.js | 153 ++ doc/app/js/jquery.js | 18 + doc/app/js/navigation.js | 142 ++ doc/app/js/search.js | 94 + doc/app/js/search_index.js | 1 + doc/app/js/searcher.js | 228 +++ doc/app/rdoc.css | 543 +++++ doc/app/table_of_contents.html | 1858 ++++++++++++++++++ 193 files changed, 100336 insertions(+) create mode 100644 doc/app/Ability.html create mode 100644 doc/app/Account.html create mode 100644 doc/app/ActivityObserver.html create mode 100644 doc/app/Admin.html create mode 100644 doc/app/Admin/DashboardController.html create mode 100644 doc/app/Admin/GroupsController.html create mode 100644 doc/app/Admin/HooksController.html create mode 100644 doc/app/Admin/LogsController.html create mode 100644 doc/app/Admin/ProjectsController.html create mode 100644 doc/app/Admin/ResqueController.html create mode 100644 doc/app/Admin/TeamMembersController.html create mode 100644 doc/app/Admin/UsersController.html create mode 100644 doc/app/AdminController.html create mode 100644 doc/app/ApplicationController.html create mode 100644 doc/app/ApplicationDecorator.html create mode 100644 doc/app/ApplicationHelper.html create mode 100644 doc/app/AttachmentUploader.html create mode 100644 doc/app/Authority.html create mode 100644 doc/app/BaseContext.html create mode 100644 doc/app/BlameController.html create mode 100644 doc/app/BlobController.html create mode 100644 doc/app/Commit.html create mode 100644 doc/app/CommitController.html create mode 100644 doc/app/CommitDecorator.html create mode 100644 doc/app/CommitLoadContext.html create mode 100644 doc/app/CommitsController.html create mode 100644 doc/app/CommitsHelper.html create mode 100644 doc/app/CompareController.html create mode 100644 doc/app/DashboardController.html create mode 100644 doc/app/DeployKeysController.html create mode 100644 doc/app/ErrorsController.html create mode 100644 doc/app/Event.html create mode 100644 doc/app/EventDecorator.html create mode 100644 doc/app/EventsHelper.html create mode 100644 doc/app/ExtractsPath.html create mode 100644 doc/app/ExtractsPath/InvalidPathError.html create mode 100644 doc/app/FileSizeValidator.html create mode 100644 doc/app/FileSizeValidator/Helper.html create mode 100644 doc/app/GitHost.html create mode 100644 doc/app/Gitlab.html create mode 100644 doc/app/Gitlab/API.html create mode 100644 doc/app/Gitlab/APIHelpers.html create mode 100644 doc/app/Gitlab/AppLogger.html create mode 100644 doc/app/Gitlab/Auth.html create mode 100644 doc/app/Gitlab/Encode.html create mode 100644 doc/app/Gitlab/Entities.html create mode 100644 doc/app/Gitlab/Entities/Hook.html create mode 100644 doc/app/Gitlab/Entities/Issue.html create mode 100644 doc/app/Gitlab/Entities/Milestone.html create mode 100644 doc/app/Gitlab/Entities/Project.html create mode 100644 doc/app/Gitlab/Entities/ProjectMember.html create mode 100644 doc/app/Gitlab/Entities/ProjectSnippet.html create mode 100644 doc/app/Gitlab/Entities/RepoCommit.html create mode 100644 doc/app/Gitlab/Entities/RepoObject.html create mode 100644 doc/app/Gitlab/Entities/SSHKey.html create mode 100644 doc/app/Gitlab/Entities/User.html create mode 100644 doc/app/Gitlab/Entities/UserBasic.html create mode 100644 doc/app/Gitlab/Entities/UserLogin.html create mode 100644 doc/app/Gitlab/FileEditor.html create mode 100644 doc/app/Gitlab/GitLogger.html create mode 100644 doc/app/Gitlab/Gitolite.html create mode 100644 doc/app/Gitlab/Gitolite/AccessDenied.html create mode 100644 doc/app/Gitlab/GitoliteConfig.html create mode 100644 doc/app/Gitlab/GitoliteConfig/PullError.html create mode 100644 doc/app/Gitlab/GitoliteConfig/PushError.html create mode 100644 doc/app/Gitlab/GraphCommit.html create mode 100644 doc/app/Gitlab/InlineDiff.html create mode 100644 doc/app/Gitlab/Issues.html create mode 100644 doc/app/Gitlab/Logger.html create mode 100644 doc/app/Gitlab/Markdown.html create mode 100644 doc/app/Gitlab/Merge.html create mode 100644 doc/app/Gitlab/Milestones.html create mode 100644 doc/app/Gitlab/Projects.html create mode 100644 doc/app/Gitlab/Satellite.html create mode 100644 doc/app/Gitlab/Session.html create mode 100644 doc/app/Gitlab/Theme.html create mode 100644 doc/app/Gitlab/Users.html create mode 100644 doc/app/GitlabMarkdownHelper.html create mode 100644 doc/app/Grack.html create mode 100644 doc/app/Grack/Auth.html create mode 100644 doc/app/Group.html create mode 100644 doc/app/GroupsController.html create mode 100644 doc/app/HelpController.html create mode 100644 doc/app/HooksController.html create mode 100644 doc/app/Issue.html create mode 100644 doc/app/IssueCommonality.html create mode 100644 doc/app/IssueCommonality/ClassMethods.html create mode 100644 doc/app/IssueObserver.html create mode 100644 doc/app/IssuesBulkUpdateContext.html create mode 100644 doc/app/IssuesController.html create mode 100644 doc/app/IssuesHelper.html create mode 100644 doc/app/IssuesListContext.html create mode 100644 doc/app/Key.html create mode 100644 doc/app/KeyObserver.html create mode 100644 doc/app/KeysController.html create mode 100644 doc/app/LabelsController.html create mode 100644 doc/app/MergeRequest.html create mode 100644 doc/app/MergeRequestObserver.html create mode 100644 doc/app/MergeRequestsController.html create mode 100644 doc/app/MergeRequestsHelper.html create mode 100644 doc/app/MergeRequestsLoadContext.html create mode 100644 doc/app/Milestone.html create mode 100644 doc/app/MilestonesController.html create mode 100644 doc/app/Note.html create mode 100644 doc/app/NoteObserver.html create mode 100644 doc/app/Notes.html create mode 100644 doc/app/Notes/CreateContext.html create mode 100644 doc/app/Notes/LoadContext.html create mode 100644 doc/app/NotesController.html create mode 100644 doc/app/NotesHelper.html create mode 100644 doc/app/Notify.html create mode 100644 doc/app/OmniauthCallbacksController.html create mode 100644 doc/app/PostReceive.html create mode 100644 doc/app/ProfileController.html create mode 100644 doc/app/ProfileHelper.html create mode 100644 doc/app/Project.html create mode 100644 doc/app/ProjectHook.html create mode 100644 doc/app/ProjectObserver.html create mode 100644 doc/app/ProjectResourceController.html create mode 100644 doc/app/ProjectsController.html create mode 100644 doc/app/ProjectsHelper.html create mode 100644 doc/app/ProtectedBranch.html create mode 100644 doc/app/ProtectedBranchesController.html create mode 100644 doc/app/PushEvent.html create mode 100644 doc/app/PushObserver.html create mode 100644 doc/app/Redcarpet.html create mode 100644 doc/app/Redcarpet/Render.html create mode 100644 doc/app/Redcarpet/Render/GitlabHTML.html create mode 100644 doc/app/RefsController.html create mode 100644 doc/app/RepositoriesController.html create mode 100644 doc/app/Repository.html create mode 100644 doc/app/SearchContext.html create mode 100644 doc/app/SearchController.html create mode 100644 doc/app/Snippet.html create mode 100644 doc/app/SnippetsController.html create mode 100644 doc/app/SnippetsHelper.html create mode 100644 doc/app/StaticModel.html create mode 100644 doc/app/StaticModel/ClassMethods.html create mode 100644 doc/app/SystemHook.html create mode 100644 doc/app/SystemHookObserver.html create mode 100644 doc/app/SystemHookWorker.html create mode 100644 doc/app/TabHelper.html create mode 100644 doc/app/TagsHelper.html create mode 100644 doc/app/Team.html create mode 100644 doc/app/TeamMembersController.html create mode 100644 doc/app/TestHookContext.html create mode 100644 doc/app/Tree.html create mode 100644 doc/app/TreeController.html create mode 100644 doc/app/TreeDecorator.html create mode 100644 doc/app/TreeHelper.html create mode 100644 doc/app/User.html create mode 100644 doc/app/UserObserver.html create mode 100644 doc/app/UsersProject.html create mode 100644 doc/app/UsersProjectObserver.html create mode 100644 doc/app/Votes.html create mode 100644 doc/app/WebHook.html create mode 100644 doc/app/Wiki.html create mode 100644 doc/app/WikisController.html create mode 100644 doc/app/created.rid create mode 100644 doc/app/doc/README_FOR_APP.html create mode 100755 doc/app/images/add.png create mode 100644 doc/app/images/brick.png create mode 100644 doc/app/images/brick_link.png create mode 100644 doc/app/images/bug.png create mode 100644 doc/app/images/bullet_black.png create mode 100644 doc/app/images/bullet_toggle_minus.png create mode 100644 doc/app/images/bullet_toggle_plus.png create mode 100644 doc/app/images/date.png create mode 100755 doc/app/images/delete.png create mode 100644 doc/app/images/find.png create mode 100644 doc/app/images/loadingAnimation.gif create mode 100644 doc/app/images/macFFBgHack.png create mode 100644 doc/app/images/package.png create mode 100644 doc/app/images/page_green.png create mode 100644 doc/app/images/page_white_text.png create mode 100644 doc/app/images/page_white_width.png create mode 100644 doc/app/images/plugin.png create mode 100644 doc/app/images/ruby.png create mode 100755 doc/app/images/tag_blue.png create mode 100644 doc/app/images/tag_green.png create mode 100644 doc/app/images/transparent.png create mode 100644 doc/app/images/wrench.png create mode 100644 doc/app/images/wrench_orange.png create mode 100644 doc/app/images/zoom.png create mode 100644 doc/app/index.html create mode 100644 doc/app/js/darkfish.js create mode 100644 doc/app/js/jquery.js create mode 100644 doc/app/js/navigation.js create mode 100644 doc/app/js/search.js create mode 100644 doc/app/js/search_index.js create mode 100644 doc/app/js/searcher.js create mode 100644 doc/app/rdoc.css create mode 100644 doc/app/table_of_contents.html diff --git a/doc/app/Ability.html b/doc/app/Ability.html new file mode 100644 index 00000000..f780d067 --- /dev/null +++ b/doc/app/Ability.html @@ -0,0 +1,570 @@ + + + + + + +class Ability - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Ability

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + allowed(object, subject) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/ability.rb, line 3
    +def allowed(object, subject)
    +  case subject.class.name
    +  when "Project" then project_abilities(object, subject)
    +  when "Issue" then issue_abilities(object, subject)
    +  when "Note" then note_abilities(object, subject)
    +  when "Snippet" then snippet_abilities(object, subject)
    +  when "MergeRequest" then merge_request_abilities(object, subject)
    +  else []
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_abilities(user, project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/ability.rb, line 14
    +def project_abilities(user, project)
    +  rules = []
    +
    +  rules << [
    +    :read_project,
    +    :read_wiki,
    +    :read_issue,
    +    :read_milestone,
    +    :read_snippet,
    +    :read_team_member,
    +    :read_merge_request,
    +    :read_note,
    +    :write_project,
    +    :write_issue,
    +    :write_note
    +  ] if project.guest_access_for?(user)
    +
    +  rules << [
    +    :download_code,
    +    :write_merge_request,
    +    :write_snippet
    +  ] if project.report_access_for?(user)
    +
    +  rules << [
    +    :write_wiki,
    +    :push_code
    +  ] if project.dev_access_for?(user)
    +
    +  rules << [
    +    :push_code_to_protected_branches
    +  ] if project.master_access_for?(user)
    +
    +  rules << [
    +    :modify_issue,
    +    :modify_snippet,
    +    :modify_merge_request,
    +    :admin_project,
    +    :admin_issue,
    +    :admin_milestone,
    +    :admin_snippet,
    +    :admin_team_member,
    +    :admin_merge_request,
    +    :admin_note,
    +    :accept_mr,
    +    :admin_wiki
    +  ] if project.master_access_for?(user) || project.owner == user
    +
    +  rules.flatten
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Account.html b/doc/app/Account.html new file mode 100644 index 00000000..58f65758 --- /dev/null +++ b/doc/app/Account.html @@ -0,0 +1,881 @@ + + + + + + +module Account - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Account

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + block() + click to toggle source +
    + + +
    + +

    Remove user from all projects and set blocked attribute to true

    + + + +
    +
    # File app/roles/account.rb, line 47
    +def block
    +  users_projects.find_each do |membership|
    +    return false unless membership.destroy
    +  end
    +
    +  self.blocked = true
    +  save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can_create_group?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 25
    +def can_create_group?
    +  is_admin?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can_create_project?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 21
    +def can_create_project?
    +  projects_limit > my_own_projects.count
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + cared_merge_requests() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 37
    +def cared_merge_requests
    +  MergeRequest.where("author_id = :id or assignee_id = :id", id: self.id).opened
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + first_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 33
    +def first_name
    +  name.split.first unless name.blank?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + identifier() + click to toggle source +
    + + +
    + +

    Returns a string for use as a Gitolite user identifier

    + +

    Note that Gitolite 2.x requires the following +pattern for users:

    + +
    ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
    + + + +
    +
    # File app/roles/account.rb, line 7
    +def identifier
    +  # Replace non-word chars with underscores, then make sure it starts with
    +  # valid chars
    +  email.gsub(%r\W/, '_').gsub(%r\A([\W\_])+/, '')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_admin?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 13
    +def is_admin?
    +  admin
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_activity_project() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 29
    +def last_activity_project
    +  projects.first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_ids() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 41
    +def project_ids
    +  projects.map(&:id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + projects_limit_percent() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 56
    +def projects_limit_percent
    +  return 100 if projects_limit.zero?
    +  (my_own_projects.count.to_f / projects_limit) * 100
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + projects_with_events() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 70
    +def projects_with_events
    +  projects.includes(:events).order("events.created_at DESC")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + recent_push(project_id = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 61
    +def recent_push project_id = nil
    +  # Get push events not earlier than 2 hours ago
    +  events = recent_events.code_push.where("created_at > ?", Time.now - 2.hours)
    +  events = events.where(project_id: project_id) if project_id
    +
    +  # Take only latest one
    +  events = events.recent.limit(1).first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + require_ssh_key?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/account.rb, line 17
    +def require_ssh_key?
    +  keys.count == 0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ActivityObserver.html b/doc/app/ActivityObserver.html new file mode 100644 index 00000000..3b31271d --- /dev/null +++ b/doc/app/ActivityObserver.html @@ -0,0 +1,531 @@ + + + + + + +class ActivityObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ActivityObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(record) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/activity_observer.rb, line 4
    +def after_create(record)
    +  Event.create(
    +    project: record.project,
    +    target_id: record.id,
    +    target_type: record.class.name,
    +    action: Event.determine_action(record),
    +    author_id: record.author_id
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_save(record) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/activity_observer.rb, line 14
    +def after_save(record)
    +  if record.changed.include?("closed") 
    +    Event.create(
    +      project: record.project,
    +      target_id: record.id,
    +      target_type: record.class.name,
    +      action: (record.closed ? Event::Closed : Event::Reopened),
    +      author_id: record.author_id_of_changes
    +    )
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin.html b/doc/app/Admin.html new file mode 100644 index 00000000..94fb27ef --- /dev/null +++ b/doc/app/Admin.html @@ -0,0 +1,432 @@ + + + + + + +module Admin - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Admin

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Admin/DashboardController.html b/doc/app/Admin/DashboardController.html new file mode 100644 index 00000000..00154b3d --- /dev/null +++ b/doc/app/Admin/DashboardController.html @@ -0,0 +1,488 @@ + + + + + + +class Admin::DashboardController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::DashboardController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/dashboard_controller.rb, line 2
    +def index
    +  @workers = Resque.workers
    +  @pending_jobs = Resque.size(:post_receive)
    +  @projects = Project.order("created_at DESC").limit(10)
    +  @users = User.order("created_at DESC").limit(10)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/GroupsController.html b/doc/app/Admin/GroupsController.html new file mode 100644 index 00000000..ef4dae9e --- /dev/null +++ b/doc/app/Admin/GroupsController.html @@ -0,0 +1,771 @@ + + + + + + +class Admin::GroupsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::GroupsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 23
    +def create
    +  @group = Group.new(params[:group])
    +  @group.owner = current_user
    +
    +  if @group.save
    +    redirect_to [:admin, @group], notice: 'Group was successfully created.'
    +  else
    +    render action: "new"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 64
    +def destroy
    +  @group.destroy
    +
    +  redirect_to admin_groups_path, notice: 'Group was successfully deleted.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 20
    +def edit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 4
    +def index
    +  @groups = Group.scoped
    +  @groups = @groups.search(params[:name]) if params[:name].present?
    +  @groups = @groups.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 16
    +def new
    +  @group = Group.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 49
    +def project_update
    +  project_ids = params[:project_ids]
    +  Project.where(id: project_ids).update_all(group_id: @group.id)
    +
    +  redirect_to :back, notice: 'Group was successfully updated.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + remove_project() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 56
    +def remove_project
    +  @project = Project.find(params[:project_id])
    +  @project.group_id = nil
    +  @project.save
    +
    +  redirect_to :back, notice: 'Group was successfully updated.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 10
    +def show
    +  @projects = Project.scoped
    +  @projects = @projects.not_in_group(@group) if @group.projects.present?
    +  @projects = @projects.all
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/groups_controller.rb, line 34
    +def update
    +  group_params = params[:group].dup
    +  owner_id =group_params.delete(:owner_id)
    +
    +  if owner_id
    +    @group.owner = User.find(owner_id)
    +  end
    +
    +  if @group.update_attributes(group_params)
    +    redirect_to [:admin, @group], notice: 'Group was successfully updated.'
    +  else
    +    render action: "edit"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/HooksController.html b/doc/app/Admin/HooksController.html new file mode 100644 index 00000000..48cd5d00 --- /dev/null +++ b/doc/app/Admin/HooksController.html @@ -0,0 +1,603 @@ + + + + + + +class Admin::HooksController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::HooksController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/hooks_controller.rb, line 7
    +def create
    +  @hook = SystemHook.new(params[:hook])
    +
    +  if @hook.save
    +    redirect_to admin_hooks_path, notice: 'Hook was successfully created.'
    +  else
    +    @hooks = SystemHook.all
    +    render :index
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/hooks_controller.rb, line 18
    +def destroy
    +  @hook = SystemHook.find(params[:id])
    +  @hook.destroy
    +
    +  redirect_to admin_hooks_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/hooks_controller.rb, line 2
    +def index
    +  @hooks = SystemHook.all
    +  @hook = SystemHook.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + test() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/hooks_controller.rb, line 26
    +def test
    +  @hook = SystemHook.find(params[:hook_id])
    +  data = {
    +    event_name: "project_create",
    +    name: "Ruby",
    +    path: "ruby",
    +    project_id: 1,
    +    owner_name: "Someone",
    +    owner_email: "example@gitlabhq.com"
    +  }
    +  @hook.execute(data)
    +
    +  redirect_to :back
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/LogsController.html b/doc/app/Admin/LogsController.html new file mode 100644 index 00000000..8f70b1ad --- /dev/null +++ b/doc/app/Admin/LogsController.html @@ -0,0 +1,439 @@ + + + + + + +class Admin::LogsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::LogsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Admin/ProjectsController.html b/doc/app/Admin/ProjectsController.html new file mode 100644 index 00000000..5744746b --- /dev/null +++ b/doc/app/Admin/ProjectsController.html @@ -0,0 +1,733 @@ + + + + + + +class Admin::ProjectsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::ProjectsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 29
    +def create
    +  @admin_project = Project.new(params[:project])
    +  @admin_project.owner = current_user
    +
    +  if @admin_project.save
    +    redirect_to [:admin, @admin_project], notice: 'Project was successfully created.'
    +  else
    +    render action: "new"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 54
    +def destroy
    +  @admin_project.destroy
    +
    +  redirect_to admin_projects_url, notice: 'Project was successfully deleted.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 20
    +def edit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 4
    +def index
    +  @admin_projects = Project.scoped
    +  @admin_projects = @admin_projects.search(params[:name]) if params[:name].present?
    +  @admin_projects = @admin_projects.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 16
    +def new
    +  @admin_project = Project.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 10
    +def show
    +  @users = User.scoped
    +  @users = @users.not_in_project(@admin_project) if @admin_project.users.present?
    +  @users = @users.all
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + team_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 23
    +def team_update
    +  @admin_project.add_users_ids_to_team(params[:user_ids], params[:project_access])
    +
    +  redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/projects_controller.rb, line 40
    +def update
    +  owner_id = params[:project].delete(:owner_id)
    +
    +  if owner_id
    +    @admin_project.owner = User.find(owner_id)
    +  end
    +
    +  if @admin_project.update_attributes(params[:project])
    +    redirect_to [:admin, @admin_project], notice: 'Project was successfully updated.'
    +  else
    +    render action: "edit"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/ResqueController.html b/doc/app/Admin/ResqueController.html new file mode 100644 index 00000000..db73599b --- /dev/null +++ b/doc/app/Admin/ResqueController.html @@ -0,0 +1,484 @@ + + + + + + +class Admin::ResqueController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::ResqueController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/resque_controller.rb, line 2
    +def show
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/TeamMembersController.html b/doc/app/Admin/TeamMembersController.html new file mode 100644 index 00000000..907bf279 --- /dev/null +++ b/doc/app/Admin/TeamMembersController.html @@ -0,0 +1,558 @@ + + + + + + +class Admin::TeamMembersController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::TeamMembersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/team_members_controller.rb, line 16
    +def destroy
    +  @admin_team_member = UsersProject.find(params[:id])
    +  @admin_team_member.destroy
    +
    +  redirect_to :back
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/team_members_controller.rb, line 2
    +def edit
    +  @admin_team_member = UsersProject.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/team_members_controller.rb, line 6
    +def update
    +  @admin_team_member = UsersProject.find(params[:id])
    +
    +  if @admin_team_member.update_attributes(params[:team_member])
    +    redirect_to [:admin, @admin_team_member.project],  notice: 'Project Access was successfully updated.'
    +  else
    +    render action: "edit"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Admin/UsersController.html b/doc/app/Admin/UsersController.html new file mode 100644 index 00000000..b300e4f7 --- /dev/null +++ b/doc/app/Admin/UsersController.html @@ -0,0 +1,839 @@ + + + + + + +class Admin::UsersController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Admin::UsersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + block() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 40
    +def block
    +  @admin_user = User.find(params[:id])
    +
    +  if @admin_user.block
    +    redirect_to :back, alert: "Successfully blocked"
    +  else
    +    redirect_to :back, alert: "Error occured. User was not blocked"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 60
    +def create
    +  admin = params[:user].delete("admin")
    +
    +  @admin_user = User.new(params[:user], as: :admin)
    +  @admin_user.admin = (admin && admin.to_i > 0)
    +
    +  respond_to do |format|
    +    if @admin_user.save
    +      format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully created.' }
    +      format.json { render json: @admin_user, status: :created, location: @admin_user }
    +    else
    +      format.html { render action: "new" }
    +      format.json { render json: @admin_user.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 99
    +def destroy
    +  @admin_user = User.find(params[:id])
    +  @admin_user.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to admin_users_url }
    +    format.json { head :ok }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 36
    +def edit
    +  @admin_user = User.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 2
    +def index
    +  @admin_users = User.scoped
    +  @admin_users = @admin_users.filter(params[:filter])
    +  @admin_users = @admin_users.search(params[:name]) if params[:name].present?
    +  @admin_users = @admin_users.order("updated_at DESC").page(params[:page])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 32
    +def new
    +  @admin_user = User.new({ projects_limit: Gitlab.config.default_projects_limit }, as: :admin)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 9
    +def show
    +  @admin_user = User.find(params[:id])
    +
    +  @projects = if @admin_user.projects.empty?
    +             Project
    +           else
    +             Project.without_user(@admin_user)
    +           end.all
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + team_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 19
    +def team_update
    +  @admin_user = User.find(params[:id])
    +
    +  UsersProject.user_bulk_import(
    +    @admin_user,
    +    params[:project_ids],
    +    params[:project_access]
    +  )
    +
    +  redirect_to [:admin, @admin_user], notice: 'Teams were successfully updated.'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unblock() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 50
    +def unblock
    +  @admin_user = User.find(params[:id])
    +
    +  if @admin_user.update_attribute(:blocked, false)
    +    redirect_to :back, alert: "Successfully unblocked"
    +  else
    +    redirect_to :back, alert: "Error occured. User was not unblocked"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin/users_controller.rb, line 77
    +def update
    +  admin = params[:user].delete("admin")
    +
    +  if params[:user][:password].blank?
    +    params[:user].delete(:password)
    +    params[:user].delete(:password_confirmation)
    +  end
    +
    +  @admin_user = User.find(params[:id])
    +  @admin_user.admin = (admin && admin.to_i > 0)
    +
    +  respond_to do |format|
    +    if @admin_user.update_attributes(params[:user], as: :admin)
    +      format.html { redirect_to [:admin, @admin_user], notice: 'User was successfully updated.' }
    +      format.json { head :ok }
    +    else
    +      format.html { render action: "edit" }
    +      format.json { render json: @admin_user.errors, status: :unprocessable_entity }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/AdminController.html b/doc/app/AdminController.html new file mode 100644 index 00000000..bdda7958 --- /dev/null +++ b/doc/app/AdminController.html @@ -0,0 +1,490 @@ + + + + + + +class AdminController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class AdminController

    + +
    + +

    Provides a base class for Admin controllers to +subclass

    + +

    Automatically sets the layout and ensures an administrator is logged in

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + authenticate_admin!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/admin_controller.rb, line 8
    +def authenticate_admin!
    +  return render_404 unless current_user.is_admin?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ApplicationController.html b/doc/app/ApplicationController.html new file mode 100644 index 00000000..dafa3413 --- /dev/null +++ b/doc/app/ApplicationController.html @@ -0,0 +1,1015 @@ + + + + + + +class ApplicationController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ApplicationController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Protected Instance Methods

    + + +
    + +
    + abilities() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 48
    +def abilities
    +  @abilities ||= Six.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + access_denied!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 73
    +def access_denied!
    +  render "errors/access_denied", layout: "errors", status: 404
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + add_project_abilities() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 61
    +def add_project_abilities
    +  abilities << Ability
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_sign_in_path_for(resource) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 33
    +def after_sign_in_path_for resource
    +  if resource.is_a?(User) && resource.respond_to?(:blocked) && resource.blocked
    +    sign_out resource
    +    flash[:alert] = "Your account was blocked"
    +    new_user_session_path
    +  else
    +    super
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize_code_access!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 69
    +def authorize_code_access!
    +  return access_denied! unless can?(current_user, :download_code, project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize_project!(action) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 65
    +def authorize_project!(action)
    +  return access_denied! unless can?(current_user, action, project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can?(object, action, subject) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 52
    +def can?(object, action, subject)
    +  abilities.allowed?(object, action, subject)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + dev_tools() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 107
    +def dev_tools
    +  Rack::MiniProfiler.authorize_request
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + git_not_found!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 81
    +def git_not_found!
    +  render "errors/git_not_found", layout: "errors", status: 404
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + method_missing(method_sym, *arguments, &block) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 85
    +def method_missing(method_sym, *arguments, &block)
    +  if method_sym.to_s =~ %r^authorize_(.*)!$/
    +    authorize_project!($1.to_sym)
    +  else
    +    super
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + no_cache_headers() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 101
    +def no_cache_headers
    +  response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
    +  response.headers["Pragma"] = "no-cache"
    +  response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + not_found!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 77
    +def not_found!
    +  render "errors/not_found", layout: "errors", status: 404
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 56
    +def project
    +  @project ||= current_user.projects.find_by_code(params[:project_id] || params[:id])
    +  @project || render_404
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reject_blocked!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 25
    +def reject_blocked!
    +  if current_user && current_user.blocked
    +    sign_out current_user
    +    flash[:alert] = "Your account was blocked"
    +    redirect_to new_user_session_path
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + render_404() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 93
    +def render_404
    +  render file: Rails.root.join("public", "404"), layout: false, status: "404"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + require_non_empty_project() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 97
    +def require_non_empty_project
    +  redirect_to @project if @project.empty_repo?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + set_current_user_for_observers() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/application_controller.rb, line 43
    +def set_current_user_for_observers
    +  MergeRequestObserver.current_user = current_user
    +  IssueObserver.current_user = current_user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ApplicationDecorator.html b/doc/app/ApplicationDecorator.html new file mode 100644 index 00000000..72a459bb --- /dev/null +++ b/doc/app/ApplicationDecorator.html @@ -0,0 +1,439 @@ + + + + + + +class ApplicationDecorator - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ApplicationDecorator

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/ApplicationHelper.html b/doc/app/ApplicationHelper.html new file mode 100644 index 00000000..9bc4243e --- /dev/null +++ b/doc/app/ApplicationHelper.html @@ -0,0 +1,1018 @@ + + + + + + +module ApplicationHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module ApplicationHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + app_theme() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 125
    +def app_theme
    +  Gitlab::Theme.css_class_by_id(current_user.try(:theme_id))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authbutton(provider, size = 64) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 150
    +def authbutton(provider, size = 64)
    +  file_name = "#{provider.to_s.split('_').first}_#{size}.png"
    +  image_tag("authbuttons/#{file_name}",
    +            alt: "Sign in with #{provider.to_s.titleize}")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + current_action?(*args) + click to toggle source +
    + + +
    + +

    Check if a partcular action is the current one

    + +

    args - One or more action names to check

    + +

    Examples

    + +
    # On Projects#new
    +current_action?(:new)           # => true
    +current_action?(:create)        # => false
    +current_action?(:new, :create)  # => true
    +
    + + + +
    +
    # File app/helpers/application_helper.rb, line 29
    +def current_action?(*args)
    +  args.any? { |v| v.to_s.downcase == action_name }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + current_controller?(*args) + click to toggle source +
    + + +
    + +

    Check if a particular controller is the current one

    + +

    args - One or more controller names to check

    + +

    Examples

    + +
    # On TreeController
    +current_controller?(:tree)           # => true
    +current_controller?(:commits)        # => false
    +current_controller?(:commits, :tree) # => true
    +
    + + + +
    +
    # File app/helpers/application_helper.rb, line 15
    +def current_controller?(*args)
    +  args.any? { |v| v.to_s.downcase == controller.controller_name }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + emoji_autocomplete_source() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 115
    +def emoji_autocomplete_source
    +  # should be an array of strings
    +  # so to_s can be called, because it is sufficient and to_json is too slow
    +  Emoji.names.to_s
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + gravatar_icon(user_email = '', size = 40) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 33
    +def gravatar_icon(user_email = '', size = 40)
    +  if Gitlab.config.disable_gravatar? || user_email.blank?
    +    'no_avatar.png'
    +  else
    +    gravatar_prefix = request.ssl? ? "https://secure" : "http://www"
    +    user_email.strip!
    +    "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + grouped_options_refs(destination = :tree) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 61
    +def grouped_options_refs(destination = :tree)
    +  options = [
    +    ["Branch", @project.branch_names ],
    +    [ "Tag", @project.tag_names ]
    +  ]
    +
    +  # If reference is commit id -
    +  # we should add it to branch/tag selectbox
    +  if(@ref && !options.flatten.include?(@ref) &&
    +     @ref =~ %r^[0-9a-zA-Z]{6,52}$/)
    +    options << ["Commit", [@ref]]
    +  end
    +
    +  grouped_options_for_select(options, @ref || @project.default_branch)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + hexdigest(string) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 137
    +def hexdigest(string)
    +  Digest::SHA1.hexdigest string
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_commit(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 51
    +def last_commit(project)
    +  if project.repo_exists?
    +    time_ago_in_words(project.commit.committed_date) + " ago"
    +  else
    +    "Never"
    +  end
    +rescue
    +  "Never"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ldap_enable?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 121
    +def ldap_enable?
    +  Devise.omniauth_providers.include?(:ldap)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_last_activity(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 141
    +def project_last_activity project
    +  activity = project.last_activity
    +  if activity && activity.created_at
    +    time_ago_in_words(activity.created_at) + " ago"
    +  else
    +    "Never"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + request_protocol() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 43
    +def request_protocol
    +  request.ssl? ? "https" : "http"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + search_autocomplete_source() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 77
    +def search_autocomplete_source
    +  projects = current_user.projects.map{ |p| { label: p.name, url: project_path(p) } }
    +
    +  default_nav = [
    +    { label: "My Profile", url: profile_path },
    +    { label: "My SSH Keys", url: keys_path },
    +    { label: "My Dashboard", url: root_path },
    +    { label: "Admin Section", url: admin_root_path },
    +  ]
    +
    +  help_nav = [
    +    { label: "Workflow Help", url: help_workflow_path },
    +    { label: "Permissions Help", url: help_permissions_path },
    +    { label: "Web Hooks Help", url: help_web_hooks_path },
    +    { label: "System Hooks Help", url: help_system_hooks_path },
    +    { label: "API Help", url: help_api_path },
    +    { label: "Markdown Help", url: help_markdown_path },
    +    { label: "SSH Keys Help", url: help_ssh_path },
    +  ]
    +
    +  project_nav = []
    +  if @project && !@project.new_record?
    +    project_nav = [
    +      { label: "#{@project.name} Issues",   url: project_issues_path(@project) },
    +      { label: "#{@project.name} Commits",  url: project_commits_path(@project, @ref || @project.root_ref) },
    +      { label: "#{@project.name} Merge Requests", url: project_merge_requests_path(@project) },
    +      { label: "#{@project.name} Milestones", url: project_milestones_path(@project) },
    +      { label: "#{@project.name} Snippets", url: project_snippets_path(@project) },
    +      { label: "#{@project.name} Team",     url: project_team_index_path(@project) },
    +      { label: "#{@project.name} Tree",     url: project_tree_path(@project, @ref || @project.root_ref) },
    +      { label: "#{@project.name} Wall",     url: wall_project_path(@project) },
    +      { label: "#{@project.name} Wiki",     url: project_wikis_path(@project) },
    +    ]
    +  end
    +
    +  [projects, default_nav, project_nav, help_nav].flatten.to_json
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show_last_push_widget?(event) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 129
    +def show_last_push_widget?(event)
    +  event &&
    +    event.last_push_to_non_root? &&
    +    !event.rm_ref? &&
    +    event.project &&
    +    event.project.merge_requests_enabled
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + web_app_url() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/application_helper.rb, line 47
    +def web_app_url
    +  "#{request_protocol}://#{Gitlab.config.web_host}/"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/AttachmentUploader.html b/doc/app/AttachmentUploader.html new file mode 100644 index 00000000..b6e9d1ba --- /dev/null +++ b/doc/app/AttachmentUploader.html @@ -0,0 +1,486 @@ + + + + + + +class AttachmentUploader - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class AttachmentUploader

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + store_dir() + click to toggle source +
    + + +
    + +

    Override the directory where uploaded files will be stored. This is a +sensible default for uploaders that are meant to be mounted:

    + + + +
    +
    # File app/uploaders/attachment_uploader.rb, line 15
    +def store_dir
    +  "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Authority.html b/doc/app/Authority.html new file mode 100644 index 00000000..92f46c55 --- /dev/null +++ b/doc/app/Authority.html @@ -0,0 +1,782 @@ + + + + + + +module Authority - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Authority

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + add_access(user, *access) + click to toggle source +
    + + +
    + +

    Compatible with all access rights Should be rewrited for new access rights

    + + + +
    +
    # File app/roles/authority.rb, line 4
    +def add_access(user, *access)
    +  access = if access.include?(:admin)
    +             { project_access: UsersProject::MASTER }
    +           elsif access.include?(:write)
    +             { project_access: UsersProject::DEVELOPER }
    +           else
    +             { project_access: UsersProject::REPORTER }
    +           end
    +  opts = { user: user }
    +  opts.merge!(access)
    +  users_projects.create(opts)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + allow_read_for?(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 39
    +def allow_read_for?(user)
    +  !users_projects.where(user_id: user.id).empty?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + dev_access_for?(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 51
    +def dev_access_for?(user)
    +  !users_projects.where(user_id: user.id, project_access: [UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + guest_access_for?(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 43
    +def guest_access_for?(user)
    +  !users_projects.where(user_id: user.id).empty?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + master_access_for?(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 55
    +def master_access_for?(user)
    +  !users_projects.where(user_id: user.id, project_access: [UsersProject::MASTER]).empty?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + report_access_for?(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 47
    +def report_access_for?(user)
    +  !users_projects.where(user_id: user.id, project_access: [UsersProject::REPORTER, UsersProject::DEVELOPER, UsersProject::MASTER]).empty?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repository_masters() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 33
    +def repository_masters
    +  keys = Key.joins({user: :users_projects}).
    +    where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::MASTER)
    +  keys.map(&:identifier)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repository_readers() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 21
    +def repository_readers
    +  keys = Key.joins({user: :users_projects}).
    +    where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::REPORTER)
    +  keys.map(&:identifier) + deploy_keys.map(&:identifier)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repository_writers() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 27
    +def repository_writers
    +  keys = Key.joins({user: :users_projects}).
    +    where("users_projects.project_id = ? AND users_projects.project_access = ?", id, UsersProject::DEVELOPER)
    +  keys.map(&:identifier)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reset_access(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/authority.rb, line 17
    +def reset_access(user)
    +  users_projects.where(project_id: self.id, user_id: user.id).destroy if self.id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/BaseContext.html b/doc/app/BaseContext.html new file mode 100644 index 00000000..b9c46738 --- /dev/null +++ b/doc/app/BaseContext.html @@ -0,0 +1,605 @@ + + + + + + +class BaseContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class BaseContext

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + current_user[RW] +
    + +
    + + + +
    +
    + +
    +
    + params[RW] +
    + +
    + + + +
    +
    + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(project, user, params) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/base_context.rb, line 4
    +def initialize(project, user, params)
    +  @project, @current_user, @params = project, user, params.dup
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + abilities() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/base_context.rb, line 8
    +def abilities
    +  @abilities ||= begin
    +                   abilities = Six.new
    +                   abilities << Ability
    +                   abilities
    +                 end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can?(object, action, subject) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/base_context.rb, line 16
    +def can?(object, action, subject)
    +  abilities.allowed?(object, action, subject)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/BlameController.html b/doc/app/BlameController.html new file mode 100644 index 00000000..4b23b227 --- /dev/null +++ b/doc/app/BlameController.html @@ -0,0 +1,500 @@ + + + + + + +class BlameController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class BlameController

    + +
    + +

    Controller for viewing a file’s blame

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/blame_controller.rb, line 12
    +def show
    +  @repo = @project.repo
    +  @blame = Grit::Blob.blame(@repo, @commit.id, @path)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/BlobController.html b/doc/app/BlobController.html new file mode 100644 index 00000000..e8f069c2 --- /dev/null +++ b/doc/app/BlobController.html @@ -0,0 +1,519 @@ + + + + + + +class BlobController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class BlobController

    + +
    + +

    Controller for viewing a file’s blame

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/blob_controller.rb, line 13
    +def show
    +  if @tree.is_blob?
    +    if @tree.text?
    +      encoding = detect_encoding(@tree.data)
    +      mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
    +    else
    +      mime_type = @tree.mime_type
    +    end
    +
    +    send_data(
    +      @tree.data,
    +      type: mime_type,
    +      disposition: 'inline',
    +      filename: @tree.name
    +    )
    +  else
    +    not_found!
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Commit.html b/doc/app/Commit.html new file mode 100644 index 00000000..05a3f3ce --- /dev/null +++ b/doc/app/Commit.html @@ -0,0 +1,1191 @@ + + + + + + +class Commit - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Commit

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + commit[RW] +
    + +
    + + + +
    +
    + +
    +
    + head[RW] +
    + +
    + + + +
    +
    + +
    +
    + refs[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + commits(repo, ref, path = nil, limit = nil, offset = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 58
    +def commits(repo, ref, path = nil, limit = nil, offset = nil)
    +  if path
    +    repo.log(ref, path, max_count: limit, skip: offset)
    +  elsif limit && offset
    +    repo.commits(ref, limit, offset)
    +  else
    +    repo.commits(ref)
    +  end.map{ |c| Commit.new(c) }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_between(repo, from, to) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 68
    +def commits_between(repo, from, to)
    +  repo.commits_between(from, to).map { |c| Commit.new(c) }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_since(repo, date) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 46
    +def commits_since(repo, date)
    +  commits = repo.heads.map do |h|
    +    repo.log(h.name, nil, since: date).each { |c| Commit.new(c, h) }
    +  end.flatten.uniq { |c| c.id }
    +
    +  commits.sort! do |x, y|
    +    y.committed_date <=> x.committed_date
    +  end
    +
    +  commits
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_with_refs(repo, n = 20) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 36
    +def commits_with_refs(repo, n = 20)
    +  commits = repo.branches.map { |ref| Commit.new(ref.commit, ref) }
    +
    +  commits.sort! do |x, y|
    +    y.committed_date <=> x.committed_date
    +  end
    +
    +  commits[0..n]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + compare(project, from, to) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 72
    +def compare(project, from, to)
    +  result = {
    +    commits: [],
    +    diffs: [],
    +    commit: nil,
    +    same: false
    +  }
    +
    +  return result unless from && to
    +
    +  first = project.commit(to.try(:strip))
    +  last = project.commit(from.try(:strip))
    +
    +  if first && last
    +    commits = [first, last].sort_by(&:created_at)
    +    younger = commits.first
    +    older = commits.last
    +
    +    result[:same] = (younger.id == older.id)
    +    result[:commits] = project.repo.commits_between(younger.id, older.id).map {|c| Commit.new(c)}
    +    result[:diffs] = project.repo.diff(younger.id, older.id) rescue []
    +    result[:commit] = Commit.new(older)
    +  end
    +
    +  result
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + find_or_first(repo, commit_id = nil, root_ref) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 14
    +def find_or_first(repo, commit_id = nil, root_ref)
    +  commit = if commit_id
    +             repo.commit(commit_id)
    +           else
    +             repo.commits(root_ref).first
    +           end
    +
    +  Commit.new(commit) if commit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + fresh_commits(repo, n = 10) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 24
    +def fresh_commits(repo, n = 10)
    +  commits = repo.heads.map do |h|
    +    repo.commits(h.name, n).map { |c| Commit.new(c, h) }
    +  end.flatten.uniq { |c| c.id }
    +
    +  commits.sort! do |x, y|
    +    y.committed_date <=> x.committed_date
    +  end
    +
    +  commits[0...n]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new(raw_commit, head = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 100
    +def initialize(raw_commit, head = nil)
    +  @commit = raw_commit
    +  @head = head
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + author_email() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 117
    +def author_email
    +  author.email
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + author_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 121
    +def author_name
    +  utf8 author.name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + committer_email() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 134
    +def committer_email
    +  committer.email
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + committer_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 130
    +def committer_name
    +  utf8 committer.name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + created_at() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 113
    +def created_at
    +  committed_date
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + different_committer?() + click to toggle source +
    + + +
    + +

    Was this commit committed by a different person than the original author?

    + + + +
    +
    # File app/models/commit.rb, line 126
    +def different_committer?
    +  author_name != committer_name || author_email != committer_email
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + parents_count() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 146
    +def parents_count
    +  parents && parents.count || 0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + prev_commit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 138
    +def prev_commit
    +  parents.try :first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + prev_commit_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 142
    +def prev_commit_id
    +  prev_commit.try :id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + safe_message() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 109
    +def safe_message
    +  @safe_message ||= utf8 message
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + short_id(length = 10) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/commit.rb, line 105
    +def short_id(length = 10)
    +  id.to_s[0..length]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CommitController.html b/doc/app/CommitController.html new file mode 100644 index 00000000..564161e9 --- /dev/null +++ b/doc/app/CommitController.html @@ -0,0 +1,509 @@ + + + + + + +class CommitController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class CommitController

    + +
    + +

    Controller for a specific Commit

    + +

    Not to be confused with CommitsController, plural.

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/commit_controller.rb, line 10
    +def show
    +  result = CommitLoadContext.new(project, current_user, params).execute
    +
    +  @commit = result[:commit]
    +  git_not_found! unless @commit
    +
    +  @suppress_diff    = result[:suppress_diff]
    +  @note             = result[:note]
    +  @line_notes       = result[:line_notes]
    +  @notes_count      = result[:notes_count]
    +  @comments_allowed = true
    +
    +  respond_to do |format|
    +    format.html do
    +      if result[:status] == :huge_commit
    +        render "huge_commit" and return
    +      end
    +    end
    +
    +    format.patch
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CommitDecorator.html b/doc/app/CommitDecorator.html new file mode 100644 index 00000000..3cca57a4 --- /dev/null +++ b/doc/app/CommitDecorator.html @@ -0,0 +1,663 @@ + + + + + + +class CommitDecorator - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class CommitDecorator

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + + + + +
    + +
    + description() + click to toggle source +
    + + +
    + +

    Returns the commits description

    + +

    cut off, ellipses (`&hellp;`) are prepended to the commit message.

    + + + +
    +
    # File app/decorators/commit_decorator.rb, line 34
    +def description
    +  description = safe_message
    +
    +  title_end = description.index(%r\n/)
    +  if (!title_end && description.length > 80) || (title_end && title_end > 80)
    +    "&hellip;".html_safe << description[70..-1]
    +  else
    +    description.split(%r\n/, 2)[1].try(:chomp)
    +  end
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + title() + click to toggle source +
    + + +
    + +

    Returns the commits title.

    + +

    Usually, the commit title is the first line of the commit message. In case +this first line is longer than 80 characters, it is cut off after 70 +characters and ellipses (`&hellp;`) are appended.

    + + + +
    +
    # File app/decorators/commit_decorator.rb, line 18
    +def title
    +  title = safe_message
    +
    +  return no_commit_message if title.blank?
    +
    +  title_end = title.index(%r\n/)
    +  if (!title_end && title.length > 80) || (title_end && title_end > 80)
    +    title[0..69] << "&hellip;".html_safe
    +  else
    +    title.split(%r\n/, 2).first
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + no_commit_message() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/commit_decorator.rb, line 69
    +def no_commit_message
    +  "--no commit message"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CommitLoadContext.html b/doc/app/CommitLoadContext.html new file mode 100644 index 00000000..feb6dbf4 --- /dev/null +++ b/doc/app/CommitLoadContext.html @@ -0,0 +1,513 @@ + + + + + + +class CommitLoadContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class CommitLoadContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/commit_load_context.rb, line 2
    +def execute
    +  result = {
    +    commit: nil,
    +    suppress_diff: false,
    +    line_notes: [],
    +    notes_count: 0,
    +    note: nil,
    +    status: :ok
    +  }
    +
    +  commit = project.commit(params[:id])
    +
    +  if commit
    +    commit = CommitDecorator.decorate(commit)
    +    line_notes = project.commit_line_notes(commit)
    +
    +    result[:commit] = commit
    +    result[:note] = project.build_commit_note(commit)
    +    result[:line_notes] = line_notes
    +    result[:notes_count] = line_notes.count + project.commit_notes(commit).count
    +
    +    begin
    +      result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff]
    +    rescue Grit::Git::GitTimeout
    +      result[:suppress_diff] = true
    +      result[:status] = :huge_commit
    +    end
    +  end
    +
    +  result
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CommitsController.html b/doc/app/CommitsController.html new file mode 100644 index 00000000..52eaad04 --- /dev/null +++ b/doc/app/CommitsController.html @@ -0,0 +1,507 @@ + + + + + + +class CommitsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class CommitsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/commits_controller.rb, line 11
    +def show
    +  @repo = @project.repo
    +  @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
    +
    +  @commits = @project.commits(@ref, @path, @limit, @offset)
    +  @commits = CommitDecorator.decorate(@commits)
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +    format.js
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CommitsHelper.html b/doc/app/CommitsHelper.html new file mode 100644 index 00000000..58844bec --- /dev/null +++ b/doc/app/CommitsHelper.html @@ -0,0 +1,625 @@ + + + + + + +module CommitsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module CommitsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + build_line_anchor(index, line_new, line_old) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/commits_helper.rb, line 12
    +def build_line_anchor(index, line_new, line_old)
    +  "#{index}_#{line_old}_#{line_new}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + each_diff_line(diff_arr, index) { |full_line, type, nil, nil, nil| ... } + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/commits_helper.rb, line 16
    +def each_diff_line(diff_arr, index)
    +  line_old = 1
    +  line_new = 1
    +  type = nil
    +
    +  lines_arr = ::Gitlab::InlineDiff.processing diff_arr
    +  lines_arr.each do |line|
    +    next if line.match(%r^\-\-\- \/dev\/null/)
    +    next if line.match(%r^\+\+\+ \/dev\/null/)
    +    next if line.match(%r^\-\-\- a/)
    +    next if line.match(%r^\+\+\+ b/)
    +
    +    full_line = html_escape(line.gsub(%r\n/, ''))
    +    full_line = ::Gitlab::InlineDiff.replace_markers full_line
    +
    +    if line.match(%r^@@ -/)
    +      type = "match"
    +
    +      line_old = line.match(%r\-[0-9]*/)[0].to_i.abs rescue 0
    +      line_new = line.match(%r\+[0-9]*/)[0].to_i.abs rescue 0
    +
    +      next if line_old == 1 && line_new == 1 #top of file
    +      yield(full_line, type, nil, nil, nil)
    +      next
    +    else
    +      type = identification_type(line)
    +      line_code = build_line_anchor(index, line_new, line_old)
    +      yield(full_line, type, line_code, line_new, line_old)
    +    end
    +
    +
    +    if line[0] == "+"
    +      line_new += 1
    +    elsif line[0] == "-"
    +      line_old += 1
    +    else
    +      line_new += 1
    +      line_old += 1
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + identification_type(line) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/commits_helper.rb, line 2
    +def identification_type(line)
    +  if line[0] == "+"
    +    "new"
    +  elsif line[0] == "-"
    +    "old"
    +  else
    +    nil
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + image_diff_class(diff) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/commits_helper.rb, line 58
    +def image_diff_class(diff)
    +  if diff.deleted_file
    +    "diff_image_removed"
    +  elsif diff.new_file
    +    "diff_image_added"
    +  else
    +    nil
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/CompareController.html b/doc/app/CompareController.html new file mode 100644 index 00000000..177e22d2 --- /dev/null +++ b/doc/app/CompareController.html @@ -0,0 +1,556 @@ + + + + + + +class CompareController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class CompareController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/compare_controller.rb, line 22
    +def create
    +  redirect_to project_compare_path(@project, params[:from], params[:to])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/compare_controller.rb, line 7
    +def index
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/compare_controller.rb, line 10
    +def show
    +  result = Commit.compare(project, params[:from], params[:to])
    +
    +  @commits       = result[:commits]
    +  @commit        = result[:commit]
    +  @diffs         = result[:diffs]
    +  @refs_are_same = result[:same]
    +  @line_notes    = []
    +
    +  @commits = CommitDecorator.decorate(@commits)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/DashboardController.html b/doc/app/DashboardController.html new file mode 100644 index 00000000..e3f4d1b4 --- /dev/null +++ b/doc/app/DashboardController.html @@ -0,0 +1,569 @@ + + + + + + +class DashboardController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class DashboardController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/dashboard_controller.rb, line 4
    +def index
    +  @groups = Group.where(id: current_user.projects.pluck(:group_id))
    +  @projects = current_user.projects_with_events
    +  @projects = @projects.page(params[:page]).per(30)
    +
    +  @events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0)
    +  @last_push = current_user.recent_push
    +
    +  respond_to do |format|
    +    format.html
    +    format.js
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issues() + click to toggle source +
    + + +
    + +

    Get only assigned issues

    + + + +
    +
    # File app/controllers/dashboard_controller.rb, line 26
    +def issues
    +  @projects = current_user.projects.all
    +  @user   = current_user
    +  @issues = current_user.assigned_issues.opened.recent.page(params[:page]).per(20)
    +  @issues = @issues.includes(:author, :project)
    +
    +  respond_to do |format|
    +    format.html
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_requests() + click to toggle source +
    + + +
    + +

    Get authored or assigned open merge requests

    + + + +
    +
    # File app/controllers/dashboard_controller.rb, line 20
    +def merge_requests
    +  @projects = current_user.projects.all
    +  @merge_requests = current_user.cared_merge_requests.recent.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/DeployKeysController.html b/doc/app/DeployKeysController.html new file mode 100644 index 00000000..318a1441 --- /dev/null +++ b/doc/app/DeployKeysController.html @@ -0,0 +1,626 @@ + + + + + + +class DeployKeysController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class DeployKeysController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/deploy_keys_controller.rb, line 21
    +def create
    +  @key = @project.deploy_keys.new(params[:key])
    +  if @key.save
    +    redirect_to project_deploy_keys_path(@project)
    +  else
    +    render "new"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/deploy_keys_controller.rb, line 30
    +def destroy
    +  @key = @project.deploy_keys.find(params[:id])
    +  @key.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_deploy_keys_url }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/deploy_keys_controller.rb, line 7
    +def index
    +  @keys = @project.deploy_keys.all
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/deploy_keys_controller.rb, line 15
    +def new
    +  @key = @project.deploy_keys.new
    +
    +  respond_with(@key)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/deploy_keys_controller.rb, line 11
    +def show
    +  @key = @project.deploy_keys.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ErrorsController.html b/doc/app/ErrorsController.html new file mode 100644 index 00000000..e77a67d7 --- /dev/null +++ b/doc/app/ErrorsController.html @@ -0,0 +1,485 @@ + + + + + + +class ErrorsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ErrorsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + githost() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/errors_controller.rb, line 2
    +def githost
    +  render "errors/gitolite"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Event.html b/doc/app/Event.html new file mode 100644 index 00000000..1347cda3 --- /dev/null +++ b/doc/app/Event.html @@ -0,0 +1,1222 @@ + + + + + + +class Event - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Event

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    Closed + +
    + + +
    Commented + +
    + + +
    Created + +
    + + +
    Joined + +
    + + +
    Left + +
    + + +
    Merged + +
    + + +
    Pushed + +
    + + +
    Reopened + +
    + + +
    Updated + +
    + + +
    +
    + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + determine_action(record) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 36
    +def determine_action(record)
    +  if [Issue, MergeRequest].include? record.class
    +    Event::Created
    +  elsif record.kind_of? Note
    +    Event::Commented
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + action_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 133
    +def action_name
    +  if closed?
    +    "closed"
    +  elsif merged?
    +    "merged"
    +  elsif joined?
    +    'joined'
    +  elsif left?
    +    'left'
    +  else
    +    "opened"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + allowed?() + click to toggle source +
    + + +
    + +

    Next events currently enabled for system

    + +
    - push
    +- new issue
    +- merge request
    + + + +
    +
    # File app/models/event.rb, line 49
    +def allowed?
    +  push? || issue? || merge_request? || membership_changed?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + author() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 129
    +def author
    +  @author ||= User.find(author_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + changed_issue?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 104
    +def changed_issue?
    +  target_type == "Issue" &&
    +    [Closed, Reopened].include?(action)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + changed_merge_request?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 99
    +def changed_merge_request?
    +  target_type == "MergeRequest" &&
    +    [Closed, Reopened].include?(action)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + closed?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 73
    +def closed?
    +  action == self.class::Closed
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issue() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 121
    +def issue
    +  target if target_type == "Issue"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issue?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 81
    +def issue?
    +  target_type == "Issue"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + joined?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 109
    +def joined?
    +  action == Joined
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + left?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 113
    +def left?
    +  action == Left
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + membership_changed?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 117
    +def membership_changed?
    +  joined? || left?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_request() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 125
    +def merge_request
    +  target if target_type == "MergeRequest"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_request?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 85
    +def merge_request?
    +  target_type == "MergeRequest"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merged?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 69
    +def merged?
    +  action == self.class::Merged
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_issue?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 89
    +def new_issue?
    +  target_type == "Issue" &&
    +    action == Created
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_merge_request?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 94
    +def new_merge_request?
    +  target_type == "MergeRequest" &&
    +    action == Created
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 53
    +def project_name
    +  if project
    +    project.name
    +  else
    +    "(deleted project)"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + push?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 65
    +def push?
    +  action == self.class::Pushed && valid_push?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reopened?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 77
    +def reopened?
    +  action == self.class::Reopened
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + target_title() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/event.rb, line 61
    +def target_title
    +  target.try :title
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/EventDecorator.html b/doc/app/EventDecorator.html new file mode 100644 index 00000000..dddb98a6 --- /dev/null +++ b/doc/app/EventDecorator.html @@ -0,0 +1,578 @@ + + + + + + +class EventDecorator - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class EventDecorator

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + feed_summary() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/event_decorator.rb, line 37
    +def feed_summary
    +  if self.issue?
    +    h.render "events/event_issue", issue: self.issue
    +  elsif self.push?
    +    h.render "events/event_push", event: self
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + feed_title() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/event_decorator.rb, line 4
    +def feed_title
    +  if self.issue?
    +    "#{self.author_name} #{self.action_name} issue ##{self.target_id}: #{self.issue_title} at #{self.project.name}"
    +  elsif self.merge_request?
    +    "#{self.author_name} #{self.action_name} MR ##{self.target_id}: #{self.merge_request_title} at #{self.project.name}"
    +  elsif self.push?
    +    "#{self.author_name} #{self.push_action_name} #{self.ref_type} #{self.ref_name} at #{self.project.name}"
    +  elsif self.membership_changed?
    +    "#{self.author_name} #{self.action_name} #{self.project.name}"
    +  else
    +    ""
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + feed_url() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/event_decorator.rb, line 18
    +def feed_url
    +  if self.issue?
    +    h.project_issue_url(self.project, self.issue)
    +  elsif self.merge_request?
    +    h.project_merge_request_url(self.project, self.merge_request)
    +
    +  elsif self.push?
    +    if self.push_with_commits?
    +      if self.commits_count > 1
    +        h.project_compare_url(self.project, :from => self.parent_commit.id, :to => self.last_commit.id)
    +      else
    +        h.project_commit_url(self.project, :id => self.last_commit.id)
    +      end
    +    else
    +      h.project_commits_url(self.project, self.ref_name)
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/EventsHelper.html b/doc/app/EventsHelper.html new file mode 100644 index 00000000..4f7c0454 --- /dev/null +++ b/doc/app/EventsHelper.html @@ -0,0 +1,566 @@ + + + + + + +module EventsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module EventsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + event_action_name(event) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/events_helper.rb, line 13
    +def event_action_name(event)
    +  target = if event.target_type
    +             event.target_type.titleize.downcase
    +           else
    +             'project'
    +           end
    +
    +  [event.action_name, target].join(" ")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + event_image(event) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/events_helper.rb, line 23
    +def event_image event
    +  event_image_path = if event.push?
    +                 "event_push.png"
    +               elsif event.merged?
    +                 "event_mr_merged.png"
    +               end
    +
    +  return nil unless event_image_path
    +
    +  content_tag :div, class: 'event_icon' do
    +    image_tag event_image_path
    +  end
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + +
    + + + + diff --git a/doc/app/ExtractsPath.html b/doc/app/ExtractsPath.html new file mode 100644 index 00000000..e3825307 --- /dev/null +++ b/doc/app/ExtractsPath.html @@ -0,0 +1,614 @@ + + + + + + +module ExtractsPath - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module ExtractsPath

    + +
    + +

    Module providing methods for dealing with separating a tree-ish string and +a file path string when combined in a request parameter

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + assign_ref_vars() + click to toggle source +
    + + +
    + +

    Assigns common instance variables for views working with Git tree-ish +objects

    + +

    Assignments are:

    +
    • +

      @id - A string representing the joined ref and path

      +
    • +

      @ref - A string representing the ref (e.g., the branch, tag, or commit +SHA)

      +
    • +

      @path - A string representing the filesystem path

      +
    • +

      @commit - A CommitDecorator representing +the commit from the given ref

      +
    • +

      @tree - A TreeDecorator representing the +tree at the given ref/path

      +
    + +

    If the :id parameter appears to be requesting a specific response format, +that will be handled as well.

    + +

    Automatically renders `not_found!` if a valid tree path could not be +resolved (e.g., when a user inserts an invalid path or ref).

    + + + +
    +
    # File lib/extracts_path.rb, line 94
    +def assign_ref_vars
    +  # Handle formats embedded in the id
    +  if params[:id].ends_with?('.atom')
    +    params[:id].gsub!(%r\.atom$/, '')
    +    request.format = :atom
    +  end
    +
    +  @ref, @path = extract_ref(params[:id])
    +
    +  @id = File.join(@ref, @path)
    +
    +  @commit = CommitDecorator.decorate(@project.commit(@ref))
    +
    +  @tree = Tree.new(@commit.tree, @project, @ref, @path)
    +  @tree = TreeDecorator.new(@tree)
    +
    +  raise InvalidPathError if @tree.invalid?
    +rescue NoMethodError, InvalidPathError
    +  not_found!
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + extract_ref(input) + click to toggle source +
    + + +
    + +

    Given a string containing both a Git tree-ish, such as a branch or tag, and +a filesystem path joined by forward slashes, attempts to separate the two.

    + +

    Expects a @project instance variable to contain the active project. This is +used to check the input against a list of valid repository refs.

    + +

    Examples

    + +
    # No @project available
    +extract_ref('master')
    +# => ['', '']
    +
    +extract_ref('master')
    +# => ['master', '']
    +
    +extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
    +# => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
    +
    +extract_ref("v2.0.0/README.md")
    +# => ['v2.0.0', 'README.md']
    +
    +extract_ref('issues/1234/app/models/project.rb')
    +# => ['issues/1234', 'app/models/project.rb']
    +
    +# Given an invalid branch, we fall back to just splitting on the first slash
    +extract_ref('non/existent/branch/README.md')
    +# => ['non', 'existent/branch/README.md']
    +
    + +

    Returns an Array where the first value is the tree-ish and the second is +the path

    + + + +
    +
    # File lib/extracts_path.rb, line 45
    +def extract_ref(input)
    +  pair = ['', '']
    +
    +  return pair unless @project
    +
    +  if input.match(%r^([[:alnum:]]{40})(.+)/)
    +    # If the ref appears to be a SHA, we're done, just split the string
    +    pair = $~.captures
    +  else
    +    # Otherwise, attempt to detect the ref using a list of the project's
    +    # branches and tags
    +
    +    # Append a trailing slash if we only get a ref and no file path
    +    id = input
    +    id += '/' unless id.ends_with?('/')
    +
    +    valid_refs = @project.ref_names
    +    valid_refs.select! { |v| id.start_with?("#{v}/") }
    +
    +    if valid_refs.length != 1
    +      # No exact ref match, so just try our best
    +      pair = id.match(%r([^\/]+)(.*)/).captures
    +    else
    +      # Partition the string into the ref and the path, ignoring the empty first value
    +      pair = id.partition(valid_refs.first)[1..-1]
    +    end
    +  end
    +
    +  # Remove ending slashes from path
    +  pair[1].gsub!(%r^\/|\/$/, '')
    +
    +  pair
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ExtractsPath/InvalidPathError.html b/doc/app/ExtractsPath/InvalidPathError.html new file mode 100644 index 00000000..3c8c60fc --- /dev/null +++ b/doc/app/ExtractsPath/InvalidPathError.html @@ -0,0 +1,441 @@ + + + + + + +class ExtractsPath::InvalidPathError - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ExtractsPath::InvalidPathError

    + +
    + +

    Raised when given an invalid file path

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/FileSizeValidator.html b/doc/app/FileSizeValidator.html new file mode 100644 index 00000000..5acdf291 --- /dev/null +++ b/doc/app/FileSizeValidator.html @@ -0,0 +1,652 @@ + + + + + + +class FileSizeValidator - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class FileSizeValidator

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    CHECKS + +
    + + +
    DEFAULT_TOKENIZER + +
    + + +
    MESSAGES + +
    + + +
    RESERVED_OPTIONS + +
    + + +
    +
    + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(options) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/file_size_validator.rb, line 8
    +def initialize(options)
    +  if range = (options.delete(:in) || options.delete(:within))
    +    raise ArgumentError, ":in and :within must be a Range" unless range.is_a?(Range)
    +    options[:minimum], options[:maximum] = range.begin, range.end
    +    options[:maximum] -= 1 if range.exclude_end?
    +  end
    +
    +  super
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + check_validity!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/file_size_validator.rb, line 18
    +def check_validity!
    +  keys = CHECKS.keys & options.keys
    +
    +  if keys.empty?
    +    raise ArgumentError, 'Range unspecified. Specify the :within, :maximum, :minimum, or :is option.'
    +  end
    +
    +  keys.each do |key|
    +    value = options[key]
    +
    +    unless value.is_a?(Integer) && value >= 0
    +      raise ArgumentError, ":#{key} must be a nonnegative Integer"
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + help() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/file_size_validator.rb, line 57
    +def help
    +  Helper.instance
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + validate_each(record, attribute, value) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/file_size_validator.rb, line 34
    +def validate_each(record, attribute, value)
    +  raise(ArgumentError, "A CarrierWave::Uploader::Base object was expected") unless value.kind_of? CarrierWave::Uploader::Base
    +
    +  value = (options[:tokenizer] || DEFAULT_TOKENIZER).call(value) if value.kind_of?(String)
    +
    +  CHECKS.each do |key, validity_check|
    +    next unless check_value = options[key]
    +
    +    value ||= [] if key == :maximum
    +
    +    value_size = value.size
    +    next if value_size.send(validity_check, check_value)
    +
    +    errors_options = options.except(*RESERVED_OPTIONS)
    +    errors_options[:file_size] = help.number_to_human_size check_value
    +
    +    default_message = options[MESSAGES[key]]
    +    errors_options[:message] ||= default_message if default_message
    +
    +    record.errors.add(attribute, MESSAGES[key], errors_options)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/FileSizeValidator/Helper.html b/doc/app/FileSizeValidator/Helper.html new file mode 100644 index 00000000..4fd146c2 --- /dev/null +++ b/doc/app/FileSizeValidator/Helper.html @@ -0,0 +1,455 @@ + + + + + + +class FileSizeValidator::Helper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class FileSizeValidator::Helper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/GitHost.html b/doc/app/GitHost.html new file mode 100644 index 00000000..3197a73f --- /dev/null +++ b/doc/app/GitHost.html @@ -0,0 +1,479 @@ + + + + + + +module GitHost - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module GitHost

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + git_host() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/git_host.rb, line 2
    +def git_host
    +  Gitlab::Gitolite.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab.html b/doc/app/Gitlab.html new file mode 100644 index 00000000..0e28a24b --- /dev/null +++ b/doc/app/Gitlab.html @@ -0,0 +1,454 @@ + + + + + + +module Gitlab - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Gitlab

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/API.html b/doc/app/Gitlab/API.html new file mode 100644 index 00000000..8fad1eec --- /dev/null +++ b/doc/app/Gitlab/API.html @@ -0,0 +1,452 @@ + + + + + + +class Gitlab::API - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::API

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    VERSION + +
    + + +
    +
    + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/APIHelpers.html b/doc/app/Gitlab/APIHelpers.html new file mode 100644 index 00000000..47bf3fb1 --- /dev/null +++ b/doc/app/Gitlab/APIHelpers.html @@ -0,0 +1,846 @@ + + + + + + +module Gitlab::APIHelpers - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Gitlab::APIHelpers

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + attributes_for_keys(keys) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 35
    +def attributes_for_keys(keys)
    +  attrs = {}
    +  keys.each do |key|
    +    attrs[key] = params[key] if params[key].present?
    +  end
    +  attrs
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authenticate!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 21
    +def authenticate!
    +  unauthorized! unless current_user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authenticated_as_admin!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 25
    +def authenticated_as_admin!
    +  forbidden! unless current_user.is_admin?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize!(action, subject) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 29
    +def authorize! action, subject
    +  unless abilities.allowed?(current_user, action, subject)
    +    forbidden!
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + current_user() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 3
    +def current_user
    +  @current_user ||= User.find_by_authentication_token(params[:private_token] || env["HTTP_PRIVATE_TOKEN"])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + forbidden!() + click to toggle source +
    + + +
    + +

    error helpers

    + + + +
    +
    # File lib/api/helpers.rb, line 45
    +def forbidden!
    +  render_api_error!('403 Forbidden', 403)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + not_allowed!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 60
    +def not_allowed!
    +  render_api_error!('Method Not Allowed', 405)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + not_found!(resource = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 49
    +def not_found!(resource = nil)
    +  message = ["404"]
    +  message << resource if resource
    +  message << "Not Found"
    +  render_api_error!(message.join(' '), 404)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + paginate(object) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 17
    +def paginate(object)
    +  object.page(params[:page]).per(params[:per_page].to_i)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + render_api_error!(message, status) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 64
    +def render_api_error!(message, status)
    +  error!({'message' => message}, status)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unauthorized!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 56
    +def unauthorized!
    +  render_api_error!('401 Unauthorized', 401)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + user_project() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/api/helpers.rb, line 7
    +def user_project
    +  if @project ||= current_user.projects.find_by_id(params[:id]) ||
    +                  current_user.projects.find_by_code(params[:id])
    +  else
    +    not_found!
    +  end
    +
    +  @project
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/AppLogger.html b/doc/app/Gitlab/AppLogger.html new file mode 100644 index 00000000..e3a352af --- /dev/null +++ b/doc/app/Gitlab/AppLogger.html @@ -0,0 +1,523 @@ + + + + + + +class Gitlab::AppLogger - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::AppLogger

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + file_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/app_logger.rb, line 3
    +def self.file_name
    +  'application.log'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + format_message(severity, timestamp, progname, msg) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/app_logger.rb, line 7
    +def format_message(severity, timestamp, progname, msg)
    +  "#{timestamp.to_s(:long)}: #{msg}\n"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Auth.html b/doc/app/Gitlab/Auth.html new file mode 100644 index 00000000..ac4fd556 --- /dev/null +++ b/doc/app/Gitlab/Auth.html @@ -0,0 +1,630 @@ + + + + + + +class Gitlab::Auth - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Auth

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create_from_omniauth(auth, ldap = false) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/auth.rb, line 20
    +def create_from_omniauth(auth, ldap = false)
    +  provider = auth.provider
    +  uid = auth.info.uid || auth.uid
    +  name = auth.info.name.force_encoding("utf-8")
    +  email = auth.info.email.downcase unless auth.info.email.nil?
    +
    +  ldap_prefix = ldap ? '(LDAP) ' : ''
    +  raise OmniAuth::Error, "#{ldap_prefix}#{provider} does not provide an email"         " address" if auth.info.email.blank?
    +
    +  log.info "#{ldap_prefix}Creating user from #{provider} login"         " {uid => #{uid}, name => #{name}, email => #{email}}"
    +  password = Devise.friendly_token[0, 8].downcase
    +  @user = User.new({
    +    extern_uid: uid,
    +    provider: provider,
    +    name: name,
    +    email: email,
    +    password: password,
    +    password_confirmation: password,
    +    projects_limit: Gitlab.config.default_projects_limit,
    +  }, as: :admin)
    +  if Gitlab.config.omniauth['block_auto_created_users'] && !ldap
    +    @user.blocked = true
    +  end
    +  @user.save!
    +  @user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + find_for_ldap_auth(auth, signed_in_resource = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/auth.rb, line 3
    +def find_for_ldap_auth(auth, signed_in_resource = nil)
    +  uid = auth.info.uid
    +  provider = auth.provider
    +  email = auth.info.email.downcase unless auth.info.email.nil?
    +  raise OmniAuth::Error, "LDAP accounts must provide an uid and email address" if uid.nil? or email.nil?
    +
    +  if @user = User.find_by_extern_uid_and_provider(uid, provider)
    +    @user
    +  elsif @user = User.find_by_email(email)
    +    log.info "Updating legacy LDAP user #{email} with extern_uid => #{uid}"
    +    @user.update_attributes(:extern_uid => uid, :provider => provider)
    +    @user
    +  else
    +    create_from_omniauth(auth, true)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + find_or_new_for_omniauth(auth) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/auth.rb, line 49
    +def find_or_new_for_omniauth(auth)
    +  provider, uid = auth.provider, auth.uid
    +  email = auth.info.email.downcase unless auth.info.email.nil?
    +
    +  if @user = User.find_by_provider_and_extern_uid(provider, uid)
    +    @user
    +  elsif @user = User.find_by_email(email)
    +    @user.update_attributes(:extern_uid => uid, :provider => provider)
    +    @user
    +  else
    +    if Gitlab.config.omniauth['allow_single_sign_on']
    +      @user = create_from_omniauth(auth)
    +      @user
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + log() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/auth.rb, line 66
    +def log
    +  Gitlab::AppLogger
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Encode.html b/doc/app/Gitlab/Encode.html new file mode 100644 index 00000000..387e0db2 --- /dev/null +++ b/doc/app/Gitlab/Encode.html @@ -0,0 +1,537 @@ + + + + + + +module Gitlab::Encode - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Gitlab::Encode

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + detect_encoding(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/encode.rb, line 34
    +def detect_encoding message
    +  return nil unless message
    +
    +  hash = CharlockHolmes::EncodingDetector.detect(message) rescue {}
    +  return hash[:encoding] ? hash[:encoding] : nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + utf8(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/encode.rb, line 7
    +def utf8 message
    +  # return nil if message is nil
    +  return nil unless message
    +
    +  message.force_encoding("utf-8")
    +  # return message if message type is binary
    +  detect = CharlockHolmes::EncodingDetector.detect(message)
    +  return message if detect[:type] == :binary
    +
    +  # if message is utf-8 encoding, just return it
    +  return message if message.valid_encoding?
    +
    +  # if message is not utf-8 encoding, convert it
    +  if detect[:encoding]
    +    message.force_encoding(detect[:encoding])
    +    message.encode!("utf-8", detect[:encoding], undef: :replace, replace: "", invalid: :replace)
    +  end
    +
    +  # ensure message encoding is utf8
    +  message.valid_encoding? ? message : raise
    +
    +# Prevent app from crash cause of encoding errors
    +rescue
    +  encoding = detect ? detect[:encoding] : "unknown"
    +  "--broken encoding: #{encoding}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities.html b/doc/app/Gitlab/Entities.html new file mode 100644 index 00000000..8cd0d837 --- /dev/null +++ b/doc/app/Gitlab/Entities.html @@ -0,0 +1,433 @@ + + + + + + +module Gitlab::Entities - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Gitlab::Entities

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/Hook.html b/doc/app/Gitlab/Entities/Hook.html new file mode 100644 index 00000000..c9eba832 --- /dev/null +++ b/doc/app/Gitlab/Entities/Hook.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::Hook - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::Hook

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/Issue.html b/doc/app/Gitlab/Entities/Issue.html new file mode 100644 index 00000000..f713b7ab --- /dev/null +++ b/doc/app/Gitlab/Entities/Issue.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::Issue - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::Issue

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/Milestone.html b/doc/app/Gitlab/Entities/Milestone.html new file mode 100644 index 00000000..f762ad29 --- /dev/null +++ b/doc/app/Gitlab/Entities/Milestone.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::Milestone - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::Milestone

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/Project.html b/doc/app/Gitlab/Entities/Project.html new file mode 100644 index 00000000..725e6b75 --- /dev/null +++ b/doc/app/Gitlab/Entities/Project.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::Project - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::Project

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/ProjectMember.html b/doc/app/Gitlab/Entities/ProjectMember.html new file mode 100644 index 00000000..468d3dc1 --- /dev/null +++ b/doc/app/Gitlab/Entities/ProjectMember.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::ProjectMember - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::ProjectMember

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/ProjectSnippet.html b/doc/app/Gitlab/Entities/ProjectSnippet.html new file mode 100644 index 00000000..e19fad75 --- /dev/null +++ b/doc/app/Gitlab/Entities/ProjectSnippet.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::ProjectSnippet - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::ProjectSnippet

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/RepoCommit.html b/doc/app/Gitlab/Entities/RepoCommit.html new file mode 100644 index 00000000..04c118a3 --- /dev/null +++ b/doc/app/Gitlab/Entities/RepoCommit.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::RepoCommit - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::RepoCommit

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/RepoObject.html b/doc/app/Gitlab/Entities/RepoObject.html new file mode 100644 index 00000000..27f928c1 --- /dev/null +++ b/doc/app/Gitlab/Entities/RepoObject.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::RepoObject - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::RepoObject

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/SSHKey.html b/doc/app/Gitlab/Entities/SSHKey.html new file mode 100644 index 00000000..43ed0f01 --- /dev/null +++ b/doc/app/Gitlab/Entities/SSHKey.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::SSHKey - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::SSHKey

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/User.html b/doc/app/Gitlab/Entities/User.html new file mode 100644 index 00000000..fb978194 --- /dev/null +++ b/doc/app/Gitlab/Entities/User.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::User - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::User

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/UserBasic.html b/doc/app/Gitlab/Entities/UserBasic.html new file mode 100644 index 00000000..dcb1e782 --- /dev/null +++ b/doc/app/Gitlab/Entities/UserBasic.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::UserBasic - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::UserBasic

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Entities/UserLogin.html b/doc/app/Gitlab/Entities/UserLogin.html new file mode 100644 index 00000000..fde77335 --- /dev/null +++ b/doc/app/Gitlab/Entities/UserLogin.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Entities::UserLogin - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Entities::UserLogin

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/FileEditor.html b/doc/app/Gitlab/FileEditor.html new file mode 100644 index 00000000..0916d63c --- /dev/null +++ b/doc/app/Gitlab/FileEditor.html @@ -0,0 +1,647 @@ + + + + + + +class Gitlab::FileEditor - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::FileEditor

    + +
    + +

    GitLab file editor

    + +

    It gives you ability to make changes to files & commit this changes +from GitLab UI.

    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    +
    + ref[RW] +
    + +
    + + + +
    +
    + +
    +
    + user[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(user, project, ref) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/file_editor.rb, line 9
    +def initialize(user, project, ref)
    +  self.user = user
    +  self.project = project
    +  self.ref = ref
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + update(path, content, commit_message, last_commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/file_editor.rb, line 15
    +def update(path, content, commit_message, last_commit)
    +  return false unless can_edit?(path, last_commit)
    +
    +  Grit::Git.with_timeout(10.seconds) do
    +    lock_file = Rails.root.join("tmp", "#{project.path}.lock")
    +
    +    File.open(lock_file, "w+") do |f|
    +      f.flock(File::LOCK_EX)
    +
    +      unless project.satellite.exists?
    +        raise "Satellite doesn't exist"
    +      end
    +
    +      project.satellite.clear
    +
    +      Dir.chdir(project.satellite.path) do
    +        r = Grit::Repo.new('.')
    +        r.git.sh "git reset --hard"
    +        r.git.sh "git fetch origin"
    +        r.git.sh "git config user.name \"#{user.name}\""
    +        r.git.sh "git config user.email \"#{user.email}\""
    +        r.git.sh "git checkout -b #{ref} origin/#{ref}"
    +        File.open(path, 'w'){|f| f.write(content)}
    +        r.git.sh "git add ."
    +        r.git.sh "git commit -am '#{commit_message}'"
    +        output = r.git.sh "git push origin #{ref}"
    +
    +        if output =~ %rreject/
    +          return false
    +        end
    +      end
    +    end
    +  end
    +  true
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + can_edit?(path, last_commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/file_editor.rb, line 53
    +def can_edit?(path, last_commit)
    +  current_last_commit = @project.last_commit_for(ref, path).sha
    +  last_commit == current_last_commit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/GitLogger.html b/doc/app/Gitlab/GitLogger.html new file mode 100644 index 00000000..c37bce98 --- /dev/null +++ b/doc/app/Gitlab/GitLogger.html @@ -0,0 +1,523 @@ + + + + + + +class Gitlab::GitLogger - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::GitLogger

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + file_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/git_logger.rb, line 3
    +def self.file_name
    +  'githost.log'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + format_message(severity, timestamp, progname, msg) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/git_logger.rb, line 7
    +def format_message(severity, timestamp, progname, msg)
    +  "#{timestamp.to_s(:long)} -> #{severity} -> #{msg}\n"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Gitolite.html b/doc/app/Gitlab/Gitolite.html new file mode 100644 index 00000000..60ef3b13 --- /dev/null +++ b/doc/app/Gitlab/Gitolite.html @@ -0,0 +1,716 @@ + + + + + + +class Gitlab::Gitolite - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Gitolite

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + config() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 7
    +def config
    +  Gitlab::GitoliteConfig.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create_repository(project) + click to toggle source +
    + + +
    + + + + + +
    + + + + +
    + Alias for: update_repository +
    + +
    + + +
    + +
    + enable_automerge() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 37
    +def enable_automerge
    +  config.admin_all_repo!
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + remove_key(key_id, projects) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 18
    +def remove_key key_id, projects
    +  config.apply do |config|
    +    config.rm_key(key_id)
    +    config.update_projects(projects)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + remove_repository(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 29
    +def remove_repository project
    +  config.destroy_project!(project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + set_key(key_id, key_content, projects) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 11
    +def set_key key_id, key_content, projects
    +  config.apply do |config|
    +    config.write_key(key_id, key_content)
    +    config.update_projects(projects)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_repository(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 25
    +def update_repository project
    +  config.update_project!(project.path, project)
    +end
    +
    + +
    + + +
    + Also aliased as: create_repository +
    + + + +
    + + +
    + +
    + url_to_repo(path) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite.rb, line 33
    +def url_to_repo path
    +  Gitlab.config.ssh_path + "#{path}.git"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Gitolite/AccessDenied.html b/doc/app/Gitlab/Gitolite/AccessDenied.html new file mode 100644 index 00000000..64a3b17a --- /dev/null +++ b/doc/app/Gitlab/Gitolite/AccessDenied.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::Gitolite::AccessDenied - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Gitolite::AccessDenied

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/GitoliteConfig.html b/doc/app/Gitlab/GitoliteConfig.html new file mode 100644 index 00000000..19671089 --- /dev/null +++ b/doc/app/Gitlab/GitoliteConfig.html @@ -0,0 +1,994 @@ + + + + + + +class Gitlab::GitoliteConfig - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::GitoliteConfig

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + conf[R] +
    + +
    + + + +
    +
    + +
    +
    + config_tmp_dir[R] +
    + +
    + + + +
    +
    + +
    +
    + ga_repo[R] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + admin_all_repo() + click to toggle source +
    + + +
    + +

    Enable access to all repos for gitolite admin. We use it for accept merge +request feature

    + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 162
    +def admin_all_repo
    +  owner_name = Gitlab.config.gitolite_admin_key
    +
    +  # @ALL repos premission for gitolite owner
    +  repo_name = "@all"
    +  repo = if conf.has_repo?(repo_name)
    +           conf.get_repo(repo_name)
    +         else
    +           ::Gitolite::Config::Repo.new(repo_name)
    +         end
    +
    +  repo.add_permission("RW+", "", owner_name)
    +  conf.add_repo(repo, true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + admin_all_repo!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 177
    +def admin_all_repo!
    +  apply { |config| config.admin_all_repo }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + apply() { |self| ... } + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 20
    +def apply
    +  Timeout::timeout(30) do
    +    File.open(Rails.root.join('tmp', "gitlabhq-gitolite.lock"), "w+") do |f|
    +      begin
    +        # Set exclusive lock
    +        # to prevent race condition
    +        f.flock(File::LOCK_EX)
    +
    +        # Pull gitolite-admin repo
    +        # in tmp dir before do any changes
    +        pull(config_tmp_dir)
    +
    +        # Build ga_repo object and @conf
    +        # to access gitolite-admin configuration
    +        @conf = ga_repo.config
    +
    +        # Do any changes
    +        # in gitolite-admin
    +        # config here
    +        yield(self)
    +
    +        # Save changes in
    +        # gitolite-admin repo
    +        # before push it
    +        ga_repo.save
    +
    +        # Push gitolite-admin repo
    +        # to apply all changes
    +        push(config_tmp_dir)
    +      ensure
    +        # Remove tmp dir
    +        # removing the gitolite folder first is important to avoid
    +        # NFS issues.
    +        FileUtils.rm_rf(File.join(config_tmp_dir, 'gitolite'))
    +
    +        # Remove parent tmp dir
    +        FileUtils.rm_rf(config_tmp_dir)
    +
    +        # Unlock so other task can access
    +        # gitolite configuration
    +        f.flock(File::LOCK_UN)
    +      end
    +    end
    +  end
    +rescue PullError => ex
    +  log("Pull error ->  " + ex.message)
    +  raise Gitolite::AccessDenied, ex.message
    +
    +rescue PushError => ex
    +  log("Push error ->  " + " " + ex.message)
    +  raise Gitolite::AccessDenied, ex.message
    +
    +rescue Exception => ex
    +  log(ex.class.name + " " + ex.message)
    +  raise Gitolite::AccessDenied.new("gitolite timeout")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy_project(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 81
    +def destroy_project(project)
    +  FileUtils.rm_rf(project.path_to_repo)
    +  conf.rm_repo(project.path)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy_project!(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 86
    +def destroy_project!(project)
    +  apply do |config|
    +    config.destroy_project(project)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + log(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 77
    +def log message
    +  Gitlab::GitLogger.error(message)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + rm_key(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 98
    +def rm_key(user)
    +  key_path = File.join(config_tmp_dir, 'gitolite/keydir', "#{user}.pub")
    +  ga_key = ::Gitolite::SSHKey.from_file(key_path)
    +  ga_repo.rm_key(ga_key)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_project(repo_name, project) + click to toggle source +
    + + +
    + +

    update or create

    + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 105
    +def update_project(repo_name, project)
    +  repo = update_project_config(project, conf)
    +  conf.add_repo(repo, true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_project!(repo_name, project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 110
    +def update_project!(repo_name, project)
    +  apply do |config|
    +    config.update_project(repo_name, project)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_project_config(project, conf) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 125
    +def update_project_config(project, conf)
    +  repo_name = project.path
    +
    +  repo = if conf.has_repo?(repo_name)
    +           conf.get_repo(repo_name)
    +         else
    +           ::Gitolite::Config::Repo.new(repo_name)
    +         end
    +
    +  name_readers = project.repository_readers
    +  name_writers = project.repository_writers
    +  name_masters = project.repository_masters
    +
    +  pr_br = project.protected_branches.map(&:name).join("$ ")
    +
    +  repo.clean_permissions
    +
    +  # Deny access to protected branches for writers
    +  unless name_writers.blank? || pr_br.blank?
    +    repo.add_permission("-", pr_br.strip + "$ ", name_writers)
    +  end
    +
    +  # Add read permissions
    +  repo.add_permission("R", "", name_readers) unless name_readers.blank?
    +
    +  # Add write permissions
    +  repo.add_permission("RW+", "", name_writers) unless name_writers.blank?
    +  repo.add_permission("RW+", "", name_masters) unless name_masters.blank?
    +
    +  # Add sharedRepository config
    +  repo.set_git_config("core.sharedRepository", "0660")
    +
    +  repo
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_projects(projects) + click to toggle source +
    + + +
    + +

    Updates many projects and uses project.path as the repo path An order of +magnitude faster than #update_project

    + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 118
    +def update_projects(projects)
    +  projects.each do |project|
    +    repo = update_project_config(project, conf)
    +    conf.add_repo(repo, true)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + write_key(id, key) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/gitolite_config.rb, line 92
    +def write_key(id, key)
    +  File.open(File.join(config_tmp_dir, 'gitolite/keydir',"#{id}.pub"), 'w') do |f|
    +    f.write(key.gsub(%r\n/,''))
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/GitoliteConfig/PullError.html b/doc/app/Gitlab/GitoliteConfig/PullError.html new file mode 100644 index 00000000..8e5a1510 --- /dev/null +++ b/doc/app/Gitlab/GitoliteConfig/PullError.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::GitoliteConfig::PullError - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::GitoliteConfig::PullError

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/GitoliteConfig/PushError.html b/doc/app/Gitlab/GitoliteConfig/PushError.html new file mode 100644 index 00000000..c1541f49 --- /dev/null +++ b/doc/app/Gitlab/GitoliteConfig/PushError.html @@ -0,0 +1,439 @@ + + + + + + +class Gitlab::GitoliteConfig::PushError - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::GitoliteConfig::PushError

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/GraphCommit.html b/doc/app/Gitlab/GraphCommit.html new file mode 100644 index 00000000..b8ffa6f4 --- /dev/null +++ b/doc/app/Gitlab/GraphCommit.html @@ -0,0 +1,967 @@ + + + + + + +class Gitlab::GraphCommit - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::GraphCommit

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + refs[RW] +
    + +
    + + + +
    +
    + +
    +
    + space[RW] +
    + +
    + + + +
    +
    + +
    +
    + time[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + find_free_space(time_range) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 113
    +def self.find_free_space(time_range)
    +  reserved = []
    +  for day in time_range
    +      reserved += @_reserved[day]
    +  end
    +  space = 1
    +  while reserved.include? space do
    +    space += 1
    +  end
    +  space
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index_commits(commits) + click to toggle source +
    + + +
    + +

    Method is adding time and space on the list of commits. As well as returns +date list corelated with time set on commits.

    + +

    @param [Array<GraphCommit>] comits to index

    + +

    @return [Array<TimeDate>] list of commit dates corelated with time on +commits

    + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 33
    +def self.index_commits(commits)
    +  days, heads = [], []
    +  map = {}
    +
    +  commits.reverse.each_with_index do |c,i|
    +    c.time = i
    +    days[i] = c.committed_date
    +    map[c.id] = c
    +    heads += c.refs unless c.refs.nil?
    +  end
    +
    +  heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
    +  # sort heads so the master is top and current branches are closer
    +  heads.sort! do |a,b|
    +    if a.name == "master"
    +      -1
    +    elsif b.name == "master"
    +      1
    +    else
    +      b.commit.committed_date <=> a.commit.committed_date
    +    end
    +  end
    +
    +  @_reserved = {}
    +  days.each_index do |i|
    +    @_reserved[i] = []
    +  end
    +
    +  heads.each do |h|
    +    if map.include? h.commit.id then
    +      place_chain(map[h.commit.id], map)
    +    end
    +  end
    +  days
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mark_reserved(time_range, space) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 107
    +def self.mark_reserved(time_range, space)
    +  for day in time_range
    +    @_reserved[day].push(space)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new(commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 148
    +def initialize(commit)
    +  @_commit = commit
    +  @time = -1
    +  @space = 0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + place_chain(commit, map, parent_time = nil) + click to toggle source +
    + + +
    + +

    Add space mark on commit and its parents

    + +

    @param [GraphCommit] the commit object. @param +[Hash<String,GraphCommit>] map of commits

    + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 73
    +def self.place_chain(commit, map, parent_time = nil)
    +  leaves = take_left_leaves(commit, map)
    +  if leaves.empty? then
    +    return
    +  end
    +  space = find_free_space(leaves.last.time..leaves.first.time)
    +  leaves.each{|l| l.space = space}
    +  # and mark it as reserved
    +  min_time = leaves.last.time
    +  parents = leaves.last.parents.collect
    +  parents.each do |p|
    +    if map.include? p.id then
    +      parent = map[p.id]
    +      if parent.time < min_time then
    +        min_time = parent.time
    +      end
    +    end
    +  end
    +  if parent_time.nil? then
    +    max_time = leaves.first.time
    +  else
    +    max_time = parent_time - 1
    +  end
    +  mark_reserved(min_time..max_time, space)
    +  # Visit branching chains
    +  leaves.each do |l|
    +    parents = l.parents.collect
    +      .select{|p| map.include? p.id and map[p.id].space == 0}
    +    for p in parents
    +      place_chain(map[p.id], map, l.time)
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + take_left_leaves(commit, map) + click to toggle source +
    + + +
    + +

    Takes most left subtree branch of commits which don’t have space mark yet.

    + +

    @param [GraphCommit] the commit object. @param +[Hash<String,GraphCommit>] map of commits

    + +

    @return [Array<GraphCommit>] list of branch commits

    + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 132
    +def self.take_left_leaves(commit, map)
    +  leaves = []
    +  leaves.push(commit)  if commit.space == 0
    +  while true
    +    parent = commit.parents.collect
    +      .select{|p| map.include? p.id and map[p.id].space == 0}
    +    if parent.count == 0 then
    +      return leaves
    +    else
    +      commit = map[parent.first.id]
    +      leaves.push(commit)
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_graph(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 10
    +def self.to_graph(project)
    +  @repo = project.repo
    +  commits = Grit::Commit.find_all(@repo, nil, {max_count: 650})
    +
    +  ref_cache = {}
    +
    +  commits.map! {|c| GraphCommit.new(Commit.new(c))}
    +  commits.each { |commit| commit.add_refs(ref_cache, @repo) }
    +
    +  days = GraphCommit.index_commits(commits)
    +  @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
    +  @commits_json = commits.map(&:to_graph_hash).to_json
    +
    +  return @days_json, @commits_json
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + add_refs(ref_cache, repo) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 174
    +def add_refs(ref_cache, repo)
    +  if ref_cache.empty?
    +    repo.refs.each do |ref|
    +      ref_cache[ref.commit.id] ||= []
    +      ref_cache[ref.commit.id] << ref
    +    end
    +  end
    +  @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)
    +  @refs ||= []
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + method_missing(m, *args, &block) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 154
    +def method_missing(m, *args, &block)
    +  @_commit.send(m, *args, &block)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_graph_hash() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/graph_commit.rb, line 158
    +def to_graph_hash
    +  h = {}
    +  h[:parents] = self.parents.collect do |p|
    +    [p.id,0,0]
    +  end
    +  h[:author]  = Gitlab::Encode.utf8(author.name)
    +  h[:time]    = time
    +  h[:space]   = space
    +  h[:refs]    = refs.collect{|r|r.name}.join(" ") unless refs.nil?
    +  h[:id]      = sha
    +  h[:date]    = date
    +  h[:message] = escape_once(Gitlab::Encode.utf8(message))
    +  h[:login]   = author.email
    +  h
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/InlineDiff.html b/doc/app/Gitlab/InlineDiff.html new file mode 100644 index 00000000..91eeae9c --- /dev/null +++ b/doc/app/Gitlab/InlineDiff.html @@ -0,0 +1,611 @@ + + + + + + +class Gitlab::InlineDiff - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::InlineDiff

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    FINISH + +
    + + +
    START + +
    + + +
    +
    + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + _indexes_of_changed_lines(diff_arr) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/inline_diff.rb, line 42
    +def _indexes_of_changed_lines diff_arr
    +  chain_of_first_symbols = ""
    +  diff_arr.each_with_index do |line, i|
    +    chain_of_first_symbols += line[0]
    +  end
    +  chain_of_first_symbols.gsub!(%r[^\-\+]/, "#")
    +
    +  offset = 0
    +  indexes = []
    +  while index = chain_of_first_symbols.index("#-+#", offset)
    +    indexes << index
    +    offset = index + 1
    +  end
    +  indexes
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + processing(diff_arr) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/inline_diff.rb, line 8
    +def processing diff_arr
    +  indexes = _indexes_of_changed_lines diff_arr
    +
    +  indexes.each do |index|
    +    first_line = diff_arr[index+1]
    +    second_line = diff_arr[index+2]
    +    max_length = [first_line.size, second_line.size].max
    +
    +    first_the_same_symbols = 0
    +    (0..max_length + 1).each do |i|
    +      first_the_same_symbols = i - 1
    +      if first_line[i] != second_line[i] && i > 0
    +        break
    +      end
    +    end
    +    first_token = first_line[0..first_the_same_symbols][1..-1]
    +    diff_arr[index+1].sub!(first_token, first_token + START)
    +    diff_arr[index+2].sub!(first_token, first_token + START)
    +    last_the_same_symbols = 0
    +    (1..max_length + 1).each do |i|
    +      last_the_same_symbols = -i
    +      shortest_line = second_line.size > first_line.size ? first_line : second_line
    +      if ( first_line[-i] != second_line[-i] ) || "#{first_token}#{START}".size == shortest_line[1..-i].size
    +        break
    +      end
    +    end
    +    last_the_same_symbols += 1
    +    last_token = first_line[last_the_same_symbols..-1]
    +    diff_arr[index+1].sub!(%r#{Regexp.escape(last_token)}$/, FINISH + last_token)
    +    diff_arr[index+2].sub!(%r#{Regexp.escape(last_token)}$/, FINISH + last_token)
    +  end
    +  diff_arr
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + replace_markers(line) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/inline_diff.rb, line 58
    +def replace_markers line
    +  line.gsub!(START, "<span class='idiff'>")
    +  line.gsub!(FINISH, "</span>")
    +  line
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Issues.html b/doc/app/Gitlab/Issues.html new file mode 100644 index 00000000..eda99ed1 --- /dev/null +++ b/doc/app/Gitlab/Issues.html @@ -0,0 +1,441 @@ + + + + + + +class Gitlab::Issues - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Issues

    + +
    + +

    Issues API

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Logger.html b/doc/app/Gitlab/Logger.html new file mode 100644 index 00000000..8cc6cdea --- /dev/null +++ b/doc/app/Gitlab/Logger.html @@ -0,0 +1,583 @@ + + + + + + +class Gitlab::Logger - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Logger

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + build() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/logger.rb, line 17
    +def self.build
    +  new(Rails.root.join("log", file_name))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + error(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/logger.rb, line 3
    +def self.error(message)
    +  build.error(message)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + info(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/logger.rb, line 7
    +def self.info(message)
    +  build.info(message)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + read_latest() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/logger.rb, line 11
    +def self.read_latest
    +  path = Rails.root.join("log", file_name)
    +  self.build unless File.exist?(path)
    +  logs = File.read(path).split("\n")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Markdown.html b/doc/app/Gitlab/Markdown.html new file mode 100644 index 00000000..12691455 --- /dev/null +++ b/doc/app/Gitlab/Markdown.html @@ -0,0 +1,580 @@ + + + + + + +module Gitlab::Markdown - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Gitlab::Markdown

    + +
    + +

    Custom parser for GitLab-flavored Markdown

    + +

    It replaces references in the text with links to the appropriate items in +GitLab.

    + +

    Supported reference formats are:

    + +
    * @foo for team members
    +* #123 for issues
    +* !123 for merge requests
    +* $123 for snippets
    +* 123456 for commits
    + +

    It also parses Emoji codes to insert images. See www.emoji-cheat-sheet.com/ for +a list of the supported icons.

    + +

    Examples

    + +
    >> gfm("Hey @david, can you fix this?")
    +=> "Hey <a href="/gitlab/team_members/1">@david</a>, can you fix this?"
    +
    +>> gfm("Commit 35d5f7c closes #1234")
    +=> "Commit <a href="/gitlab/commits/35d5f7c">35d5f7c</a> closes <a href="/gitlab/issues/1234">#1234</a>"
    +
    +>> gfm(":trollface:")
    +=> "<img alt=\":trollface:\" class=\"emoji\" src=\"/images/trollface.png" title=\":trollface:\" />
    +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    EMOJI_PATTERN + +
    + + +
    REFERENCE_PATTERN + +
    + + +
    +
    + + + + +
    +

    Attributes

    + + +
    +
    + html_options[R] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + gfm(text, html_options = {}) + click to toggle source +
    + + +
    + +

    Public: Parse the provided text with GitLab-Flavored Markdown

    + +

    text - the source text #html_options - extra +options for the reference links as given to link_to

    + +

    Note: reference links will only be generated if @project is set

    + + + +
    +
    # File lib/gitlab/markdown.rb, line 48
    +def gfm(text, html_options = {})
    +  return text if text.nil?
    +
    +  # Duplicate the string so we don't alter the original, then call to_str
    +  # to cast it back to a String instead of a SafeBuffer. This is required
    +  # for gsub calls to work as we need them to.
    +  text = text.dup.to_str
    +
    +  @html_options = html_options
    +
    +  # Extract pre blocks so they are not altered
    +  # from http://github.github.com/github-flavored-markdown/
    +  extractions = {}
    +  text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}) do |match|
    +    md5 = Digest::MD5.hexdigest(match)
    +    extractions[md5] = match
    +    "{gfm-extraction-#{md5}}"
    +  end
    +
    +  # TODO: add popups with additional information
    +
    +  text = parse(text)
    +
    +  # Insert pre block extractions
    +  text.gsub!(%r\{gfm-extraction-(\h{32})\}/) do
    +    extractions[$1]
    +  end
    +
    +  sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Merge.html b/doc/app/Gitlab/Merge.html new file mode 100644 index 00000000..99a66cd5 --- /dev/null +++ b/doc/app/Gitlab/Merge.html @@ -0,0 +1,628 @@ + + + + + + +class Gitlab::Merge - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Merge

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + merge_request[RW] +
    + +
    + + + +
    +
    + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    +
    + user[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(merge_request, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/merge.rb, line 5
    +def initialize(merge_request, user)
    +  @merge_request = merge_request
    +  @project = merge_request.project
    +  @user = user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + can_be_merged?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/merge.rb, line 11
    +def can_be_merged?
    +  in_locked_and_timed_satellite do |merge_repo|
    +    merge_in_satellite!(merge_repo)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge!() + click to toggle source +
    + + +
    + +

    Merges the source branch into the target branch in the satellite and pushes +it back to Gitolite. It also removes the source +branch if requested in the merge request.

    + +

    Returns false if the merge produced conflicts Returns false if pushing from +the satallite to Gitolite failed or was +rejected Returns true otherwise

    + + + +
    +
    # File lib/gitlab/merge.rb, line 24
    +def merge!
    +  in_locked_and_timed_satellite do |merge_repo|
    +    if merge_in_satellite!(merge_repo)
    +      # push merge back to Gitolite
    +      # will raise CommandFailed when push fails
    +      merge_repo.git.push({raise: true}, :origin, merge_request.target_branch)
    +
    +      # remove source branch
    +      if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch)
    +        # will raise CommandFailed when push fails
    +        merge_repo.git.push({raise: true}, :origin, ":#{merge_request.source_branch}")
    +      end
    +
    +      # merge, push and branch removal successful
    +      true
    +    end
    +  end
    +rescue Grit::Git::CommandFailed
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Milestones.html b/doc/app/Gitlab/Milestones.html new file mode 100644 index 00000000..aac605b2 --- /dev/null +++ b/doc/app/Gitlab/Milestones.html @@ -0,0 +1,441 @@ + + + + + + +class Gitlab::Milestones - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Milestones

    + +
    + +

    Milestones API

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Projects.html b/doc/app/Gitlab/Projects.html new file mode 100644 index 00000000..a44cba3c --- /dev/null +++ b/doc/app/Gitlab/Projects.html @@ -0,0 +1,441 @@ + + + + + + +class Gitlab::Projects - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Projects

    + +
    + +

    Projects API

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Satellite.html b/doc/app/Gitlab/Satellite.html new file mode 100644 index 00000000..4615d1c6 --- /dev/null +++ b/doc/app/Gitlab/Satellite.html @@ -0,0 +1,664 @@ + + + + + + +class Gitlab::Satellite - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Satellite

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    PARKING_BRANCH + +
    + + +
    +
    + + + + +
    +

    Attributes

    + + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/satellite.rb, line 8
    +def initialize project
    +  self.project = project
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + clear() + click to toggle source +
    + + +
    + +

    will be deleted all branches except PARKING_BRANCH

    + + + +
    +
    # File lib/gitlab/satellite.rb, line 25
    +def clear
    +  Dir.chdir(path) do
    +    heads = Grit::Repo.new(".").heads.map{|head| head.name}
    +    if heads.include? PARKING_BRANCH
    +      %xgit checkout #{PARKING_BRANCH}`
    +    else
    +      %xgit checkout -b #{PARKING_BRANCH}`
    +    end
    +    heads.delete(PARKING_BRANCH)
    +    heads.each do |head|
    +      %xgit branch -D #{head}`
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/satellite.rb, line 12
    +def create
    +  %xgit clone #{project.url_to_repo} #{path}`
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + exists?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/satellite.rb, line 20
    +def exists?
    +  File.exists? path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + path() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/satellite.rb, line 16
    +def path
    +  Rails.root.join("tmp", "repo_satellites", project.path)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Session.html b/doc/app/Gitlab/Session.html new file mode 100644 index 00000000..12f3433e --- /dev/null +++ b/doc/app/Gitlab/Session.html @@ -0,0 +1,441 @@ + + + + + + +class Gitlab::Session - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Session

    + +
    + +

    Users API

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Theme.html b/doc/app/Gitlab/Theme.html new file mode 100644 index 00000000..00b3e5f6 --- /dev/null +++ b/doc/app/Gitlab/Theme.html @@ -0,0 +1,493 @@ + + + + + + +class Gitlab::Theme - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Theme

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + css_class_by_id(id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/theme.rb, line 3
    +def self.css_class_by_id(id)
    +  themes = { 
    +    1 => "ui_basic",
    +    2 => "ui_mars",
    +    3 => "ui_modern"
    +  }
    +
    +  id ||= 1
    +
    +  return themes[id]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Gitlab/Users.html b/doc/app/Gitlab/Users.html new file mode 100644 index 00000000..c9712874 --- /dev/null +++ b/doc/app/Gitlab/Users.html @@ -0,0 +1,441 @@ + + + + + + +class Gitlab::Users - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Gitlab::Users

    + +
    + +

    Users API

    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/GitlabMarkdownHelper.html b/doc/app/GitlabMarkdownHelper.html new file mode 100644 index 00000000..6bf172ac --- /dev/null +++ b/doc/app/GitlabMarkdownHelper.html @@ -0,0 +1,559 @@ + + + + + + +module GitlabMarkdownHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module GitlabMarkdownHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + + + + +
    + +
    + markdown(text) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/gitlab_markdown_helper.rb, line 25
    +def markdown(text)
    +  unless @markdown
    +    gitlab_renderer = Redcarpet::Render::GitlabHTML.new(self,
    +                        # see https://github.com/vmg/redcarpet#darling-i-packed-you-a-couple-renderers-for-lunch-
    +                        filter_html: true,
    +                        with_toc_data: true,
    +                        hard_wrap: true)
    +    @markdown = Redcarpet::Markdown.new(gitlab_renderer,
    +                    # see https://github.com/vmg/redcarpet#and-its-like-really-simple-to-use
    +                    no_intra_emphasis: true,
    +                    tables: true,
    +                    fenced_code_blocks: true,
    +                    autolink: true,
    +                    strikethrough: true,
    +                    lax_html_blocks: true,
    +                    space_after_headers: true,
    +                    superscript: true)
    +  end
    +
    +  @markdown.render(text).html_safe
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Grack.html b/doc/app/Grack.html new file mode 100644 index 00000000..e3c5bbd4 --- /dev/null +++ b/doc/app/Grack.html @@ -0,0 +1,433 @@ + + + + + + +module Grack - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Grack

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Grack/Auth.html b/doc/app/Grack/Auth.html new file mode 100644 index 00000000..5da483f7 --- /dev/null +++ b/doc/app/Grack/Auth.html @@ -0,0 +1,734 @@ + + + + + + +class Grack::Auth - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Grack::Auth

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    +
    + user[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + can?(object, action, subject) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 56
    +def can?(object, action, subject)
    +  abilities.allowed?(object, action, subject)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + current_ref() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 60
    +def current_ref
    +  if @env["HTTP_CONTENT_ENCODING"] =~ %rgzip/
    +    input = Zlib::GzipReader.new(@request.body).read
    +  else
    +    input = @request.body.read
    +  end
    +  # Need to reset seek point
    +  @request.body.rewind
    +  %rrefs\/heads\/([\w-]+)/.match(input).to_a.first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + valid?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 5
    +def valid?
    +  # Authentication with username and password
    +  email, password = @auth.credentials
    +  self.user = User.find_by_email(email)
    +  return false unless user.try(:valid_password?, password)
    +
    +  # Set GL_USER env variable
    +  ENV['GL_USER'] = email
    +  # Pass Gitolite update hook
    +  ENV['GL_BYPASS_UPDATE_HOOK'] = "true"
    +
    +  # Need this patch due to the rails mount
    +  @env['PATH_INFO'] = @request.path
    +  @env['SCRIPT_NAME'] = ""
    +
    +  # Find project by PATH_INFO from env
    +  if m = %r^\/([\w-]+).git/.match(@request.path_info).to_a
    +    self.project = Project.find_by_path(m.last)
    +    return false unless project
    +  end
    +
    +  # Git upload and receive
    +  if @request.get?
    +    validate_get_request
    +  elsif @request.post?
    +    validate_post_request
    +  else
    +    false
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + validate_get_request() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 36
    +def validate_get_request
    +  true
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + validate_post_request() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 40
    +def validate_post_request
    +  if @request.path_info.end_with?('git-upload-pack')
    +    can?(user, :push_code, project)
    +  elsif @request.path_info.end_with?('git-receive-pack')
    +    action = if project.protected_branch?(current_ref)
    +               :push_code_to_protected_branches
    +             else
    +               :push_code
    +             end
    +
    +    can?(user, action, project)
    +  else
    +    false
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + abilities() + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/gitlab/backend/grack_auth.rb, line 73
    +def abilities
    +  @abilities ||= begin
    +                   abilities = Six.new
    +                   abilities << Ability
    +                   abilities
    +                 end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Group.html b/doc/app/Group.html new file mode 100644 index 00000000..a23e1da6 --- /dev/null +++ b/doc/app/Group.html @@ -0,0 +1,555 @@ + + + + + + +class Group - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Group

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + + + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + to_param() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/group.rb, line 17
    +def to_param
    +  code
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + users() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/group.rb, line 21
    +def users
    +  User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/GroupsController.html b/doc/app/GroupsController.html new file mode 100644 index 00000000..72e1022c --- /dev/null +++ b/doc/app/GroupsController.html @@ -0,0 +1,735 @@ + + + + + + +class GroupsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class GroupsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + issues() + click to toggle source +
    + + +
    + +

    Get only assigned issues

    + + + +
    +
    # File app/controllers/groups_controller.rb, line 26
    +def issues
    +  @user   = current_user
    +  @issues = current_user.assigned_issues.opened
    +  @issues = @issues.of_group(@group).recent.page(params[:page]).per(20)
    +  @issues = @issues.includes(:author, :project)
    +
    +  respond_to do |format|
    +    format.html
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_requests() + click to toggle source +
    + + +
    + +

    Get authored or assigned open merge requests

    + + + +
    +
    # File app/controllers/groups_controller.rb, line 20
    +def merge_requests
    +  @merge_requests = current_user.cared_merge_requests
    +  @merge_requests = @merge_requests.of_group(@group).recent.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + people() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/groups_controller.rb, line 46
    +def people
    +  @users = group.users.all
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/groups_controller.rb, line 8
    +def show
    +  @events = Event.in_projects(project_ids).limit(20).offset(params[:offset] || 0)
    +  @last_push = current_user.recent_push
    +
    +  respond_to do |format|
    +    format.html
    +    format.js
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + group() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/groups_controller.rb, line 52
    +def group
    +  @group ||= Group.find_by_code(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_ids() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/groups_controller.rb, line 60
    +def project_ids
    +  projects.map(&:id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + projects() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/groups_controller.rb, line 56
    +def projects
    +  @projects ||= current_user.projects_with_events.where(group_id: @group.id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/HelpController.html b/doc/app/HelpController.html new file mode 100644 index 00000000..afbbeb0b --- /dev/null +++ b/doc/app/HelpController.html @@ -0,0 +1,484 @@ + + + + + + +class HelpController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class HelpController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/help_controller.rb, line 2
    +def index
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/HooksController.html b/doc/app/HooksController.html new file mode 100644 index 00000000..70fd89c3 --- /dev/null +++ b/doc/app/HooksController.html @@ -0,0 +1,595 @@ + + + + + + +class HooksController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class HooksController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/hooks_controller.rb, line 13
    +def create
    +  @hook = @project.hooks.new(params[:hook])
    +  @hook.save
    +
    +  if @hook.valid?
    +    redirect_to project_hooks_path(@project)
    +  else
    +    @hooks = @project.hooks.all
    +    render :index
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/hooks_controller.rb, line 31
    +def destroy
    +  @hook = @project.hooks.find(params[:id])
    +  @hook.destroy
    +
    +  redirect_to project_hooks_path(@project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/hooks_controller.rb, line 8
    +def index
    +  @hooks = @project.hooks.all
    +  @hook = ProjectHook.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + test() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/hooks_controller.rb, line 25
    +def test
    +  TestHookContext.new(project, current_user, params).execute
    +
    +  redirect_to :back
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Issue.html b/doc/app/Issue.html new file mode 100644 index 00000000..e8a7881c --- /dev/null +++ b/doc/app/Issue.html @@ -0,0 +1,501 @@ + + + + + + +class Issue - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Issue

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + open_for(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/issue.rb, line 14
    +def self.open_for(user)
    +  opened.assigned(user)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssueCommonality.html b/doc/app/IssueCommonality.html new file mode 100644 index 00000000..336580d8 --- /dev/null +++ b/doc/app/IssueCommonality.html @@ -0,0 +1,641 @@ + + + + + + +module IssueCommonality - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module IssueCommonality

    + +
    + +

    Contains common functionality shared between Issues and MergeRequests

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + is_assigned?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 50
    +def is_assigned?
    +  !!assignee_id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_being_closed?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 58
    +def is_being_closed?
    +  closed_changed? && closed
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_being_reassigned?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 54
    +def is_being_reassigned?
    +  assignee_id_changed?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_being_reopened?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 62
    +def is_being_reopened?
    +  closed_changed? && !closed
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 46
    +def new?
    +  today? && created_at == updated_at
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + today?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/issue_commonality.rb, line 42
    +def today?
    +  Date.today == created_at.to_date
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssueCommonality/ClassMethods.html b/doc/app/IssueCommonality/ClassMethods.html new file mode 100644 index 00000000..d4ab179d --- /dev/null +++ b/doc/app/IssueCommonality/ClassMethods.html @@ -0,0 +1,479 @@ + + + + + + +module IssueCommonality::ClassMethods - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module IssueCommonality::ClassMethods

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + + + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssueObserver.html b/doc/app/IssueObserver.html new file mode 100644 index 00000000..7f16a865 --- /dev/null +++ b/doc/app/IssueObserver.html @@ -0,0 +1,571 @@ + + + + + + +class IssueObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class IssueObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(issue) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/issue_observer.rb, line 4
    +def after_create(issue)
    +  if issue.assignee && issue.assignee != current_user
    +    Notify.new_issue_email(issue.id).deliver 
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_update(issue) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/issue_observer.rb, line 10
    +def after_update(issue)
    +  send_reassigned_email(issue) if issue.is_being_reassigned?
    +
    +  status = nil
    +  status = 'closed' if issue.is_being_closed?
    +  status = 'reopened' if issue.is_being_reopened?
    +  if status
    +    Note.create_status_change_note(issue, current_user, status) 
    +    [issue.author, issue.assignee].compact.each do |recipient| 
    +      Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user)
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + send_reassigned_email(issue) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/issue_observer.rb, line 26
    +def send_reassigned_email(issue)
    +  recipient_ids = [issue.assignee_id, issue.assignee_id_was].keep_if {|id| id && id != current_user.id }
    +
    +  recipient_ids.each do |recipient_id|
    +    Notify.reassigned_issue_email(recipient_id, issue.id, issue.assignee_id_was).deliver
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssuesBulkUpdateContext.html b/doc/app/IssuesBulkUpdateContext.html new file mode 100644 index 00000000..1d87a757 --- /dev/null +++ b/doc/app/IssuesBulkUpdateContext.html @@ -0,0 +1,503 @@ + + + + + + +class IssuesBulkUpdateContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class IssuesBulkUpdateContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/issues_bulk_update_context.rb, line 2
    +def execute
    +  update_data = params[:update]
    +
    +  issues_ids   = update_data[:issues_ids].split(",")
    +  milestone_id = update_data[:milestone_id]
    +  assignee_id  = update_data[:assignee_id]
    +  status       = update_data[:status]
    +
    +  opts = {} 
    +  opts[:milestone_id] = milestone_id if milestone_id.present?
    +  opts[:assignee_id] = assignee_id if assignee_id.present?
    +  opts[:closed] = (status == "closed") if status.present?
    +
    +  issues = Issue.where(id: issues_ids).all
    +  issues = issues.select { |issue| can?(current_user, :modify_issue, issue) }
    +  issues.each { |issue| issue.update_attributes(opts) }
    +  { 
    +    count: issues.count,
    +    success: !issues.count.zero?
    +  }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssuesController.html b/doc/app/IssuesController.html new file mode 100644 index 00000000..6b3edbb6 --- /dev/null +++ b/doc/app/IssuesController.html @@ -0,0 +1,996 @@ + + + + + + +class IssuesController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class IssuesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + bulk_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 111
    +def bulk_update
    +  result = IssuesBulkUpdateContext.new(project, current_user, params).execute
    +  redirect_to :back, notice: "#{result[:count]} issues updated"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 48
    +def create
    +  @issue = @project.issues.new(params[:issue])
    +  @issue.author = current_user
    +  @issue.save
    +
    +  respond_to do |format|
    +    format.html do
    +      if @issue.valid?
    +        redirect_to project_issue_path(@project, @issue)
    +      else
    +        render :new
    +      end
    +    end
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 80
    +def destroy
    +  @issue.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_issues_path }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 35
    +def edit
    +  respond_with(@issue)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 19
    +def index
    +  @issues = issues_filtered
    +  @issues = @issues.page(params[:page]).per(20)
    +
    +  respond_to do |format|
    +    format.html # index.html.erb
    +    format.js
    +    format.atom { render layout: false }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 30
    +def new
    +  @issue = @project.issues.new(params[:issue])
    +  respond_with(@issue)
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 39
    +def show
    +  @note = @project.notes.new(noteable: @issue)
    +
    +  respond_to do |format|
    +    format.html
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + sort() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 89
    +def sort
    +  return render_404 unless can?(current_user, :admin_issue, @project)
    +
    +  @issues = @project.issues.where(id: params['issue'])
    +  @issues.each do |issue|
    +    issue.position = params['issue'].index(issue.id.to_s) + 1
    +    issue.save
    +  end
    +
    +  render nothing: true
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 65
    +def update
    +  @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
    +
    +  respond_to do |format|
    +    format.js
    +    format.html do
    +      if @issue.valid?
    +        redirect_to [@project, @issue]
    +      else
    +        render :edit
    +      end
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + authorize_admin_issue!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 126
    +def authorize_admin_issue!
    +  return render_404 unless can?(current_user, :admin_issue, @issue)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize_modify_issue!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 122
    +def authorize_modify_issue!
    +  return render_404 unless can?(current_user, :modify_issue, @issue)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issue() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 118
    +def issue
    +  @issue ||= @project.issues.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issues_filtered() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 134
    +def issues_filtered
    +  @issues = IssuesListContext.new(project, current_user, params).execute
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + module_enabled() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/issues_controller.rb, line 130
    +def module_enabled
    +  return render_404 unless @project.issues_enabled
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssuesHelper.html b/doc/app/IssuesHelper.html new file mode 100644 index 00000000..d58a5f7f --- /dev/null +++ b/doc/app/IssuesHelper.html @@ -0,0 +1,698 @@ + + + + + + +module IssuesHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module IssuesHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + issue_css_classes(issue) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/issues_helper.rb, line 29
    +def issue_css_classes issue
    +  classes = "issue"
    +  classes << " closed" if issue.closed
    +  classes << " today" if issue.today?
    +  classes
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issue_tags() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/issues_helper.rb, line 36
    +def issue_tags
    +  @project.issues.tag_counts_on(:labels).map(&:name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issues_filter() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/issues_helper.rb, line 47
    +def issues_filter
    +  {
    +    all: "all",
    +    closed: "closed",
    +    to_me: "assigned-to-me",
    +    open: "open"
    +  }
    +end
    +
    + +
    + + + + +
    + + + + + + + + +
    + +
    + project_issues_filter_path(project, params = {}) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/issues_helper.rb, line 2
    +def project_issues_filter_path project, params = {}
    +  params[:f] ||= cookies['issue_filter']
    +  project_issues_path project, params
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unassigned_filter() + click to toggle source +
    + + +
    + +

    Returns an OpenStruct object suitable for use by +options_from_collection_for_select to allow filtering issues +by an unassigned User or Milestone

    + + + +
    +
    # File app/helpers/issues_helper.rb, line 42
    +def unassigned_filter
    +  # Milestone uses :title, Issue uses :name
    +  OpenStruct.new(id: 0, title: 'Unspecified', name: 'Unassigned')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/IssuesListContext.html b/doc/app/IssuesListContext.html new file mode 100644 index 00000000..01acec45 --- /dev/null +++ b/doc/app/IssuesListContext.html @@ -0,0 +1,537 @@ + + + + + + +class IssuesListContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class IssuesListContext

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + issues[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/issues_list_context.rb, line 6
    +def execute
    +  @issues = case params[:f]
    +            when issues_filter[:all] then @project.issues
    +            when issues_filter[:closed] then @project.issues.closed
    +            when issues_filter[:to_me] then @project.issues.opened.assigned(current_user)
    +            else @project.issues.opened
    +            end
    +
    +  @issues = @issues.tagged_with(params[:label_name]) if params[:label_name].present?
    +  @issues = @issues.includes(:author, :project).order("updated_at")
    +
    +  # Filter by specific assignee_id (or lack thereof)?
    +  if params[:assignee_id].present?
    +    @issues = @issues.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id]))
    +  end
    +
    +  # Filter by specific milestone_id (or lack thereof)?
    +  if params[:milestone_id].present?
    +    @issues = @issues.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id]))
    +  end
    +
    +  @issues
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Key.html b/doc/app/Key.html new file mode 100644 index 00000000..afbcea93 --- /dev/null +++ b/doc/app/Key.html @@ -0,0 +1,700 @@ + + + + + + +class Key - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Key

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + fingerprintable_key() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 30
    +def fingerprintable_key
    +  return true unless key # Don't test if there is no key.
    +  # `ssh-keygen -lf /dev/stdin <<< "#{key}"` errors with: redirection unexpected
    +  file = Tempfile.new('key_file')
    +  begin
    +    file.puts key
    +    file.rewind
    +    fingerprint_output = %xssh-keygen -lf #{file.path} 2>&1` # Catch stderr.
    +  ensure
    +    file.close
    +    file.unlink # deletes the temp file
    +  end
    +  errors.add(:key, "can't be fingerprinted") if fingerprint_output.match("failed")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_deploy_key() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 53
    +def is_deploy_key
    +  true if project_id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_deploy?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 66
    +def last_deploy?
    +  Key.where(identifier: identifier).count == 0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + projects() + click to toggle source +
    + + +
    + +

    projects that has this key

    + + + +
    +
    # File app/models/key.rb, line 58
    +def projects
    +  if is_deploy_key
    +    [project]
    +  else
    +    user.projects
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + set_identifier() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 45
    +def set_identifier
    +  if is_deploy_key
    +    self.identifier = "deploy_#{Digest::MD5.hexdigest(key)}"
    +  else
    +    self.identifier = "#{user.identifier}_#{Time.now.to_i}"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + strip_white_space() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 18
    +def strip_white_space
    +  self.key = self.key.strip unless self.key.blank?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unique_key() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/key.rb, line 22
    +def unique_key
    +  query = Key.where(key: key)
    +  query = query.where('(project_id IS NULL OR project_id = ?)', project_id) if project_id
    +  if (query.count > 0)
    +    errors.add :key, 'already exist.'
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/KeyObserver.html b/doc/app/KeyObserver.html new file mode 100644 index 00000000..bdaf9f84 --- /dev/null +++ b/doc/app/KeyObserver.html @@ -0,0 +1,530 @@ + + + + + + +class KeyObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class KeyObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_destroy(key) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/key_observer.rb, line 8
    +def after_destroy(key)
    +  return if key.is_deploy_key && !key.last_deploy?
    +  git_host.remove_key(key.identifier, key.projects)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_save(key) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/key_observer.rb, line 4
    +def after_save(key)
    +  git_host.set_key(key.identifier, key.key, key.projects)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/KeysController.html b/doc/app/KeysController.html new file mode 100644 index 00000000..13fac402 --- /dev/null +++ b/doc/app/KeysController.html @@ -0,0 +1,624 @@ + + + + + + +class KeysController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class KeysController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/keys_controller.rb, line 19
    +def create
    +  @key = current_user.keys.new(params[:key])
    +  @key.save
    +
    +  respond_with(@key)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/keys_controller.rb, line 26
    +def destroy
    +  @key = current_user.keys.find(params[:id])
    +  @key.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to keys_url }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/keys_controller.rb, line 5
    +def index
    +  @keys = current_user.keys.all
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/keys_controller.rb, line 13
    +def new
    +  @key = current_user.keys.new
    +
    +  respond_with(@key)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/keys_controller.rb, line 9
    +def show
    +  @key = current_user.keys.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/LabelsController.html b/doc/app/LabelsController.html new file mode 100644 index 00000000..7dece840 --- /dev/null +++ b/doc/app/LabelsController.html @@ -0,0 +1,523 @@ + + + + + + +class LabelsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class LabelsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/labels_controller.rb, line 9
    +def index
    +  @labels = @project.issues_labels.order('count DESC')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + module_enabled() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/labels_controller.rb, line 15
    +def module_enabled
    +  return render_404 unless @project.issues_enabled
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MergeRequest.html b/doc/app/MergeRequest.html new file mode 100644 index 00000000..7dbe6f4f --- /dev/null +++ b/doc/app/MergeRequest.html @@ -0,0 +1,1478 @@ + + + + + + +class MergeRequest - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class MergeRequest

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    BROKEN_DIFF + +
    + + +
    CANNOT_BE_MERGED + +
    + + +
    CAN_BE_MERGED + +
    + + +
    UNCHECKED + +
    + + +
    +
    + + + + +
    +

    Attributes

    + + +
    +
    + should_remove_source_branch[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + find_all_by_branch(branch_name) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 25
    +def self.find_all_by_branch(branch_name)
    +  where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + automerge!(current_user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 169
    +def automerge!(current_user)
    +  if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty?
    +    self.merge!(current_user.id)
    +    true
    +  end
    +rescue
    +  self.mark_as_unmergable
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + broken_diffs?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 86
    +def broken_diffs?
    +  diffs == [BROKEN_DIFF]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + can_be_merged?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 58
    +def can_be_merged?
    +  state == CAN_BE_MERGED
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + check_if_can_be_merged() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 62
    +def check_if_can_be_merged
    +  self.state = if Gitlab::Merge.new(self, self.author).can_be_merged?
    +                 CAN_BE_MERGED
    +               else
    +                 CANNOT_BE_MERGED
    +               end
    +  self.save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + closed_event() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 114
    +def closed_event
    +  self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::Closed).last
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 118
    +def commits
    +  st_commits || []
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + diffs() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 71
    +def diffs
    +  st_diffs || []
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + human_state() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 29
    +def human_state
    +  states = {
    +    CAN_BE_MERGED =>  "can_be_merged",
    +    CANNOT_BE_MERGED => "cannot_be_merged",
    +    UNCHECKED => "unchecked"
    +  }
    +  states[self.state]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_commit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 102
    +def last_commit
    +  commits.first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mark_as_merged!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 131
    +def mark_as_merged!
    +  self.merged = true
    +  self.closed = true
    +  save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mark_as_unchecked() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 53
    +def mark_as_unchecked
    +  self.state = UNCHECKED
    +  self.save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mark_as_unmergable() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 137
    +def mark_as_unmergable
    +  self.state = CANNOT_BE_MERGED
    +  self.save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge!(user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 158
    +def merge!(user_id)
    +  self.mark_as_merged!
    +  Event.create(
    +    project: self.project,
    +    action: Event::Merged,
    +    target_id: self.id,
    +    target_type: "MergeRequest",
    +    author_id: user_id
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_event() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 110
    +def merge_event
    +  self.project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::Merged).last
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merged?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 106
    +def merged?
    +  merged && merge_event
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mr_and_commit_notes() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 191
    +def mr_and_commit_notes
    +  commit_ids = commits.map(&:id)
    +  Note.where("(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND noteable_id IN (:commit_ids))", mr_id: id, commit_ids: commit_ids)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + open?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 127
    +def open?
    +  !closed
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + probably_merged?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 122
    +def probably_merged?
    +  unmerged_commits.empty? &&
    +    commits.any? && open?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reload_code() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 44
    +def reload_code
    +  self.reloaded_commits
    +  self.reloaded_diffs
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reloaded_commits() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 142
    +def reloaded_commits
    +  if open? && unmerged_commits.any?
    +    self.st_commits = unmerged_commits
    +    save
    +  end
    +  commits
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reloaded_diffs() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 75
    +def reloaded_diffs
    +  if open? && unmerged_diffs.any?
    +    self.st_diffs = unmerged_diffs
    +    self.save
    +  end
    +
    +rescue Grit::Git::GitTimeout
    +  self.st_diffs = [BROKEN_DIFF]
    +  self.save
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_raw() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 179
    +def to_raw
    +  FileUtils.mkdir_p(Rails.root.join("tmp", "patches"))
    +  patch_path = Rails.root.join("tmp", "patches", "merge_request_#{self.id}.patch")
    +
    +  from = commits.last.id
    +  to = source_branch
    +
    +  project.repo.git.run('', "format-patch" , " > #{patch_path.to_s}", {}, ["#{from}..#{to}", "--stdout"])
    +
    +  patch_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unchecked?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 49
    +def unchecked?
    +  state == UNCHECKED
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unmerged_commits() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 150
    +def unmerged_commits
    +  self.project.repo.
    +    commits_between(self.target_branch, self.source_branch).
    +    map {|c| Commit.new(c)}.
    +    sort_by(&:created_at).
    +    reverse
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + unmerged_diffs() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 94
    +def unmerged_diffs
    +  # Only show what is new in the source branch compared to the target branch, not the other way around.
    +  # The linex below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
    +  # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
    +  common_commit = project.repo.git.native(:merge_base, {}, [target_branch, source_branch]).strip
    +  diffs = project.repo.diff(common_commit, source_branch)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + valid_diffs?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 90
    +def valid_diffs?
    +  !broken_diffs?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + validate_branches() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/merge_request.rb, line 38
    +def validate_branches
    +  if target_branch == source_branch
    +    errors.add :base, "You can not use same branch for source and target branches"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MergeRequestObserver.html b/doc/app/MergeRequestObserver.html new file mode 100644 index 00000000..f2d0dbd7 --- /dev/null +++ b/doc/app/MergeRequestObserver.html @@ -0,0 +1,569 @@ + + + + + + +class MergeRequestObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class MergeRequestObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(merge_request) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/merge_request_observer.rb, line 4
    +def after_create(merge_request)
    +  if merge_request.assignee && merge_request.assignee != current_user
    +    Notify.new_merge_request_email(merge_request.id).deliver
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_update(merge_request) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/merge_request_observer.rb, line 10
    +def after_update(merge_request)
    +  send_reassigned_email(merge_request) if merge_request.is_being_reassigned?
    +
    +  status = nil
    +  status = 'closed' if merge_request.is_being_closed?
    +  status = 'reopened' if merge_request.is_being_reopened?
    +  if status
    +    Note.create_status_change_note(merge_request, current_user, status)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + send_reassigned_email(merge_request) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/merge_request_observer.rb, line 23
    +def send_reassigned_email(merge_request)
    +  recipients_ids = merge_request.assignee_id_was, merge_request.assignee_id
    +  recipients_ids.delete current_user.id
    +
    +  recipients_ids.each do |recipient_id|
    +    Notify.reassigned_merge_request_email(recipient_id, merge_request.id, merge_request.assignee_id_was).deliver
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MergeRequestsController.html b/doc/app/MergeRequestsController.html new file mode 100644 index 00000000..ef257c6c --- /dev/null +++ b/doc/app/MergeRequestsController.html @@ -0,0 +1,1114 @@ + + + + + + +class MergeRequestsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class MergeRequestsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + automerge() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 79
    +def automerge
    +  return access_denied! unless can?(current_user, :accept_mr, @project)
    +  if @merge_request.open? && @merge_request.can_be_merged?
    +    @merge_request.should_remove_source_branch = params[:should_remove_source_branch]
    +    @merge_request.automerge!(current_user)
    +    @status = true
    +  else
    +    @status = false
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + automerge_check() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 72
    +def automerge_check
    +  if @merge_request.unchecked?
    +    @merge_request.check_if_can_be_merged
    +  end
    +  render json: {state: @merge_request.human_state}
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branch_from() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 98
    +def branch_from
    +  @commit = project.commit(params[:ref])
    +  @commit = CommitDecorator.decorate(@commit)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branch_to() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 103
    +def branch_to
    +  @commit = project.commit(params[:ref])
    +  @commit = CommitDecorator.decorate(@commit)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 50
    +def create
    +  @merge_request = @project.merge_requests.new(params[:merge_request])
    +  @merge_request.author = current_user
    +
    +  if @merge_request.save
    +    @merge_request.reload_code
    +    redirect_to [@project, @merge_request], notice: 'Merge request was successfully created.'
    +  else
    +    render action: "new"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 90
    +def destroy
    +  @merge_request.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_merge_requests_url(@project) }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + diffs() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 35
    +def diffs
    +  @diffs = @merge_request.diffs
    +  @commit = @merge_request.last_commit
    +
    +  @comments_allowed = true
    +  @line_notes = @merge_request.notes.where("line_code is not null")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 47
    +def edit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 20
    +def index
    +  @merge_requests = MergeRequestsLoadContext.new(project, current_user, params).execute
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 43
    +def new
    +  @merge_request = @project.merge_requests.new(params[:merge_request])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + raw() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 31
    +def raw
    +  send_file @merge_request.to_raw
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 24
    +def show
    +  respond_to do |format|
    +    format.html
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 62
    +def update
    +  if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
    +    @merge_request.reload_code
    +    @merge_request.mark_as_unchecked
    +    redirect_to [@project, @merge_request], notice: 'Merge request was successfully updated.'
    +  else
    +    render action: "edit"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + authorize_admin_merge_request!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 118
    +def authorize_admin_merge_request!
    +  return render_404 unless can?(current_user, :admin_merge_request, @merge_request)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize_modify_merge_request!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 114
    +def authorize_modify_merge_request!
    +  return render_404 unless can?(current_user, :modify_merge_request, @merge_request)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + define_show_vars() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 135
    +def define_show_vars
    +  # Build a note object for comment form
    +  @note = @project.notes.new(noteable: @merge_request)
    +
    +  # Get commits from repository
    +  # or from cache if already merged
    +  @commits = @merge_request.commits
    +  @commits = CommitDecorator.decorate(@commits)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + merge_request() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 110
    +def merge_request
    +  @merge_request ||= @project.merge_requests.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + module_enabled() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 122
    +def module_enabled
    +  return render_404 unless @project.merge_requests_enabled
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + validates_merge_request() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/merge_requests_controller.rb, line 126
    +def validates_merge_request
    +  # Show git not found page if target branch doesnt exist
    +  return git_not_found! unless @project.repo.heads.map(&:name).include?(@merge_request.target_branch)
    +
    +  # Show git not found page if source branch doesnt exist
    +  # and there is no saved commits between source & target branch
    +  return git_not_found! if !@project.repo.heads.map(&:name).include?(@merge_request.source_branch) && @merge_request.commits.blank?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MergeRequestsHelper.html b/doc/app/MergeRequestsHelper.html new file mode 100644 index 00000000..fec9b0e0 --- /dev/null +++ b/doc/app/MergeRequestsHelper.html @@ -0,0 +1,599 @@ + + + + + + +module MergeRequestsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module MergeRequestsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + + + + + + + +
    + +
    + mr_css_classes(mr) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/merge_requests_helper.rb, line 35
    +def mr_css_classes mr
    +  classes = "merge_request"
    +  classes << " closed" if mr.closed
    +  classes << " merged" if mr.merged?
    +  classes
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_mr_path_from_push_event(event) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/merge_requests_helper.rb, line 24
    +def new_mr_path_from_push_event(event)
    +  new_project_merge_request_path(
    +    event.project,
    +    merge_request: {
    +      source_branch: event.branch_name,
    +      target_branch: event.project.root_ref,
    +      title: event.branch_name.titleize
    +    }
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MergeRequestsLoadContext.html b/doc/app/MergeRequestsLoadContext.html new file mode 100644 index 00000000..5c1b8829 --- /dev/null +++ b/doc/app/MergeRequestsLoadContext.html @@ -0,0 +1,496 @@ + + + + + + +class MergeRequestsLoadContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class MergeRequestsLoadContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/merge_requests_load_context.rb, line 2
    +def execute
    +  type = params[:f]
    +
    +  merge_requests = project.merge_requests
    +
    +  merge_requests = case type
    +                   when 'all' then merge_requests
    +                   when 'closed' then merge_requests.closed
    +                   when 'assigned-to-me' then merge_requests.opened.assigned(current_user)
    +                   else merge_requests.opened
    +                   end.page(params[:page]).per(20)
    +
    +  merge_requests.includes(:author, :project).order("closed, created_at desc")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Milestone.html b/doc/app/Milestone.html new file mode 100644 index 00000000..cc3bdc58 --- /dev/null +++ b/doc/app/Milestone.html @@ -0,0 +1,589 @@ + + + + + + +class Milestone - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Milestone

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + active() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/milestone.rb, line 10
    +def self.active
    +  where("due_date > ? OR due_date IS NULL", Date.today)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + expires_at() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/milestone.rb, line 24
    +def expires_at
    +  "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + participants() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/milestone.rb, line 14
    +def participants
    +  User.where(id: issues.pluck(:assignee_id))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + percent_complete() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/milestone.rb, line 18
    +def percent_complete
    +  ((self.issues.closed.count * 100) / self.issues.count).abs
    +rescue ZeroDivisionError
    +  100
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/MilestonesController.html b/doc/app/MilestonesController.html new file mode 100644 index 00000000..e15d6fef --- /dev/null +++ b/doc/app/MilestonesController.html @@ -0,0 +1,816 @@ + + + + + + +class MilestonesController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class MilestonesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 42
    +def create
    +  @milestone = @project.milestones.new(params[:milestone])
    +
    +  if @milestone.save
    +    redirect_to project_milestone_path(@project, @milestone)
    +  else
    +    render "new"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 67
    +def destroy
    +  return access_denied! unless can?(current_user, :admin_milestone, @milestone)
    +
    +  @milestone.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_milestones_path }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 28
    +def edit
    +  respond_with(@milestone)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 13
    +def index
    +  @milestones = case params[:f]
    +                when 'all'; @project.milestones
    +                else @project.milestones.active
    +                end
    +
    +  @milestones = @milestones.includes(:project).order("due_date")
    +  @milestones = @milestones.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 23
    +def new
    +  @milestone = @project.milestones.new
    +  respond_with(@milestone)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 32
    +def show
    +  @issues = @milestone.issues
    +  @users = @milestone.participants
    +
    +  respond_to do |format|
    +    format.html
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 52
    +def update
    +  @milestone.update_attributes(params[:milestone])
    +
    +  respond_to do |format|
    +    format.js
    +    format.html do
    +      if @milestone.valid?
    +        redirect_to [@project, @milestone]
    +      else
    +        render :edit
    +      end
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + authorize_admin_milestone!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 84
    +def authorize_admin_milestone!
    +  return render_404 unless can?(current_user, :admin_milestone, @project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + milestone() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 80
    +def milestone
    +  @milestone ||= @project.milestones.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + module_enabled() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/milestones_controller.rb, line 88
    +def module_enabled
    +  return render_404 unless @project.issues_enabled
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Note.html b/doc/app/Note.html new file mode 100644 index 00000000..24a474b0 --- /dev/null +++ b/doc/app/Note.html @@ -0,0 +1,777 @@ + + + + + + +class Note - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Note

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + notify[RW] +
    + +
    + + + +
    +
    + +
    +
    + notify_author[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + create_status_change_note(noteable, author, status) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/note.rb, line 34
    +def self.create_status_change_note(noteable, author, status)
    +  create({
    +    noteable: noteable,
    +    project: noteable.project,
    +    author: author,
    +    note: "_Status changed to #{status}_"
    +  }, without_protection: true)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + commit_author() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/note.rb, line 90
    +def commit_author
    +  @commit_author ||=
    +    project.users.find_by_email(noteable.author_email) ||
    +    project.users.find_by_name(noteable.author_name)
    +rescue
    +  nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + downvote?() + click to toggle source +
    + + +
    + +

    Returns true if this is a downvote note, otherwise false is returned

    + + + +
    +
    # File app/models/note.rb, line 106
    +def downvote?
    +  note.start_with?('-1') || note.start_with?(':-1:')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + for_commit?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/note.rb, line 82
    +def for_commit?
    +  noteable_type == "Commit"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + for_diff_line?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/note.rb, line 86
    +def for_diff_line?
    +  line_code.present?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + noteable() + click to toggle source +
    + + +
    + +

    override to return commits, which are not active record

    + + + +
    +
    # File app/models/note.rb, line 52
    +def noteable
    +  if for_commit?
    +    project.commit(noteable_id)
    +  else
    +    super
    +  end
    +# Temp fix to prevent app crash
    +# if note commit id doesnt exist
    +rescue
    +  nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + notify_only_author?(user) + click to toggle source +
    + + +
    + +

    Check if we can notify commit author with email about our comment

    + +

    If commit author email exist in project and commit author is not passed +user we can send email to him

    + +

    params:

    + +
    user - current user
    + +

    return:

    + +
    Boolean
    + + + +
    +
    # File app/models/note.rb, line 77
    +def notify_only_author?(user)
    +  for_commit? && commit_author &&
    +    commit_author.email != user.email
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + upvote?() + click to toggle source +
    + + +
    + +

    Returns true if this is an upvote note, otherwise false is returned

    + + + +
    +
    # File app/models/note.rb, line 100
    +def upvote?
    +  note.start_with?('+1') || note.start_with?(':+1:')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/NoteObserver.html b/doc/app/NoteObserver.html new file mode 100644 index 00000000..d0528833 --- /dev/null +++ b/doc/app/NoteObserver.html @@ -0,0 +1,603 @@ + + + + + + +class NoteObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class NoteObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(note) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/note_observer.rb, line 3
    +def after_create(note)
    +  send_notify_mails(note)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + notify_team(note) + click to toggle source +
    + + +
    + +

    Notifies the whole team except the author of note

    + + + +
    +
    # File app/observers/note_observer.rb, line 22
    +def notify_team(note)
    +  # Note: wall posts are not "attached" to anything, so fall back to "Wall"
    +  noteable_type = note.noteable_type || "Wall"
    +  notify_method = "note_#{noteable_type.underscore}_email".to_sym
    +
    +  if Notify.respond_to? notify_method
    +    team_without_note_author(note).map do |u|
    +      Notify.send(notify_method, u.id, note.id).deliver
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + send_notify_mails(note) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/note_observer.rb, line 9
    +def send_notify_mails(note)
    +  if note.notify
    +    notify_team(note)
    +  elsif note.notify_author
    +    # Notify only author of resource
    +    Notify.note_commit_email(note.commit_author.id, note.id).deliver
    +  else
    +    # Otherwise ignore it
    +    nil
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + team_without_note_author(note) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/note_observer.rb, line 34
    +def team_without_note_author(note)
    +  note.project.users.reject { |u| u.id == note.author.id }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Notes.html b/doc/app/Notes.html new file mode 100644 index 00000000..d6bcc540 --- /dev/null +++ b/doc/app/Notes.html @@ -0,0 +1,434 @@ + + + + + + +module Notes - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Notes

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Notes/CreateContext.html b/doc/app/Notes/CreateContext.html new file mode 100644 index 00000000..6d4c8449 --- /dev/null +++ b/doc/app/Notes/CreateContext.html @@ -0,0 +1,490 @@ + + + + + + +class Notes::CreateContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Notes::CreateContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/notes/create_context.rb, line 3
    +def execute
    +  note = project.notes.new(params[:note])
    +  note.author = current_user
    +  note.notify = true if params[:notify] == '1'
    +  note.notify_author = true if params[:notify_author] == '1'
    +  note.save
    +  note
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Notes/LoadContext.html b/doc/app/Notes/LoadContext.html new file mode 100644 index 00000000..273fc0f0 --- /dev/null +++ b/doc/app/Notes/LoadContext.html @@ -0,0 +1,513 @@ + + + + + + +class Notes::LoadContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Notes::LoadContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/notes/load_context.rb, line 3
    +def execute
    +  target_type = params[:target_type]
    +  target_id   = params[:target_id]
    +  after_id    = params[:after_id]
    +  before_id   = params[:before_id]
    +
    +
    +  @notes = case target_type
    +           when "commit"
    +             project.commit_notes(project.commit(target_id)).fresh.limit(20)
    +           when "issue"
    +             project.issues.find(target_id).notes.inc_author.fresh.limit(20)
    +           when "merge_request"
    +             project.merge_requests.find(target_id).mr_and_commit_notes.inc_author.fresh.limit(20)
    +           when "snippet"
    +             project.snippets.find(target_id).notes.fresh
    +           when "wall"
    +             # this is the only case, where the order is DESC
    +             project.common_notes.order("created_at DESC, id DESC").limit(50)
    +           when "wiki"
    +             project.wiki_notes.limit(20)
    +           end
    +
    +  @notes = if after_id
    +             @notes.where("id > ?", after_id)
    +           elsif before_id
    +             @notes.where("id < ?", before_id)
    +           else
    +             @notes
    +           end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/NotesController.html b/doc/app/NotesController.html new file mode 100644 index 00000000..5623d4a2 --- /dev/null +++ b/doc/app/NotesController.html @@ -0,0 +1,636 @@ + + + + + + +class NotesController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class NotesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/notes_controller.rb, line 18
    +def create
    +  @note = Notes::CreateContext.new(project, current_user, params).execute
    +
    +  respond_to do |format|
    +    format.html {redirect_to :back}
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/notes_controller.rb, line 27
    +def destroy
    +  @note = @project.notes.find(params[:id])
    +  return access_denied! unless can?(current_user, :admin_note, @note)
    +  @note.destroy
    +
    +  respond_to do |format|
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/notes_controller.rb, line 8
    +def index
    +  notes
    +  if params[:target_type] == "merge_request"
    +    @mixed_targets = true
    +    @main_target_type = params[:target_type].camelize
    +  end
    +
    +  respond_with(@notes)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + preview() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/notes_controller.rb, line 37
    +def preview
    +  render text: view_context.markdown(params[:note])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + notes() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/notes_controller.rb, line 43
    +def notes
    +  @notes = Notes::LoadContext.new(project, current_user, params).execute
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/NotesHelper.html b/doc/app/NotesHelper.html new file mode 100644 index 00000000..c2940f8d --- /dev/null +++ b/doc/app/NotesHelper.html @@ -0,0 +1,581 @@ + + + + + + +module NotesHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module NotesHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + + + + +
    + +
    + loading_more_notes?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/notes_helper.rb, line 2
    +def loading_more_notes?
    +  params[:loading_more].present?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + loading_new_notes?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/notes_helper.rb, line 6
    +def loading_new_notes?
    +  params[:loading_new].present?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_for_main_target?(note) + click to toggle source +
    + + +
    + +

    Helps to distinguish e.g. commit notes in mr notes list

    + + + +
    +
    # File app/helpers/notes_helper.rb, line 11
    +def note_for_main_target?(note)
    +  !@mixed_targets || @main_target_type == note.noteable_type
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Notify.html b/doc/app/Notify.html new file mode 100644 index 00000000..933e1cbc --- /dev/null +++ b/doc/app/Notify.html @@ -0,0 +1,883 @@ + + + + + + +class Notify - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Notify

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 31
    +def issue_status_changed_email(recipient_id, issue_id, status, updated_by_user_id)
    +  @issue = Issue.find issue_id
    +  @issue_status = status
    +  @updated_by = User.find updated_by_user_id
    +  mail(to: recipient(recipient_id),
    +      subject: subject("changed issue ##{@issue.id}", @issue.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_issue_email(issue_id) + click to toggle source +
    + + +
    + +

    Issue

    + + + +
    +
    # File app/mailers/notify.rb, line 18
    +def new_issue_email(issue_id)
    +  @issue = Issue.find(issue_id)
    +  @project = @issue.project
    +  mail(to: @issue.assignee_email, subject: subject("new issue ##{@issue.id}", @issue.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_merge_request_email(merge_request_id) + click to toggle source +
    + + +
    + +

    Merge Request

    + + + +
    +
    # File app/mailers/notify.rb, line 45
    +def new_merge_request_email(merge_request_id)
    +  @merge_request = MergeRequest.find(merge_request_id)
    +  @project = @merge_request.project
    +  mail(to: @merge_request.assignee_email, subject: subject("new merge request !#{@merge_request.id}", @merge_request.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_user_email(user_id, password) + click to toggle source +
    + + +
    + +

    User

    + + + +
    +
    # File app/mailers/notify.rb, line 118
    +def new_user_email(user_id, password)
    +  @user = User.find(user_id)
    +  @password = password
    +  mail(to: @user.email, subject: subject("Account was created for you"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_commit_email(recipient_id, note_id) + click to toggle source +
    + + +
    + +

    Note

    + + + +
    +
    # File app/mailers/notify.rb, line 64
    +def note_commit_email(recipient_id, note_id)
    +  @note = Note.find(note_id)
    +  @commit = @note.noteable
    +  @commit = CommitDecorator.decorate(@commit)
    +  @project = @note.project
    +  mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_issue_email(recipient_id, note_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 72
    +def note_issue_email(recipient_id, note_id)
    +  @note = Note.find(note_id)
    +  @issue = @note.noteable
    +  @project = @note.project
    +  mail(to: recipient(recipient_id), subject: subject("note for issue ##{@issue.id}"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_merge_request_email(recipient_id, note_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 79
    +def note_merge_request_email(recipient_id, note_id)
    +  @note = Note.find(note_id)
    +  @merge_request = @note.noteable
    +  @project = @note.project
    +  mail(to: recipient(recipient_id), subject: subject("note for merge request !#{@merge_request.id}"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_wall_email(recipient_id, note_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 86
    +def note_wall_email(recipient_id, note_id)
    +  @note = Note.find(note_id)
    +  @project = @note.project
    +  mail(to: recipient(recipient_id), subject: subject)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + note_wiki_email(recipient_id, note_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 92
    +def note_wiki_email(recipient_id, note_id)
    +  @note = Note.find(note_id)
    +  @wiki = @note.noteable
    +  @project = @note.project
    +  mail(to: recipient(recipient_id), subject: subject("note for wiki"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_access_granted_email(user_project_id) + click to toggle source +
    + + +
    + +

    Project

    + + + +
    +
    # File app/mailers/notify.rb, line 105
    +def project_access_granted_email(user_project_id)
    +  @users_project = UsersProject.find user_project_id
    +  @project = @users_project.project
    +  mail(to: @users_project.user.email, 
    +       subject: subject("access to project was granted"))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 24
    +def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
    +  @issue = Issue.find(issue_id)
    +  @previous_assignee ||= User.find(previous_assignee_id)
    +  @project = @issue.project
    +  mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.id}", @issue.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/mailers/notify.rb, line 51
    +def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
    +  @merge_request = MergeRequest.find(merge_request_id)
    +  @previous_assignee ||= User.find(previous_assignee_id)
    +  @project = @merge_request.project
    +  mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.id}", @merge_request.title))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/OmniauthCallbacksController.html b/doc/app/OmniauthCallbacksController.html new file mode 100644 index 00000000..d40a16a3 --- /dev/null +++ b/doc/app/OmniauthCallbacksController.html @@ -0,0 +1,527 @@ + + + + + + +class OmniauthCallbacksController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class OmniauthCallbacksController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + failure_message() + click to toggle source +
    + + +
    + +

    Extend the standard message generation to accept our custom exception

    + + + +
    +
    # File app/controllers/omniauth_callbacks_controller.rb, line 9
    +def failure_message
    +  exception = env["omniauth.error"]
    +  error   = exception.error_reason if exception.respond_to?(:error_reason)
    +  error ||= exception.error        if exception.respond_to?(:error)
    +  error ||= exception.message      if exception.respond_to?(:message)
    +  error ||= env["omniauth.error.type"].to_s
    +  error.to_s.humanize if error
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ldap() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/omniauth_callbacks_controller.rb, line 18
    +def ldap
    +  # We only find ourselves here if the authentication to LDAP was successful.
    +  @user = User.find_for_ldap_auth(request.env["omniauth.auth"], current_user)
    +  if @user.persisted?
    +    @user.remember_me = true
    +  end
    +  sign_in_and_redirect @user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/PostReceive.html b/doc/app/PostReceive.html new file mode 100644 index 00000000..11468fd9 --- /dev/null +++ b/doc/app/PostReceive.html @@ -0,0 +1,495 @@ + + + + + + +class PostReceive - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class PostReceive

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + perform(reponame, oldrev, newrev, ref, identifier) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/workers/post_receive.rb, line 4
    +def self.perform(reponame, oldrev, newrev, ref, identifier)
    +  project = Project.find_by_path(reponame)
    +  return false if project.nil?
    +
    +  # Ignore push from non-gitlab users
    +  if %r^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier)
    +    return false unless user = User.find_by_email(identifier)
    +  else
    +    return false unless user = Key.find_by_identifier(identifier).try(:user)
    +  end
    +
    +  project.trigger_post_receive(oldrev, newrev, ref, user)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProfileController.html b/doc/app/ProfileController.html new file mode 100644 index 00000000..deb4b0bc --- /dev/null +++ b/doc/app/ProfileController.html @@ -0,0 +1,683 @@ + + + + + + +class ProfileController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProfileController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + design() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 7
    +def design
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + history() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 34
    +def history
    +  @events = current_user.recent_events.page(params[:page]).per(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + password_update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 18
    +def password_update
    +  params[:user].reject!{ |k, v| k != "password" && k != "password_confirmation"}
    +
    +  if @user.update_attributes(params[:user])
    +    flash[:notice] = "Password was successfully updated. Please login with it"
    +    redirect_to new_user_session_path
    +  else
    +    render action: "password"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + reset_private_token() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 29
    +def reset_private_token
    +  current_user.reset_authentication_token!
    +  redirect_to profile_account_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 4
    +def show
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + token() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 15
    +def token
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/profile_controller.rb, line 10
    +def update
    +  @user.update_attributes(params[:user])
    +  redirect_to :back
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProfileHelper.html b/doc/app/ProfileHelper.html new file mode 100644 index 00000000..ab7773ba --- /dev/null +++ b/doc/app/ProfileHelper.html @@ -0,0 +1,481 @@ + + + + + + +module ProfileHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module ProfileHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + oauth_active_class(provider) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/profile_helper.rb, line 2
    +def oauth_active_class provider
    +  if current_user.provider == provider.to_s
    +    'active'
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Project.html b/doc/app/Project.html new file mode 100644 index 00000000..55868ef1 --- /dev/null +++ b/doc/app/Project.html @@ -0,0 +1,1202 @@ + + + + + + +class Project - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Project

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + error_code[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + access_options() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 85
    +def access_options
    +  UsersProject.access_roles
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + active() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 52
    +def active
    +  joins(:issues, :notes, :merge_requests).order("issues.created_at, notes.created_at, merge_requests.created_at DESC")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create_by_user(params, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 60
    +def create_by_user(params, user)
    +  project = Project.new params
    +
    +  Project.transaction do
    +    project.owner = user
    +    project.save!
    +
    +    # Add user as project master
    +    project.users_projects.create!(project_access: UsersProject::MASTER, user: user)
    +
    +    # when project saved no team member exist so
    +    # project repository should be updated after first user add
    +    project.update_repository
    +  end
    +
    +  project
    +rescue Gitlab::Gitolite::AccessDenied => ex
    +  project.error_code = :gitolite
    +  project
    +rescue => ex
    +  project.error_code = :db
    +  project.errors.add(:base, "Can't save project. Please try again later")
    +  project
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + build_commit_note(commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 124
    +def build_commit_note(commit)
    +  notes.new(noteable_id: commit.id, noteable_type: "Commit")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + check_limit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 98
    +def check_limit
    +  unless owner.can_create_project?
    +    errors[:base] << ("Your own projects limit is #{owner.projects_limit}! Please contact administrator to increase it")
    +  end
    +rescue
    +  errors[:base] << ("Can't check your ability to create project")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commit_line_notes(commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 132
    +def commit_line_notes(commit)
    +  notes.where(noteable_id: commit.id, noteable_type: "Commit").where("line_code IS NOT NULL")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commit_notes(commit) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 128
    +def commit_notes(commit)
    +  notes.where(noteable_id: commit.id, noteable_type: "Commit", line_code: nil)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + common_notes() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 120
    +def common_notes
    +  notes.where(noteable_type: ["", nil]).inc_author_project
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + git_error?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 90
    +def git_error?
    +  error_code == :gitolite
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + issues_labels() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 160
    +def issues_labels
    +  issues.tag_counts_on(:labels)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_activity() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 144
    +def last_activity
    +  last_event
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_activity_date() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 148
    +def last_activity_date
    +  last_event.try(:created_at) || updated_at
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + private?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 140
    +def private?
    +  private_flag
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + project_id() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 156
    +def project_id
    +  self.id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + public?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 136
    +def public?
    +  !private_flag
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repo_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 106
    +def repo_name
    +  if path == "gitolite-admin"
    +    errors.add(:path, " like 'gitolite-admin' is not allowed")
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + saved?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 94
    +def saved?
    +  id && valid?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_param() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 112
    +def to_param
    +  code
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + web_url() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 116
    +def web_url
    +  [Gitlab.config.url, code].join("/")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + wiki_notes() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/project.rb, line 152
    +def wiki_notes
    +  Note.where(noteable_id: wikis.pluck(:id), noteable_type: 'Wiki', project_id: self.id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProjectHook.html b/doc/app/ProjectHook.html new file mode 100644 index 00000000..e5d17ef0 --- /dev/null +++ b/doc/app/ProjectHook.html @@ -0,0 +1,439 @@ + + + + + + +class ProjectHook - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectHook

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/ProjectObserver.html b/doc/app/ProjectObserver.html new file mode 100644 index 00000000..d4ce7824 --- /dev/null +++ b/doc/app/ProjectObserver.html @@ -0,0 +1,589 @@ + + + + + + +class ProjectObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/project_observer.rb, line 12
    +def after_create project
    +  log_info("#{project.owner.name} created a new project \"#{project.name}\"")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_destroy(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/project_observer.rb, line 6
    +def after_destroy(project)
    +  log_info("Project \"#{project.name}\" was removed")
    +
    +  project.destroy_repository
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_save(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/project_observer.rb, line 2
    +def after_save(project)
    +  project.update_repository
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + log_info(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/project_observer.rb, line 18
    +def log_info message
    +  Gitlab::AppLogger.info message
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProjectResourceController.html b/doc/app/ProjectResourceController.html new file mode 100644 index 00000000..aa972617 --- /dev/null +++ b/doc/app/ProjectResourceController.html @@ -0,0 +1,439 @@ + + + + + + +class ProjectResourceController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectResourceController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/ProjectsController.html b/doc/app/ProjectsController.html new file mode 100644 index 00000000..6982deab --- /dev/null +++ b/doc/app/ProjectsController.html @@ -0,0 +1,785 @@ + + + + + + +class ProjectsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProjectsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 20
    +def create
    +  @project = Project.create_by_user(params[:project], current_user)
    +
    +  respond_to do |format|
    +    format.html do
    +      if @project.saved?
    +        redirect_to(@project, notice: 'Project was successfully created.')
    +      else
    +        render action: "new"
    +      end
    +    end
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 85
    +def destroy
    +  # Disable the UsersProject update_repository call, otherwise it will be
    +  # called once for every person removed from the project
    +  UsersProject.skip_callback(:destroy, :after, :update_repository)
    +  project.destroy
    +  UsersProject.set_callback(:destroy, :after, :update_repository)
    +
    +  respond_to do |format|
    +    format.html { redirect_to root_path }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 17
    +def edit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + files() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 64
    +def files
    +  @notes = @project.notes.where("attachment != 'NULL'").order("created_at DESC").limit(100)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + graph() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 81
    +def graph
    +  @days_json, @commits_json = Gitlab::GraphCommit.to_graph(project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 13
    +def new
    +  @project = Project.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 47
    +def show
    +  limit = (params[:limit] || 20).to_i
    +  @events = @project.events.recent.limit(limit).offset(params[:offset] || 0)
    +
    +  respond_to do |format|
    +    format.html do
    +       unless @project.empty_repo?
    +         @last_push = current_user.recent_push(@project.id)
    +         render :show
    +       else
    +         render "projects/empty"
    +       end
    +    end
    +    format.js
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/projects_controller.rb, line 35
    +def update
    +  respond_to do |format|
    +    if project.update_attributes(params[:project])
    +      format.html { redirect_to edit_project_path(project), notice: 'Project was successfully updated.' }
    +      format.js
    +    else
    +      format.html { render action: "edit" }
    +      format.js
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + wall() + click to toggle source +
    + + +
    + +

    Wall

    + + + +
    +
    # File app/controllers/projects_controller.rb, line 72
    +def wall
    +  return render_404 unless @project.wall_enabled
    +  @note = Note.new
    +
    +  respond_to do |format|
    +    format.html
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProjectsHelper.html b/doc/app/ProjectsHelper.html new file mode 100644 index 00000000..5edd4592 --- /dev/null +++ b/doc/app/ProjectsHelper.html @@ -0,0 +1,543 @@ + + + + + + +module ProjectsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module ProjectsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + grouper_project_members(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/projects_helper.rb, line 2
    +def grouper_project_members(project)
    +  @project.users_projects.sort_by(&:project_access).reverse.group_by(&:project_access)
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + remove_from_team_message(project, member) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/projects_helper.rb, line 6
    +def remove_from_team_message(project, member)
    +  "You are going to remove #{member.user_name} from #{project.name}. Are you sure?"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProtectedBranch.html b/doc/app/ProtectedBranch.html new file mode 100644 index 00000000..900646dc --- /dev/null +++ b/doc/app/ProtectedBranch.html @@ -0,0 +1,529 @@ + + + + + + +class ProtectedBranch - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProtectedBranch

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + commit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/protected_branch.rb, line 17
    +def commit
    +  project.commit(self.name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_repository() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/protected_branch.rb, line 13
    +def update_repository
    +  git_host.update_repository(project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/ProtectedBranchesController.html b/doc/app/ProtectedBranchesController.html new file mode 100644 index 00000000..7eb2b1fd --- /dev/null +++ b/doc/app/ProtectedBranchesController.html @@ -0,0 +1,556 @@ + + + + + + +class ProtectedBranchesController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class ProtectedBranchesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/protected_branches_controller.rb, line 13
    +def create
    +  @project.protected_branches.create(params[:protected_branch])
    +  redirect_to project_protected_branches_path(@project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/protected_branches_controller.rb, line 18
    +def destroy
    +  @project.protected_branches.find(params[:id]).destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_protected_branches_path }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/protected_branches_controller.rb, line 8
    +def index
    +  @branches = @project.protected_branches.all
    +  @protected_branch = @project.protected_branches.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/PushEvent.html b/doc/app/PushEvent.html new file mode 100644 index 00000000..002866a6 --- /dev/null +++ b/doc/app/PushEvent.html @@ -0,0 +1,1105 @@ + + + + + + +module PushEvent - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module PushEvent

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + branch?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 12
    +def branch?
    +  data[:ref]["refs/heads"]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branch_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 48
    +def branch_name
    +  @branch_name ||= data[:ref].gsub("refs/heads/", "")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commit_from() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 32
    +def commit_from
    +  data[:before]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commit_to() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 36
    +def commit_to
    +  data[:after]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits() + click to toggle source +
    + + +
    + +

    Max 20 commits from push DESC

    + + + +
    +
    # File app/roles/push_event.rb, line 57
    +def commits
    +  @commits ||= data[:commits].map { |commit| project.commit(commit[:id]) }.reverse
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_count() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 61
    +def commits_count 
    +  data[:total_commits_count] || commits.count || 0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_commit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 85
    +def last_commit
    +  project.commit(commit_to)
    +rescue => ex
    +  nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_push_to_non_root?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 97
    +def last_push_to_non_root?
    +  branch? && project.default_branch != branch_name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + md_ref?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 28
    +def md_ref?
    +  !(rm_ref? || new_ref?)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_branch?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 16
    +def new_branch?
    +  commit_from =~ %r^00000/
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_ref?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 20
    +def new_ref?
    +  commit_from =~ %r^00000/
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + parent_commit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 79
    +def parent_commit
    +  project.commit(commit_from)
    +rescue => ex
    +  nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + push_action_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 69
    +def push_action_name
    +  if new_ref?
    +    "pushed new"
    +  elsif rm_ref?
    +    "deleted"
    +  else
    +    "pushed to"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + push_with_commits?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 91
    +def push_with_commits? 
    +  md_ref? && commits.any? && parent_commit && last_commit
    +rescue Grit::NoSuchPathError
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ref_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 40
    +def ref_name
    +  if tag?
    +    tag_name
    +  else
    +    branch_name
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ref_type() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 65
    +def ref_type
    +  tag? ? "tag" : "branch"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + rm_ref?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 24
    +def rm_ref?
    +  commit_to =~ %r^00000/
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tag?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 8
    +def tag?
    +  data[:ref]["refs/tags"]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tag_name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 52
    +def tag_name
    +  @tag_name ||= data[:ref].gsub("refs/tags/", "")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + valid_push?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_event.rb, line 2
    +def valid_push?
    +  data[:ref]
    +rescue => ex
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/PushObserver.html b/doc/app/PushObserver.html new file mode 100644 index 00000000..804447a6 --- /dev/null +++ b/doc/app/PushObserver.html @@ -0,0 +1,699 @@ + + + + + + +module PushObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module PushObserver

    + +
    + +

    Includes methods for handling Git Push events

    + +

    Triggered by PostReceive job

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute_hooks(oldrev, newrev, ref, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_observer.rb, line 33
    +def execute_hooks(oldrev, newrev, ref, user)
    +  ref_parts = ref.split('/')
    +
    +  # Return if this is not a push to a branch (e.g. new commits)
    +  return if ref_parts[1] !~ %rheads/ || oldrev == "00000000000000000000000000000000"
    +
    +  data = post_receive_data(oldrev, newrev, ref, user)
    +
    +  hooks.each { |hook| hook.execute(data) }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + observe_push(oldrev, newrev, ref, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_observer.rb, line 5
    +def observe_push(oldrev, newrev, ref, user)
    +  data = post_receive_data(oldrev, newrev, ref, user)
    +
    +  Event.create(
    +    project: self,
    +    action: Event::Pushed,
    +    data: data,
    +    author_id: data[:user_id]
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + post_receive_data(oldrev, newrev, ref, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_observer.rb, line 44
    +def post_receive_data(oldrev, newrev, ref, user)
    +
    +  push_commits = commits_between(oldrev, newrev)
    +
    +  # Total commits count
    +  push_commits_count = push_commits.size
    +
    +  # Get latest 20 commits ASC
    +  push_commits_limited = push_commits.last(20)
    +
    +  # Hash to be passed as post_receive_data
    +  data = {
    +    before: oldrev,
    +    after: newrev,
    +    ref: ref,
    +    user_id: user.id,
    +    user_name: user.name,
    +    repository: {
    +      name: name,
    +      url: web_url,
    +      description: description,
    +      homepage: web_url,
    +    },
    +    commits: [],
    +    total_commits_count: push_commits_count
    +  }
    +
    +  # For perfomance purposes maximum 20 latest commits
    +  # will be passed as post receive hook data.
    +  #
    +  push_commits_limited.each do |commit|
    +    data[:commits] << {
    +      id: commit.id,
    +      message: commit.safe_message,
    +      timestamp: commit.date.xmlschema,
    +      url: "#{Gitlab.config.url}/#{code}/commits/#{commit.id}",
    +      author: {
    +        name: commit.author_name,
    +        email: commit.author_email
    +      }
    +    }
    +  end
    +
    +  data
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + trigger_post_receive(oldrev, newrev, ref, user) + click to toggle source +
    + + +
    + +

    This method will be called after each post receive and only if the provided +user is present in GitLab.

    + +

    All callbacks for post receive should be placed here.

    + + + +
    +
    # File app/roles/push_observer.rb, line 94
    +def trigger_post_receive(oldrev, newrev, ref, user)
    +  # Create push event
    +  self.observe_push(oldrev, newrev, ref, user)
    +
    +  # Close merged MR
    +  self.update_merge_requests(oldrev, newrev, ref, user)
    +
    +  # Execute web hooks
    +  self.execute_hooks(oldrev, newrev, ref, user)
    +
    +  # Create satellite
    +  self.satellite.create unless self.satellite.exists?
    +
    +  # Discover the default branch, but only if it hasn't already been set to
    +  # something else
    +  if default_branch.nil?
    +    update_attributes(default_branch: discover_default_branch)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_merge_requests(oldrev, newrev, ref, user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/push_observer.rb, line 16
    +def update_merge_requests(oldrev, newrev, ref, user)
    +  return true unless ref =~ %rheads/
    +  branch_name = ref.gsub("refs/heads/", "")
    +  c_ids = self.commits_between(oldrev, newrev).map(&:id)
    +
    +  # Update code for merge requests
    +  mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
    +  mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
    +
    +  # Close merge requests
    +  mrs = self.merge_requests.opened.where(target_branch: branch_name).all
    +  mrs = mrs.select(&:last_commit).select { |mr| c_ids.include?(mr.last_commit.id) }
    +  mrs.each { |merge_request| merge_request.merge!(user.id) }
    +
    +  true
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Redcarpet.html b/doc/app/Redcarpet.html new file mode 100644 index 00000000..238b7f25 --- /dev/null +++ b/doc/app/Redcarpet.html @@ -0,0 +1,432 @@ + + + + + + +module Redcarpet - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Redcarpet

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Redcarpet/Render.html b/doc/app/Redcarpet/Render.html new file mode 100644 index 00000000..acb7ba3c --- /dev/null +++ b/doc/app/Redcarpet/Render.html @@ -0,0 +1,432 @@ + + + + + + +module Redcarpet::Render - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Redcarpet::Render

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    + +
    + + + + diff --git a/doc/app/Redcarpet/Render/GitlabHTML.html b/doc/app/Redcarpet/Render/GitlabHTML.html new file mode 100644 index 00000000..93212eab --- /dev/null +++ b/doc/app/Redcarpet/Render/GitlabHTML.html @@ -0,0 +1,594 @@ + + + + + + +class Redcarpet::Render::GitlabHTML - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Redcarpet::Render::GitlabHTML

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + h[R] +
    + +
    + + + +
    +
    + +
    +
    + template[R] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(template, options = {}) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/redcarpet/render/gitlab_html.rb, line 6
    +def initialize(template, options = {})
    +  @template = template
    +  @project = @template.instance_variable_get("@project")
    +  super options
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + block_code(code, language) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/redcarpet/render/gitlab_html.rb, line 12
    +def block_code(code, language)
    +  if Pygments::Lexer.find(language)
    +    Pygments.highlight(code, lexer: language, options: {encoding: 'utf-8'})
    +  else
    +    Pygments.highlight(code, options: {encoding: 'utf-8'})
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + postprocess(full_document) + click to toggle source +
    + + +
    + + + + + +
    +
    # File lib/redcarpet/render/gitlab_html.rb, line 20
    +def postprocess(full_document)
    +  h.gfm(full_document)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/RefsController.html b/doc/app/RefsController.html new file mode 100644 index 00000000..a8248da0 --- /dev/null +++ b/doc/app/RefsController.html @@ -0,0 +1,638 @@ + + + + + + +class RefsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class RefsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + logs_tree() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/refs_controller.rb, line 31
    +def logs_tree
    +  contents = @tree.contents
    +  @logs = contents.map do |content|
    +    file = params[:path] ? File.join(params[:path], content.name) : content.name
    +    last_commit = @project.commits(@commit.id, file, 1).last
    +    last_commit = CommitDecorator.decorate(last_commit)
    +    {
    +      file_name: content.name,
    +      commit: last_commit
    +    }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + switch() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/refs_controller.rb, line 12
    +def switch
    +  respond_to do |format|
    +    format.html do
    +      new_path = if params[:destination] == "tree"
    +                   project_tree_path(@project, @ref)
    +                 else
    +                   project_commits_path(@project, @ref)
    +                 end
    +
    +      redirect_to new_path
    +    end
    +    format.js do
    +      @ref = params[:ref]
    +      define_tree_vars
    +      render "tree"
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + define_tree_vars() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/refs_controller.rb, line 46
    +def define_tree_vars
    +  params[:path] = nil if params[:path].blank?
    +
    +  @repo = project.repo
    +  @commit = project.commit(@ref)
    +  @commit = CommitDecorator.decorate(@commit)
    +  @tree = Tree.new(@commit.tree, project, @ref, params[:path])
    +  @tree = TreeDecorator.new(@tree)
    +  @hex_path = Digest::SHA1.hexdigest(params[:path] || "")
    +
    +  if params[:path]
    +    @logs_path = logs_file_project_ref_path(@project, @ref, params[:path])
    +  else
    +    @logs_path = logs_tree_project_ref_path(@project, @ref)
    +  end
    +rescue
    +  return render_404
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ref() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/refs_controller.rb, line 65
    +def ref
    +  @ref = params[:id] || params[:ref]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/RepositoriesController.html b/doc/app/RepositoriesController.html new file mode 100644 index 00000000..3a22f71e --- /dev/null +++ b/doc/app/RepositoriesController.html @@ -0,0 +1,593 @@ + + + + + + +class RepositoriesController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class RepositoriesController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + archive() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/repositories_controller.rb, line 19
    +def archive
    +  unless can?(current_user, :download_code, @project)
    +    render_404 and return 
    +  end
    +
    +
    +  file_path = @project.archive_repo(params[:ref])
    +
    +  if file_path
    +    # Send file to user
    +    send_file file_path
    +  else
    +    render_404
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branches() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/repositories_controller.rb, line 11
    +def branches
    +  @branches = @project.branches
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/repositories_controller.rb, line 7
    +def show
    +  @activities = @project.commits_with_refs(20)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tags() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/repositories_controller.rb, line 15
    +def tags
    +  @tags = @project.tags
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Repository.html b/doc/app/Repository.html new file mode 100644 index 00000000..cb68146c --- /dev/null +++ b/doc/app/Repository.html @@ -0,0 +1,1566 @@ + + + + + + +module Repository - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Repository

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + archive_repo(ref) + click to toggle source +
    + + +
    + +

    Archive Project to .tar.gz

    + +

    Already packed repo archives stored at +app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz

    + + + +
    +
    # File app/roles/repository.rb, line 157
    +def archive_repo(ref)
    +  ref = ref || self.root_ref
    +  commit = self.commit(ref)
    +  return nil unless commit
    +
    +  # Build file path
    +  file_name = self.code + "-" + commit.id.to_s + ".tar.gz"
    +  storage_path = Rails.root.join("tmp", "repositories", self.code)
    +  file_path = File.join(storage_path, file_name)
    +
    +  # Put files into a directory before archiving
    +  prefix = self.code + "/"
    +
    +  # Create file if not exists
    +  unless File.exists?(file_path)
    +    FileUtils.mkdir_p storage_path
    +    file = self.repo.archive_to_file(ref, prefix,  file_path)
    +  end
    +
    +  file_path
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branch_names() + click to toggle source +
    + + +
    + +

    Returns an Array of branch names

    + + + +
    +
    # File app/roles/repository.rb, line 53
    +def branch_names
    +  repo.branches.collect(&:name).sort
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + branches() + click to toggle source +
    + + +
    + +

    Returns an Array of Branches

    + + + +
    +
    # File app/roles/repository.rb, line 58
    +def branches
    +  repo.branches.sort_by(&:name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commit(commit_id = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 15
    +def commit(commit_id = nil)
    +  Commit.find_or_first(repo, commit_id, root_ref)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits(ref, path = nil, limit = nil, offset = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 31
    +def commits(ref, path = nil, limit = nil, offset = nil)
    +  Commit.commits(repo, ref, path, limit, offset)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_between(from, to) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 39
    +def commits_between(from, to)
    +  Commit.commits_between(repo, from, to)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_since(date) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 27
    +def commits_since(date)
    +  Commit.commits_since(repo, date)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + commits_with_refs(n = 20) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 23
    +def commits_with_refs(n = 20)
    +  Commit.commits_with_refs(repo, n)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy_repository() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 93
    +def destroy_repository
    +  git_host.remove_repository(self)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + discover_default_branch() + click to toggle source +
    + + +
    + +

    Discovers the default branch based on the repository’s available branches

    +
    • +

      If no branches are present, returns nil

      +
    • +

      If one branch is present, returns its name

      +
    • +

      If two or more branches are present, returns the one that has a name +matching #root_ref +(default_branch or ‘master’ if default_branch is nil)

      +
    + + + +
    +
    # File app/roles/repository.rb, line 128
    +def discover_default_branch
    +  if branch_names.length == 0
    +    nil
    +  elsif branch_names.length == 1
    +    branch_names.first
    +  else
    +    branch_names.select { |v| v == root_ref }.first
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + empty_repo?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 11
    +def empty_repo?
    +  !repo_exists? || !has_commits?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + fresh_commits(n = 10) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 19
    +def fresh_commits(n = 10)
    +  Commit.fresh_commits(repo, n)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + has_commits?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 138
    +def has_commits?
    +  !!commit
    +rescue Grit::NoSuchPathError
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + has_post_receive_file?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 47
    +def has_post_receive_file?
    +  hook_file = File.join(path_to_repo, 'hooks', 'post-receive')
    +  File.exists?(hook_file)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + heads() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 103
    +def heads
    +  @heads ||= repo.heads
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + http_url_to_repo() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 183
    +def http_url_to_repo
    +  http_url = [Gitlab.config.url, "/", path, ".git"].join('')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + last_commit_for(ref, path = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 35
    +def last_commit_for(ref, path = nil)
    +  commits(ref, path, 1).first
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + open_branches() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 113
    +def open_branches
    +  if protected_branches.empty?
    +    self.repo.heads
    +  else
    +    pnames = protected_branches.map(&:name)
    +    self.repo.heads.reject { |h| pnames.include?(h.name) }
    +  end.sort_by(&:name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + path_to_repo() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 85
    +def path_to_repo
    +  File.join(Gitlab.config.git_base_path, "#{path}.git")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + protected_branch?(branch_name) + click to toggle source +
    + + +
    + +

    Check if current branch name is marked as protected in the system

    + + + +
    +
    # File app/roles/repository.rb, line 188
    +def protected_branch? branch_name
    +  protected_branches.map(&:name).include?(branch_name)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ref_names() + click to toggle source +
    + + +
    + +

    Returns an Array of branch and tag names

    + + + +
    +
    # File app/roles/repository.rb, line 73
    +def ref_names
    +  [branch_names + tag_names].flatten
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repo() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 77
    +def repo
    +  @repo ||= Grit::Repo.new(path_to_repo)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repo_exists?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 97
    +def repo_exists?
    +  @repo_exists ||= (repo && !repo.branches.empty?)
    +rescue
    +  @repo_exists = false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + root_ref() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 144
    +def root_ref
    +  default_branch || "master"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + root_ref?(branch) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 148
    +def root_ref?(branch)
    +  root_ref == branch
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + satellite() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 43
    +def satellite
    +  @satellite ||= Gitlab::Satellite.new(self)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + ssh_url_to_repo() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 179
    +def ssh_url_to_repo
    +  url_to_repo
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tag_names() + click to toggle source +
    + + +
    + +

    Returns an Array of tag names

    + + + +
    +
    # File app/roles/repository.rb, line 63
    +def tag_names
    +  repo.tags.collect(&:name).sort.reverse
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tags() + click to toggle source +
    + + +
    + +

    Returns an Array of Tags

    + + + +
    +
    # File app/roles/repository.rb, line 68
    +def tags
    +  repo.tags.sort_by(&:name).reverse
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tree(fcommit, path = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 107
    +def tree(fcommit, path = nil)
    +  fcommit = commit if fcommit == :head
    +  tree = fcommit.tree
    +  path ? (tree / path) : tree
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_repository() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 89
    +def update_repository
    +  git_host.update_repository(self)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + url_to_repo() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 81
    +def url_to_repo
    +  git_host.url_to_repo(path)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + valid_repo?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/repository.rb, line 4
    +def valid_repo?
    +  repo
    +rescue
    +  errors.add(:path, "Invalid repository path")
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SearchContext.html b/doc/app/SearchContext.html new file mode 100644 index 00000000..6a3d2bd5 --- /dev/null +++ b/doc/app/SearchContext.html @@ -0,0 +1,599 @@ + + + + + + +class SearchContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SearchContext

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + params[RW] +
    + +
    + + + +
    +
    + +
    +
    + project_ids[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(project_ids, params) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/search_context.rb, line 4
    +def initialize(project_ids, params)
    +  @project_ids, @params = project_ids, params.dup
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/search_context.rb, line 8
    +def execute
    +  query = params[:search]
    +
    +  return result unless query.present?
    +
    +  result[:projects] = Project.where(id: project_ids).search(query).limit(10)
    +  result[:merge_requests] = MergeRequest.where(project_id: project_ids).search(query).limit(10)
    +  result[:issues] = Issue.where(project_id: project_ids).search(query).limit(10)
    +  result
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + result() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/search_context.rb, line 19
    +def result
    +  @result ||= {
    +    projects: [],
    +    merge_requests: [],
    +    issues: []
    +  }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SearchController.html b/doc/app/SearchController.html new file mode 100644 index 00000000..0c14ea8f --- /dev/null +++ b/doc/app/SearchController.html @@ -0,0 +1,489 @@ + + + + + + +class SearchController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SearchController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/search_controller.rb, line 2
    +def show
    +  result = SearchContext.new(current_user.project_ids, params).execute
    +
    +  @projects       = result[:projects]
    +  @merge_requests = result[:merge_requests]
    +  @issues         = result[:issues]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Snippet.html b/doc/app/Snippet.html new file mode 100644 index 00000000..a24e4494 --- /dev/null +++ b/doc/app/Snippet.html @@ -0,0 +1,667 @@ + + + + + + +class Snippet - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Snippet

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + content_types() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 23
    +def self.content_types
    +  [
    +    ".rb", ".py", ".pl", ".scala", ".c", ".cpp", ".java",
    +    ".haml", ".html", ".sass", ".scss", ".xml", ".php", ".erb",
    +    ".js", ".sh", ".coffee", ".yml", ".md"
    +  ]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + data() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 31
    +def data
    +  content
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + expired?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 47
    +def expired?
    +  expires_at && expires_at < Time.current
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + mode() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 43
    +def mode
    +  nil
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + name() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 39
    +def name
    +  file_name
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + size() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/snippet.rb, line 35
    +def size
    +  0
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SnippetsController.html b/doc/app/SnippetsController.html new file mode 100644 index 00000000..7585a295 --- /dev/null +++ b/doc/app/SnippetsController.html @@ -0,0 +1,833 @@ + + + + + + +class SnippetsController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SnippetsController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 26
    +def create
    +  @snippet = @project.snippets.new(params[:snippet])
    +  @snippet.author = current_user
    +  @snippet.save
    +
    +  if @snippet.valid?
    +    redirect_to [@project, @snippet]
    +  else
    +    respond_with(@snippet)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 55
    +def destroy
    +  return access_denied! unless can?(current_user, :admin_snippet, @snippet)
    +
    +  @snippet.destroy
    +
    +  redirect_to project_snippets_path(@project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 38
    +def edit
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 18
    +def index
    +  @snippets = @project.snippets
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 22
    +def new
    +  @snippet = @project.snippets.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + raw() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 63
    +def raw 
    +  send_data(
    +    @snippet.content,
    +    type: "text/plain",
    +    disposition: 'inline',
    +    filename: @snippet.file_name
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 51
    +def show
    +  @note = @project.notes.new(noteable: @snippet)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 41
    +def update
    +  @snippet.update_attributes(params[:snippet])
    +
    +  if @snippet.valid?
    +    redirect_to [@project, @snippet]
    +  else
    +    respond_with(@snippet)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + authorize_admin_snippet!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 82
    +def authorize_admin_snippet!
    +  return render_404 unless can?(current_user, :admin_snippet, @snippet)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + authorize_modify_snippet!() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 78
    +def authorize_modify_snippet!
    +  return render_404 unless can?(current_user, :modify_snippet, @snippet)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + snippet() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/snippets_controller.rb, line 74
    +def snippet
    +  @snippet ||= @project.snippets.find(params[:id])
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SnippetsHelper.html b/doc/app/SnippetsHelper.html new file mode 100644 index 00000000..99c08d51 --- /dev/null +++ b/doc/app/SnippetsHelper.html @@ -0,0 +1,485 @@ + + + + + + +module SnippetsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module SnippetsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + lifetime_select_options() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/snippets_helper.rb, line 2
    +def lifetime_select_options
    +  options = [
    +      ['forever', nil],
    +      ['1 day',   "#{Date.current + 1.day}"],
    +      ['1 week',  "#{Date.current + 1.week}"],
    +      ['1 month', "#{Date.current + 1.month}"]
    +  ]
    +  options_for_select(options)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/StaticModel.html b/doc/app/StaticModel.html new file mode 100644 index 00000000..9dd1617c --- /dev/null +++ b/doc/app/StaticModel.html @@ -0,0 +1,648 @@ + + + + + + +module StaticModel - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module StaticModel

    + +
    + +

    Provides an ActiveRecord-like interface to a model whose data is not +persisted to a database.

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + ==(other) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/static_model.rb, line 40
    +def ==(other)
    +  if other.is_a? StaticModel
    +    id == other.id
    +  else
    +    super
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + [](key) + click to toggle source +
    + + +
    + +

    Used by AR for fetching attributes

    + +

    Pass it along if we respond to it.

    + + + +
    +
    # File app/roles/static_model.rb, line 20
    +def [](key)
    +  send(key) if respond_to?(key)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroyed?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/static_model.rb, line 36
    +def destroyed?
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new_record?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/static_model.rb, line 28
    +def new_record?
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + persisted?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/static_model.rb, line 32
    +def persisted?
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + to_param() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/static_model.rb, line 24
    +def to_param
    +  id
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/StaticModel/ClassMethods.html b/doc/app/StaticModel/ClassMethods.html new file mode 100644 index 00000000..27ee1373 --- /dev/null +++ b/doc/app/StaticModel/ClassMethods.html @@ -0,0 +1,511 @@ + + + + + + +module StaticModel::ClassMethods - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module StaticModel::ClassMethods

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + base_class() + click to toggle source +
    + + +
    + +

    Used by ActiveRecord’s polymorphic association to set object_type

    + + + +
    +
    # File app/roles/static_model.rb, line 12
    +def base_class
    +  self
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + primary_key() + click to toggle source +
    + + +
    + +

    Used by ActiveRecord’s polymorphic association to set object_id

    + + + +
    +
    # File app/roles/static_model.rb, line 7
    +def primary_key
    +  'id'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SystemHook.html b/doc/app/SystemHook.html new file mode 100644 index 00000000..8e35bf27 --- /dev/null +++ b/doc/app/SystemHook.html @@ -0,0 +1,525 @@ + + + + + + +class SystemHook - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SystemHook

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + all_hooks_fire(data) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/system_hook.rb, line 2
    +def self.all_hooks_fire(data)
    +  SystemHook.all.each do |sh|
    +    sh.async_execute data
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + async_execute(data) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/system_hook.rb, line 8
    +def async_execute(data)
    +  Resque.enqueue(SystemHookWorker, id, data)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SystemHookObserver.html b/doc/app/SystemHookObserver.html new file mode 100644 index 00000000..20d81963 --- /dev/null +++ b/doc/app/SystemHookObserver.html @@ -0,0 +1,573 @@ + + + + + + +class SystemHookObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SystemHookObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(model) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/system_hook_observer.rb, line 4
    +def after_create(model)
    +  if model.kind_of? Project
    +    SystemHook.all_hooks_fire({
    +      event_name: "project_create",
    +      name: model.name,
    +      path: model.path,
    +      project_id: model.id,
    +      owner_name: model.owner.name,
    +      owner_email: model.owner.email,
    +      created_at: model.created_at
    +    })
    +  elsif model.kind_of? User 
    +    SystemHook.all_hooks_fire({
    +      event_name: "user_create",
    +      name: model.name,
    +      email: model.email,
    +      created_at: model.created_at
    +    })
    +
    +  elsif model.kind_of? UsersProject
    +    SystemHook.all_hooks_fire({
    +      event_name: "user_add_to_team",
    +      project_name: model.project.name,
    +      project_path: model.project.path,
    +      project_id: model.project_id,
    +      user_name: model.user.name,
    +      user_email: model.user.email,
    +      project_access: model.repo_access_human,
    +      created_at: model.created_at
    +    })
    +
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_destroy(model) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/system_hook_observer.rb, line 38
    +def after_destroy(model)
    +  if model.kind_of? Project
    +    SystemHook.all_hooks_fire({
    +      event_name: "project_destroy",
    +      name: model.name,
    +      path: model.path,
    +      project_id: model.id,
    +      owner_name: model.owner.name,
    +      owner_email: model.owner.email,
    +    })
    +  elsif model.kind_of? User
    +    SystemHook.all_hooks_fire({
    +      event_name: "user_destroy",
    +      name: model.name,
    +      email: model.email
    +    })
    +
    +  elsif model.kind_of? UsersProject
    +    SystemHook.all_hooks_fire({
    +      event_name: "user_remove_from_team",
    +      project_name: model.project.name,
    +      project_path: model.project.path,
    +      project_id: model.project_id,
    +      user_name: model.user.name,
    +      user_email: model.user.email,
    +      project_access: model.repo_access_human
    +    })
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/SystemHookWorker.html b/doc/app/SystemHookWorker.html new file mode 100644 index 00000000..153eb577 --- /dev/null +++ b/doc/app/SystemHookWorker.html @@ -0,0 +1,485 @@ + + + + + + +class SystemHookWorker - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class SystemHookWorker

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + perform(hook_id, data) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/workers/system_hook_worker.rb, line 4
    +def self.perform(hook_id, data)
    +  SystemHook.find(hook_id).execute data
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TabHelper.html b/doc/app/TabHelper.html new file mode 100644 index 00000000..43cc08a4 --- /dev/null +++ b/doc/app/TabHelper.html @@ -0,0 +1,621 @@ + + + + + + +module TabHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module TabHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + branches_tab_class() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tab_helper.rb, line 80
    +def branches_tab_class
    +  if current_page?(branches_project_repository_path(@project)) ||
    +    current_controller?(:protected_branches) ||
    +    current_page?(project_repository_path(@project))
    +    'active'
    +  end
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + project_tab_class() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tab_helper.rb, line 70
    +def project_tab_class
    +  [:show, :files, :edit, :update].each do |action|
    +    return "active" if current_page?(controller: "projects", action: action, id: @project)
    +  end
    +
    +  if ['snippets', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
    +   "active"
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TagsHelper.html b/doc/app/TagsHelper.html new file mode 100644 index 00000000..3a98d61f --- /dev/null +++ b/doc/app/TagsHelper.html @@ -0,0 +1,516 @@ + + + + + + +module TagsHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module TagsHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + tag_list(project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tags_helper.rb, line 6
    +def tag_list project
    +  html = ''
    +  project.tag_list.each do |tag|
    +    html += link_to tag, tag_path(tag)
    +  end
    +
    +  html.html_safe
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tag_path(tag) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tags_helper.rb, line 2
    +def tag_path tag
    +  "/tags/#{tag}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Team.html b/doc/app/Team.html new file mode 100644 index 00000000..3a583694 --- /dev/null +++ b/doc/app/Team.html @@ -0,0 +1,710 @@ + + + + + + +module Team - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Team

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + add_user_id_to_team(user_id, access_role) + click to toggle source +
    + + +
    + +

    Add user to project with passed access role by user id

    + + + +
    +
    # File app/roles/team.rb, line 26
    +def add_user_id_to_team(user_id, access_role)
    +  users_projects.create(
    +    user_id: user_id,
    +    project_access: access_role
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + add_user_to_team(user, access_role) + click to toggle source +
    + + +
    + +

    Add user to project with passed access role

    + + + +
    +
    # File app/roles/team.rb, line 14
    +def add_user_to_team(user, access_role)
    +  add_user_id_to_team(user.id, access_role)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + add_users_ids_to_team(users_ids, access_role) + click to toggle source +
    + + +
    + +

    Add multiple users to project with same access role by user ids

    + + + +
    +
    # File app/roles/team.rb, line 35
    +def add_users_ids_to_team(users_ids, access_role)
    +  UsersProject.bulk_import(self, users_ids, access_role)
    +  self.update_repository
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + add_users_to_team(users, access_role) + click to toggle source +
    + + +
    + +

    Add multiple users to project with same access role

    + + + +
    +
    # File app/roles/team.rb, line 20
    +def add_users_to_team(users, access_role)
    +  add_users_ids_to_team(users.map(&:id), access_role)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + delete_users_ids_from_team(users_ids) + click to toggle source +
    + + +
    + +

    Delete multiple users from project by user ids

    + + + +
    +
    # File app/roles/team.rb, line 48
    +def delete_users_ids_from_team(users_ids)
    +  UsersProject.bulk_delete(self, users_ids)
    +  self.update_repository
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + team_member_by_id(user_id) + click to toggle source +
    + + +
    + +

    Get Team Member record by user id

    + + + +
    +
    # File app/roles/team.rb, line 8
    +def team_member_by_id(user_id)
    +  users_projects.find_by_user_id(user_id)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + team_member_by_name_or_email(name = nil, email = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/team.rb, line 2
    +def team_member_by_name_or_email(name = nil, email = nil)
    +  user = users.where("name like ? or email like ?", name, email).first
    +  users_projects.where(user: user) if user
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_users_ids_to_role(users_ids, access_role) + click to toggle source +
    + + +
    + +

    Update multiple project users to same access role by user ids

    + + + +
    +
    # File app/roles/team.rb, line 42
    +def update_users_ids_to_role(users_ids, access_role)
    +  UsersProject.bulk_update(self, users_ids, access_role)
    +  self.update_repository
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TeamMembersController.html b/doc/app/TeamMembersController.html new file mode 100644 index 00000000..46af7c9f --- /dev/null +++ b/doc/app/TeamMembersController.html @@ -0,0 +1,698 @@ + + + + + + +class TeamMembersController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class TeamMembersController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + apply_import() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 47
    +def apply_import
    +  giver = Project.find(params[:source_project_id])
    +  status = UsersProject.import_team(giver, project)
    +  notice = status ? "Succesfully imported" : "Import failed"
    +
    +  redirect_to project_team_members_path(project), notice: notice
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 18
    +def create
    +  @project.add_users_ids_to_team(
    +    params[:user_ids],
    +    params[:project_access]
    +  )
    +
    +  redirect_to project_team_index_path(@project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 37
    +def destroy
    +  @team_member = project.users_projects.find(params[:id])
    +  @team_member.destroy
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_team_index_path(@project) }
    +    format.js { render nothing: true }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + index() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 6
    +def index
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + new() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 14
    +def new
    +  @team_member = project.users_projects.new
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 9
    +def show
    +  @team_member = project.users_projects.find(params[:id])
    +  @events = @team_member.user.recent_events.where(:project_id => @project.id).limit(7)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/team_members_controller.rb, line 27
    +def update
    +  @team_member = project.users_projects.find(params[:id])
    +  @team_member.update_attributes(params[:team_member])
    +
    +  unless @team_member.valid?
    +    flash[:alert] = "User should have at least one role"
    +  end
    +  redirect_to project_team_index_path(@project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TestHookContext.html b/doc/app/TestHookContext.html new file mode 100644 index 00000000..e18701cb --- /dev/null +++ b/doc/app/TestHookContext.html @@ -0,0 +1,488 @@ + + + + + + +class TestHookContext - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class TestHookContext

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/contexts/test_hook_context.rb, line 2
    +def execute
    +  hook = project.hooks.find(params[:id])
    +  commits = project.commits(project.default_branch, nil, 3)
    +  data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
    +  hook.execute(data)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Tree.html b/doc/app/Tree.html new file mode 100644 index 00000000..f1f414a4 --- /dev/null +++ b/doc/app/Tree.html @@ -0,0 +1,663 @@ + + + + + + +class Tree - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Tree

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + path[RW] +
    + +
    + + + +
    +
    + +
    +
    + project[RW] +
    + +
    + + + +
    +
    + +
    +
    + ref[RW] +
    + +
    + + + +
    +
    + +
    +
    + tree[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + new(raw_tree, project, ref = nil, path = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/tree.rb, line 8
    +def initialize(raw_tree, project, ref = nil, path = nil)
    +  @project, @ref, @path = project, ref, path
    +  @tree = if path.present?
    +            raw_tree / path.dup.force_encoding('ascii-8bit')
    +          else
    +            raw_tree
    +          end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + empty?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/tree.rb, line 25
    +def empty?
    +  data.blank?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + invalid?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/tree.rb, line 21
    +def invalid?
    +  tree.nil?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + is_blob?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/tree.rb, line 17
    +def is_blob?
    +  tree.is_a?(Grit::Blob)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TreeController.html b/doc/app/TreeController.html new file mode 100644 index 00000000..1adba0ec --- /dev/null +++ b/doc/app/TreeController.html @@ -0,0 +1,583 @@ + + + + + + +class TreeController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class TreeController

    + +
    + +

    Controller for viewing a repository’s file structure

    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/tree_controller.rb, line 24
    +def edit
    +  @last_commit = @project.last_commit_for(@ref, @path).sha
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/tree_controller.rb, line 13
    +def show
    +  @hex_path  = Digest::SHA1.hexdigest(@path)
    +  @logs_path = logs_file_project_ref_path(@project, @ref, @path)
    +
    +  respond_to do |format|
    +    format.html
    +    # Disable cache so browser history works
    +    format.js { no_cache_headers }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/tree_controller.rb, line 28
    +def update
    +  file_editor = Gitlab::FileEditor.new(current_user, @project, @ref)
    +  update_status = file_editor.update(
    +    @path,
    +    params[:content],
    +    params[:commit_message],
    +    params[:last_commit]
    +  )
    +
    +  if update_status
    +    redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited"
    +  else
    +    flash[:notice] = "Your changes could not be commited, because the file has been changed"
    +    render :edit
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TreeDecorator.html b/doc/app/TreeDecorator.html new file mode 100644 index 00000000..e6bdc0fa --- /dev/null +++ b/doc/app/TreeDecorator.html @@ -0,0 +1,597 @@ + + + + + + +class TreeDecorator - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class TreeDecorator

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + breadcrumbs(max_links = 2) { |link_to("..", "| ... } + click to toggle source +
    + + +
    + + + + + + + +
    + + + + +
    + + +
    + +
    + readme() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/tree_decorator.rb, line 32
    +def readme
    +  @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ %r^readme/ }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + up_dir?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/tree_decorator.rb, line 23
    +def up_dir?
    +  path.present?
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + up_dir_path() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/decorators/tree_decorator.rb, line 27
    +def up_dir_path
    +  file = File.join(path, "..")
    +  h.project_tree_path(project, h.tree_join(ref, file))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/TreeHelper.html b/doc/app/TreeHelper.html new file mode 100644 index 00000000..e185ba72 --- /dev/null +++ b/doc/app/TreeHelper.html @@ -0,0 +1,736 @@ + + + + + + +module TreeHelper - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module TreeHelper

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + allowed_tree_edit?() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tree_helper.rb, line 63
    +def allowed_tree_edit?
    +  if @project.protected_branch? @ref
    +    can?(current_user, :push_code_to_protected_branches, @project)
    +  else
    +    can?(current_user, :push_code, @project)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + gitlab_markdown?(filename) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tree_helper.rb, line 50
    +def gitlab_markdown?(filename)
    +  filename.end_with?(*%w(.mdown .md .markdown))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + markup?(filename) + click to toggle source +
    + + +
    + +

    Public: Determines if a given filename is compatible with GitHub::Markup.

    + +

    filename - Filename string to check

    + +

    Returns boolean

    + + + +
    +
    # File app/helpers/tree_helper.rb, line 45
    +def markup?(filename)
    +  filename.end_with?(*%w(.textile .rdoc .org .creole
    +                         .mediawiki .rst .asciidoc .pod))
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + plain_text_readme?(filename) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tree_helper.rb, line 54
    +def plain_text_readme? filename
    +  filename == 'README'
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + render_tree(contents) + click to toggle source +
    + + +
    + +

    Sorts a repository’s tree so that folders are before files and renders +their corresponding partials

    + +

    contents - A Grit::Tree object for the current tree

    + + + +
    +
    # File app/helpers/tree_helper.rb, line 6
    +def render_tree(contents)
    +  # Render Folders before Files/Submodules
    +  folders, files = contents.partition { |v| v.kind_of?(Grit::Tree) }
    +
    +  tree = ""
    +
    +  # Render folders if we have any
    +  tree += render partial: 'tree/tree_item', collection: folders, locals: {type: 'folder'} if folders.present?
    +
    +  files.each do |f|
    +    if f.respond_to?(:url)
    +      # Object is a Submodule
    +      tree += render partial: 'tree/submodule_item', object: f
    +    else
    +      # Object is a Blob
    +      tree += render partial: 'tree/tree_item', object: f, locals: {type: 'file'}
    +    end
    +  end
    +
    +  tree.html_safe
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tree_hex_class(content) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/helpers/tree_helper.rb, line 36
    +def tree_hex_class(content)
    +  "file_#{hexdigest(content.name)}"
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tree_icon(type) + click to toggle source +
    + + +
    + +

    Return an image icon depending on the file type

    + +

    type - String type of the tree item; either ‘folder’ or ‘file’

    + + + +
    +
    # File app/helpers/tree_helper.rb, line 31
    +def tree_icon(type)
    +  image = type == 'folder' ? 'file_dir.png' : 'file_txt.png'
    +  image_tag(image, size: '16x16')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + tree_join(*args) + click to toggle source +
    + + +
    + +

    Simple shortcut to File.join

    + + + +
    +
    # File app/helpers/tree_helper.rb, line 59
    +def tree_join(*args)
    +  File.join(*args)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/User.html b/doc/app/User.html new file mode 100644 index 00000000..513f9644 --- /dev/null +++ b/doc/app/User.html @@ -0,0 +1,755 @@ + + + + + + +class User - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class User

    + +
    + +
    + + + + +
    + + + + + + + + +
    +

    Attributes

    + + +
    +
    + force_random_password[RW] +
    + +
    + + + +
    +
    + +
    + + + + +
    +

    Public Class Methods

    + + +
    + +
    + create_from_omniauth(auth, ldap = false) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 55
    +def create_from_omniauth(auth, ldap = false)
    +  gitlab_auth.create_from_omniauth(auth, ldap)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + filter(filter_name) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 41
    +def filter filter_name
    +  case filter_name
    +  when "admins"; self.admins
    +  when "blocked"; self.blocked
    +  when "wop"; self.without_projects
    +  else
    +    self.active
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + find_for_ldap_auth(auth, signed_in_resource = nil) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 63
    +def find_for_ldap_auth(auth, signed_in_resource = nil)
    +  gitlab_auth.find_for_ldap_auth(auth, signed_in_resource)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + find_or_new_for_omniauth(auth) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 59
    +def find_or_new_for_omniauth(auth)
    +  gitlab_auth.find_or_new_for_omniauth(auth)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + gitlab_auth() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 67
    +def gitlab_auth
    +  Gitlab::Auth.new
    +end
    +
    + +
    + + + + +
    + + + + + +
    + +
    + without_projects() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 51
    +def without_projects
    +  where('id NOT IN (SELECT DISTINCT(user_id) FROM users_projects)')
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + generate_password() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/user.rb, line 76
    +def generate_password
    +  if self.force_random_password
    +    self.password = self.password_confirmation = Devise.friendly_token.first(8)
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/UserObserver.html b/doc/app/UserObserver.html new file mode 100644 index 00000000..95c7249d --- /dev/null +++ b/doc/app/UserObserver.html @@ -0,0 +1,557 @@ + + + + + + +class UserObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class UserObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_create(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/user_observer.rb, line 2
    +def after_create(user)
    +  log_info("User \"#{user.name}\" (#{user.email}) was created")
    +
    +  Notify.new_user_email(user.id, user.password).deliver
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_destroy(user) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/user_observer.rb, line 8
    +def after_destroy user
    +  log_info("User \"#{user.name}\" (#{user.email})  was removed")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + log_info(message) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/user_observer.rb, line 14
    +def log_info message
    +  Gitlab::AppLogger.info message
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/UsersProject.html b/doc/app/UsersProject.html new file mode 100644 index 00000000..f157832b --- /dev/null +++ b/doc/app/UsersProject.html @@ -0,0 +1,904 @@ + + + + + + +class UsersProject - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class UsersProject

    + +
    + +
    + + + + +
    + + + + + + +
    +

    Constants

    +
    + +
    DEVELOPER + +
    + + +
    GUEST + +
    + + +
    MASTER + +
    + + +
    REPORTER + +
    + + +
    +
    + + + + + + +
    +

    Public Class Methods

    + + +
    + +
    + access_roles() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 96
    +def access_roles
    +  {
    +    "Guest"     => GUEST,
    +    "Reporter"  => REPORTER,
    +    "Developer" => DEVELOPER,
    +    "Master"    => MASTER
    +  }
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + bulk_delete(project, user_ids) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 53
    +def bulk_delete(project, user_ids)
    +  UsersProject.transaction do
    +    UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
    +      users_project.destroy
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + bulk_import(project, user_ids, project_access) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 70
    +def bulk_import(project, user_ids, project_access)
    +  UsersProject.transaction do
    +    user_ids.each do |user_id|
    +      users_project = UsersProject.new(
    +        project_access: project_access,
    +        user_id: user_id
    +      )
    +      users_project.project = project
    +      users_project.save
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + bulk_update(project, user_ids, project_access) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 61
    +def bulk_update(project, user_ids, project_access)
    +  UsersProject.transaction do
    +    UsersProject.where(:user_id => user_ids, :project_id => project.id).each do |users_project|
    +      users_project.project_access = project_access
    +      users_project.save
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + import_team(source_project, target_project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 24
    +def import_team(source_project, target_project)
    +  UsersProject.without_repository_callback do
    +    UsersProject.transaction do
    +      team = source_project.users_projects.all
    +
    +      team.each do |tm|
    +        # Skip if user already present in team
    +        next if target_project.users.include?(tm.user)
    +
    +        new_tm = tm.dup
    +        new_tm.id = nil
    +        new_tm.project_id = target_project.id
    +        new_tm.save
    +      end
    +    end
    +  end
    +
    +  target_project.update_repository
    +  true
    +rescue
    +  false
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + user_bulk_import(user, project_ids, project_access) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 83
    +def user_bulk_import(user, project_ids, project_access)
    +  UsersProject.transaction do
    +    project_ids.each do |project_id|
    +      users_project = UsersProject.new(
    +        project_access: project_access,
    +      )
    +      users_project.project_id = project_id
    +      users_project.user_id = user.id
    +      users_project.save
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + without_repository_callback() { || ... } + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 47
    +def without_repository_callback
    +  UsersProject.skip_callback(:destroy, :after, :update_repository)
    +  yield
    +  UsersProject.set_callback(:destroy, :after, :update_repository)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + project_access_human() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 114
    +def project_access_human
    +  Project.access_options.key(self.project_access)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + repo_access_human() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 118
    +def repo_access_human
    +  self.class.access_roles.invert[self.project_access]
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + role_access() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 106
    +def role_access
    +  project_access
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + update_repository() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/users_project.rb, line 110
    +def update_repository
    +  git_host.update_repository(project)
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/UsersProjectObserver.html b/doc/app/UsersProjectObserver.html new file mode 100644 index 00000000..7c7b90a0 --- /dev/null +++ b/doc/app/UsersProjectObserver.html @@ -0,0 +1,558 @@ + + + + + + +class UsersProjectObserver - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class UsersProjectObserver

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + after_commit(users_project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/users_project_observer.rb, line 2
    +def after_commit(users_project)
    +  return if users_project.destroyed?
    +  Notify.project_access_granted_email(users_project.id).deliver
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_create(users_project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/users_project_observer.rb, line 7
    +def after_create(users_project)
    +  Event.create(
    +    project_id: users_project.project.id,
    +    action: Event::Joined,
    +    author_id: users_project.user.id
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + after_destroy(users_project) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/observers/users_project_observer.rb, line 15
    +def after_destroy(users_project)
    +  Event.create(
    +    project_id: users_project.project.id,
    +    action: Event::Left,
    +    author_id: users_project.user.id
    +  )
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Votes.html b/doc/app/Votes.html new file mode 100644 index 00000000..9fa2a0b7 --- /dev/null +++ b/doc/app/Votes.html @@ -0,0 +1,615 @@ + + + + + + +module Votes - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    module Votes

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + downvotes() + click to toggle source +
    + + +
    + +

    Return the number of -1 comments (downvotes)

    + + + +
    +
    # File app/roles/votes.rb, line 16
    +def downvotes
    +  notes.select(&:downvote?).size
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + downvotes_in_percent() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/votes.rb, line 20
    +def downvotes_in_percent
    +  if votes_count.zero?
    +    0
    +  else
    +    100.0 - upvotes_in_percent
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + upvotes() + click to toggle source +
    + + +
    + +

    Return the number of +1 comments (upvotes)

    + + + +
    +
    # File app/roles/votes.rb, line 3
    +def upvotes
    +  notes.select(&:upvote?).size
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + upvotes_in_percent() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/roles/votes.rb, line 7
    +def upvotes_in_percent
    +  if votes_count.zero?
    +    0
    +  else
    +    100.0 / votes_count * upvotes
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + votes_count() + click to toggle source +
    + + +
    + +

    Return the total number of votes

    + + + +
    +
    # File app/roles/votes.rb, line 29
    +def votes_count
    +  upvotes + downvotes
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/WebHook.html b/doc/app/WebHook.html new file mode 100644 index 00000000..44a89adb --- /dev/null +++ b/doc/app/WebHook.html @@ -0,0 +1,506 @@ + + + + + + +class WebHook - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class WebHook

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + execute(data) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/web_hook.rb, line 12
    +def execute(data)
    +  parsed_url = URI.parse(url)
    +  if parsed_url.userinfo.blank?
    +    WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
    +  else
    +    post_url = url.gsub("#{parsed_url.userinfo}@", "")
    +    WebHook.post(post_url,
    +                 body: data.to_json,
    +                 headers: {"Content-Type" => "application/json"},
    +                 basic_auth: {username: parsed_url.user, password: parsed_url.password})
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/Wiki.html b/doc/app/Wiki.html new file mode 100644 index 00000000..c2bf5b61 --- /dev/null +++ b/doc/app/Wiki.html @@ -0,0 +1,567 @@ + + + + + + +class Wiki - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class Wiki

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Protected Class Methods

    + + +
    + +
    + regenerate_from(wiki) + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/wiki.rb, line 20
    +def self.regenerate_from wiki
    +  regenerated_field = [:slug, :content, :title]
    +
    +  new_wiki = Wiki.new
    +  regenerated_field.each do |field|
    +    new_wiki.send("#{field}=", wiki.send(field))
    +  end
    +  new_wiki
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Public Instance Methods

    + + +
    + +
    + to_param() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/wiki.rb, line 14
    +def to_param
    +  slug
    +end
    +
    + +
    + + + + +
    + + +
    + +
    +

    Protected Instance Methods

    + + +
    + +
    + set_slug() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/models/wiki.rb, line 30
    +def set_slug
    +  self.slug = self.title.parameterize
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/WikisController.html b/doc/app/WikisController.html new file mode 100644 index 00000000..4a4e930c --- /dev/null +++ b/doc/app/WikisController.html @@ -0,0 +1,676 @@ + + + + + + +class WikisController - Rails Application Documentation + + + + + + + + + + + + + + + + +
    +

    class WikisController

    + +
    + +
    + + + + +
    + + + + + + + + + + +
    +

    Public Instance Methods

    + + +
    + +
    + create() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 36
    +def create
    +  @wiki = @project.wikis.new(params[:wiki])
    +  @wiki.user = current_user
    +
    +  respond_to do |format|
    +    if @wiki.save
    +      format.html { redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.' }
    +    else
    +      format.html { render action: "edit" }
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + destroy() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 53
    +def destroy
    +  @wikis = @project.wikis.where(slug: params[:id]).delete_all
    +
    +  respond_to do |format|
    +    format.html { redirect_to project_wiki_path(@project, :index), notice: "Page was successfully deleted" }
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + edit() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 31
    +def edit
    +  @wiki = @project.wikis.where(slug: params[:id]).order("created_at").last
    +  @wiki = Wiki.regenerate_from @wiki
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + history() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 49
    +def history
    +  @wikis = @project.wikis.where(slug: params[:id]).order("created_at")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + pages() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 6
    +def pages
    +  @wikis = @project.wikis.group(:slug).order("created_at")
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + show() + click to toggle source +
    + + +
    + + + + + +
    +
    # File app/controllers/wikis_controller.rb, line 10
    +def show
    +  if params[:old_page_id]
    +    @wiki = @project.wikis.find(params[:old_page_id])
    +  else
    +    @wiki = @project.wikis.where(slug: params[:id]).order("created_at").last
    +  end
    +
    +  @note = @project.notes.new(noteable: @wiki)
    +
    +  if @wiki
    +    render 'show'
    +  else
    +    if can?(current_user, :write_wiki, @project)
    +      @wiki = @project.wikis.new(slug: params[:id])
    +      render 'edit'
    +    else
    +      render 'empty'
    +    end
    +  end
    +end
    +
    + +
    + + + + +
    + + +
    + +
    + +
    + + + + diff --git a/doc/app/created.rid b/doc/app/created.rid new file mode 100644 index 00000000..972a7e6f --- /dev/null +++ b/doc/app/created.rid @@ -0,0 +1,135 @@ +Thu, 25 Oct 2012 11:45:21 +0300 +doc/README_FOR_APP Wed, 06 Jun 2012 13:56:49 +0300 +app/observers/issue_observer.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/observers/key_observer.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/observers/project_observer.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/observers/activity_observer.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/observers/user_observer.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/observers/merge_request_observer.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/observers/note_observer.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/observers/system_hook_observer.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/observers/users_project_observer.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/contexts/test_hook_context.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/contexts/commit_load_context.rb Mon, 22 Oct 2012 16:08:19 +0300 +app/contexts/notes/create_context.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/contexts/notes/load_context.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/contexts/search_context.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/contexts/issues_bulk_update_context.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/contexts/base_context.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/contexts/merge_requests_load_context.rb Mon, 22 Oct 2012 16:08:19 +0300 +app/contexts/issues_list_context.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/mailers/notify.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/team.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/push_event.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/votes.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/roles/issue_commonality.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/git_host.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/roles/authority.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/push_observer.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/roles/account.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/static_model.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/roles/repository.rb Wed, 24 Oct 2012 12:43:00 +0300 +app/workers/post_receive.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/workers/system_hook_worker.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/controllers/issues_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/labels_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/project_resource_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/dashboard_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/projects_controller.rb Tue, 23 Oct 2012 11:29:23 +0300 +app/controllers/repositories_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/milestones_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/hooks_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/blob_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/merge_requests_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/admin/logs_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/admin/dashboard_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/admin/projects_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/admin/hooks_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/admin/team_members_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/admin/groups_controller.rb Wed, 24 Oct 2012 12:43:00 +0300 +app/controllers/admin/users_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/admin/resque_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/blame_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/keys_controller.rb Wed, 26 Sep 2012 13:10:32 +0300 +app/controllers/admin_controller.rb Wed, 26 Sep 2012 13:10:32 +0300 +app/controllers/errors_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/help_controller.rb Wed, 06 Jun 2012 13:56:49 +0300 +app/controllers/profile_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/commits_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/team_members_controller.rb Wed, 24 Oct 2012 16:14:03 +0300 +app/controllers/omniauth_callbacks_controller.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/controllers/protected_branches_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/snippets_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/groups_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/compare_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/wikis_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/search_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/deploy_keys_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/tree_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/commit_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/refs_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/controllers/application_controller.rb Wed, 24 Oct 2012 14:17:22 +0300 +app/controllers/notes_controller.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/uploaders/attachment_uploader.rb Wed, 22 Aug 2012 14:52:27 +0300 +app/models/tree.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/project.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/issue.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/project_hook.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/group.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/key.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/snippet.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/user.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/note.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/wiki.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/users_project.rb Wed, 24 Oct 2012 16:14:03 +0300 +app/models/web_hook.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/ability.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/milestone.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/commit.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/protected_branch.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/merge_request.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/event.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/models/system_hook.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/decorators/commit_decorator.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/decorators/event_decorator.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/decorators/application_decorator.rb Fri, 21 Sep 2012 15:40:04 +0300 +app/decorators/tree_decorator.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/tags_helper.rb Wed, 06 Jun 2012 13:56:49 +0300 +app/helpers/application_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/gitlab_markdown_helper.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/helpers/notes_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/profile_helper.rb Fri, 21 Sep 2012 15:47:07 +0300 +app/helpers/tree_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/commits_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/projects_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/events_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/issues_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/tab_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +app/helpers/snippets_helper.rb Wed, 06 Jun 2012 13:56:49 +0300 +app/helpers/merge_requests_helper.rb Mon, 22 Oct 2012 16:08:18 +0300 +lib/file_size_validator.rb Wed, 22 Aug 2012 14:52:27 +0300 +lib/api.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/gitlab/encode.rb Wed, 22 Aug 2012 14:52:27 +0300 +lib/gitlab/graph_commit.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/gitlab/theme.rb Tue, 26 Jun 2012 16:08:37 +0300 +lib/gitlab/app_logger.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/gitlab/inline_diff.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/merge.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/backend/gitolite.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/gitlab/backend/grack_auth.rb Mon, 22 Oct 2012 19:02:02 +0300 +lib/gitlab/backend/gitolite_config.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/git_logger.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/gitlab/markdown.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/file_editor.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/logger.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/satellite.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/gitlab/auth.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/extracts_path.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/api/issues.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/api/projects.rb Mon, 22 Oct 2012 16:08:18 +0300 +lib/api/helpers.rb Mon, 22 Oct 2012 16:08:18 +0300 +lib/api/entities.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/api/session.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/api/users.rb Mon, 22 Oct 2012 16:08:19 +0300 +lib/api/milestones.rb Fri, 21 Sep 2012 15:47:07 +0300 +lib/redcarpet/render/gitlab_html.rb Wed, 22 Aug 2012 14:52:27 +0300 diff --git a/doc/app/doc/README_FOR_APP.html b/doc/app/doc/README_FOR_APP.html new file mode 100644 index 00000000..9456512e --- /dev/null +++ b/doc/app/doc/README_FOR_APP.html @@ -0,0 +1,399 @@ + + + + + + +README_FOR_APP - Rails Application Documentation + + + + + + + + + + + + + + + + +
    + +

    Use this README file to introduce your application and point to useful +places in the API for learning more. Run “rake doc:app” to generate API +documentation for your models, controllers, helpers, and libraries.

    + +
    + + + + + diff --git a/doc/app/images/add.png b/doc/app/images/add.png new file mode 100755 index 0000000000000000000000000000000000000000..6332fefea4be19eeadf211b0b202b272e8564898 GIT binary patch literal 733 zcmV<30wVp1P)9VHk(~TedF+gQSL8D5xnVSSWAVY>J9b+m>@{iq7_KE}go~11+5s4;8hc+i0Xa zI1j@EX5!S+Me6HNqKzU5YQwL;-W5$p%ZMKMeR<%zp69-~?<4?8|C8S?bklXr4v&Ov zb&06v2|-x?qB`90yn>Qi%Sh2^G4n)$ZdyvTPf9}1)_buUT7>`e2G&2VU@~Bb(o+Mz zi4)>IxlSY${Dj4k={-9RzU^W5g9|2V5RZ2ZulL9s2xQbZ@r6eP9Ra5u(s|C0Nj#&4>wTSkb?%#=9?@ z^oxDy-O@tyN{L@by(WWvQ3%CyEu8x{+#Jb4-h&K9Owi)2pgg+heWDyked|3R$$kL@A z#sp1v-r+=G4B8D6DqsDH0@7OztA7aT9qc1Py{()w`m``?Y0&gi2=ROcc-9+nU^I6< zT=e_Y=vSnG@?3Ue{BW5ONFttcE!R-R_W4O01|0-|K-YNXLo2`4Qv z`r1LxR6#yf3FB%T95gJnaKKivA~Z}S9A(ZxEDK}O3T04USJ P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/doc/app/images/brick.png b/doc/app/images/brick.png new file mode 100644 index 0000000000000000000000000000000000000000..7851cf34c946e5667221e3478668503eb1cd733f GIT binary patch literal 452 zcmV;#0XzPQP)Pdwe5?6tW?r-ok|b$oDQj8FV%kZPq;(MWOV8?8;<)(iP}>hNMU> z7fbz%jjlr7h8uuoQ~J6}n}@Y@PdTk=)PxO{%7zmL?dchpZX*~n;I{!C>*(8cU;q(~ zAS%Po_@naEU!xidrBXD?;hN|x^%W|Ij)0y*r5vi|?W&Fub(NqJ@z0o=O&SR3v>A``^efOSo-hEdApp;^Jd;9y!%1UfzX6Bh- z%-mbG|0Na{7Ruai_Y+DEb1s+b!*9k%Q!whMxjtZKA*?o;i1g&jy0@( zaU=-@d-h+o%gal6JRXEXA&L3`d2 z%jIxzZ~*p9O-;EJp_Ds0If38rM<5W8ic~K>FOK&2_p!CLg^i63OioVb6k$)zWHLx3 z5;!|M!}<9+#QSi1dRlbEcxPt^;cysUuU8@%3}RwpLRIGG<|IKnoyP6$Eh3SKw7a*r zSDXP=IYc&YZf;7@?fCe($^l9ORaJ3wbAx0uiC8QqRr$2t-Cfy8%XCI3B%pxJW>XdM zw~zPt_s}#A@pxQ5Ly)4szaMtH9lgE1SXx@b+S(fW`ub$fYPE8J7#bSNDzme*Ub07{ zQKV8SjEs!%0@v5ql8ggm!@$6Rbi^E8vBqpRM-}l+@5OSMrl+TWj*gC^qoV@>u{fQb zov5v?g~?>X@bEC&+uLPaQ&Ypn-y~^mZA}+f(&2EFH8eE%dU|@ENpN*_1-)L6_4Rc* zFuq@`IjX9vp1QiaK9ZojyZhnQURP99d=u;%37VRkpwsD4U0sd3x;hEQB&e^i|3QN0 z=H|Os1fRqaw!?#igLmS4HE!G3*ce(`TF} zlgUq0Q544c8(ae&UR$8ps&snq6^bPY3v3xAmMW74Di$h~GCH6E3TaYs2#6A<7K*gC z777H71_Wa;(dfp+g-drPCSWu)#PInZi72LJ;o?i~$-U=y&UbQ89Dul3%3P+Axkzc* zbH-y;QF=hR{qLItf%ci2_&e5wNo0gnVatG?ul6Zw=o$I9Ljfn*ic3`U?>IfEim3g{ zujU&$-hy6wn;w(xme|zJm;lWJxtTFfM)q0`kX!Vu0+d${$}LCddK1<^htTe-fUYL3 zB`SdNsZD>RgvLj1<^@h6_+cDRK2Brcr2~>%$*5S)hyV33PV^teac3%|4lz@8p4?)5 z?t5o^?q+%^%)Yygo~I^U4VR!bTnWuE35hcWrfCDR3q+sxJ79e7Fg`&)RCqLA^2^y^ z0laVfadW90_Fz8Brm|r47sB^u1VgI>kanj)Z4`zMSfHlm8>CwXa$JVM`$2RrmZB-3 zN10m-!;BvH*Br3V8t`DH7m`jf#2upVDXl{5ff18_pzCPK1Zu$$CKKvd8FGeFf)+K<|x33pc7P&S#3GZT4mEw;nr(Ze*F z3&*?-4U-lm*#tber5 z%S_ceqB`b3ko6r~BbvDwdohTvP(3a(pq{x#T$yQsu#OKwEe}KuH^Mh@nxg_(Nw136 zq#a^3xNBke)In+!?qk3%4wB69{pF`Tzg`07*qoM6N<$ Eg55P&8UO$Q literal 0 HcmV?d00001 diff --git a/doc/app/images/bullet_black.png b/doc/app/images/bullet_black.png new file mode 100644 index 0000000000000000000000000000000000000000..57619706d10d9736b1849a83f2c5694fbe09c53b GIT binary patch literal 211 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-$h^>lFz(Kw&{<9vg>5sw~gS5O!4 zr|{HuUFIBKiQyL}eBJ-L{`UVT|6_O~L{G%N{Wbre{kQtZ_0LvEhC#5QQ<|d}62BjvZR2H60wE-$h^mK6y(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz1H+_;eX)`ni0%X8XBDc-`=Ph(Uan2 zYsR{H!kvIN--9isvHznRsC#5QQ<|d}62BjvZR2H60wE-$h_H=O!(Kw&{<9vg>(S^W+6Zii9 z|Nhthr~iNb*Z!}6uiN$Dz5neG3a-`baBX8yz4q@v|B?28{s)#N@CGn3@%_y|zAV9T z66e<&B4?b6oF&azg|C(V&1ZbI_D}pL`}(^FT2yXwG1Ph~$Q@h8mJYOz!PC{xWt~$( F699+YQR)By literal 0 HcmV?d00001 diff --git a/doc/app/images/date.png b/doc/app/images/date.png new file mode 100644 index 0000000000000000000000000000000000000000..783c83357fdf90a1c7c024358e1d768b5c09c135 GIT binary patch literal 626 zcmV-&0*(ENP)5OC%H;f`~O(q$Q#t2<^v$A>fbmv%e#dKTwK=Ku{5lS|}<-`a#7b zzTCOnnT>at)D}AMFuOZ5&%EqFN(lyumd$2ASF6=;nM~%2?gqc@U=#|4PqkX@EBo-9 z7pD#bO_RUa>*faM`8;MYfVi$JnB-zcBFc6gjl$d!bF98Q!!!(Z1_R~P?e!pt#6CHJ9S&n_n&@=9 z%GP;!@Co4c*at+6vNz7o(6en^Q1%qHrc;1)9IRaz-$@S$Z-qdC^ds3X0NvQH;KS)D z-dh&rW&@X;1cS(45z)J&BVt+tv&GMVJ%!EiW) zLBGZW)#Z+gl-Lih&?>X3SS-S#ujQ;9JRXmIB7X)8`d6ETj)D#Q2+$s|<_b7-B9Xvq zwNfqlEp%y3$uY`h{Y$(Gn5@}sqEsq95lpAkFO5dyBmP6^H-51G4J|rN2Ujt<`2YX_ M07*qoM6N<$fC4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/doc/app/images/find.png b/doc/app/images/find.png new file mode 100644 index 0000000000000000000000000000000000000000..1547479646722bda4647df52cf3e8bc9b77428c6 GIT binary patch literal 659 zcmV;E0&M+>P)IO9T&v~?D!=C@G6X*U1@h2}>2WE%HrrsjTfQsh6N9%SR25A5rkWp0g zzi;-6|3HJE;58sAyX1e@^d7EwiKQLb00%dp|5+t<{|l;G!D3eSuFDma zRCxr2MVY_`ELgLXqo}ssqp5E;*r|opZT~&|!~VN?1^mw`Yxp0VmiIp*r|Ey~#AW|W zTBd;IxVd?%*x1<_!3Ip2yP9Rn!u1aqt=siKx4a3At0%7dKV|u@|9wlg|7x7R;eT!K z{QuFp&Huxb3&AdAW?^~2z`(!^HUQ{cR*=op7H|BYU0VMi3A-|5H&#ol!zs_8lnTUg(&PtE($2Dhdk=&(F^R z|KGZGj(DV`tD_*NsU$2QNCCXqf9n(sfdh~LzJJdCa}5CGoUI+JZJBOCDz({abl~fE zw*5kfzVoR6cNi2r#C!ZEH0O;NW@rIh| zlqsqSSs9s#;sV;-@|>77A1W_O_DV`91Pq4Kz`Z(PaO&pn=GOMkuU$ROkc5GuVd!Y* zcn`UMYkYq7V07o@rsi~>-ziMLT zG+?a49zQWzia{TFcs{FKj#dh}e#z5@`O3omC>ELXboP2cR7WT?J@&ao#fn-I;sJ*F zD;=5p9?%y~V{F{q4^{|Zlt~d?*Ve!iWj&E%8@h^*gN$V29v5mAsN{O(ULD=kFMd^> zzLGLp)CZ#Qm6Q%3+`@kXtfre9GnE->Ai(oKKDoxtH@hRaB&C1e=IHR>I8;havNP_A z5Rq#nPVBdI5VpJ;S&et6>VVp>c?LwQ)tZWlq#H^i>)VP@16GREXU98`irCrvkEecY zkv~S7^T>M0*)Mb{LvE6`M77!t_ZXXI^`uU6W|L`YE-^~uca*s^)=F=9o*rxs>$qx+ zN_$rAd`ahYK2^cpF)HkQ1(Vq|Urh;b~<55D)DL$EUNo=p_A6VQ1A+M~) zfa$>U0O5Rbu4r3$+|O$+gUQaOR@{dPsf3U1Dln%z0(Y0xq^w4=AKW8UMLXPC9RL7* zZ3?i~&mg|kvE%&Q2{D=<{q^E0^^uNwISF-V^g!SN_6Pp zHm8=*qyzo0O&|aW=mQ}BV^c}pv_6$imk>cA#v4GgKI?F@S#sYw42|o9Jp1uLDt+Ls z2-H#~>q=LQWTF;nU7xJYKH2KCI4{O5B$T{{EgN}dE+rE|#F+n@O!gj|u;Xxe?Su03 z2tWqC_4M@)#<@OoQ{pg&@m`>d=YYXNQlKHoj2tjT2nB<`FCZcENCi2SLd5c#Iz{+w= zQMis*31e?RPgP7h#4AOzY&hE#R4n&Ii?x5Yq0)?J7KNcBj@XdX zlWZ;>n^k?`V`54w4oMu!H=JW%u_9}!!vS4^ZMC2#K+@g2!t)G5*y)(xiYlL_px35D zIhY0lK348EIpV!%r-=F;O(7xbv>oQP6>|(>Opp4COU-9M>Q6ub0PdDCFo(En#x&eN zGni{g@pt^Yi&Zk-WUSBg%!GQT&imw!)F&}=v0^+ zPAeQFDhtKVnUuxMHpDJZ^)IYcqn3l$E3tGu>6%O0JW{Qd&uUAT_CJz)Db-2{$Z4Cq zibD~-93PZJRMP~xt4_LEY#WADM=C$k2DOim8}|&T7PflIw)ySUdh%=c{&;)e+r`Hd z>F)2L5sYyl@Pwfv-Z+Q9(~d^Q%E@BrXlV!+zKk$1SUf5lN)jz7MS>v}FnGm>Qbf5( zWmQ8>Y4OMAhWe&Lk?b!b?Oi z7q@cwX@48D4*Plhd-GIrduvP}Ef)tlzfP@U!q&vPH#vyU*UZF+Z1UXs%zV%z6LOs+ zcaVxUJ2&!|`1z(BM}Lk=9HZd_-+C?1s|j(*3pM}K)5P_O^ZvgjpgCOOIH^P=rz zrnafS&0I?@i8t47Fuv>lf^b*BgG?Gr8}Rx=$^MeEIq58C~R;2W5b2+Z6DSOmY&y?jM>PP zmCH(!b;p5a z08~hSk!QD03@!sbLen@urU{Gbn>9K(ikm zl#3h~9C5N=ig9Rs_qtTd=#qk`!ZGs7NvnMZ+uzd@j(?Rvpko)yuH)l~lSKOGS)aBD z7_OmZBdg=SE=0lny&|8m4WGI#J|9BJ}fBGEjmh_+3QFV-yUQn(l{$5#`e$ znfciyaIqFV2bzbhDu?7{<$RLQFC=|ws^?CtX)4I8sO>-(eMb1ar-sUdK)fzgqvMk> zZ^Rh)#8kxW$|S;j1HHPvzPz`!bA(!5h*+9K{Bl4}FHo45&3%yp?rDAP3~x@+ME*8G z&}mIK2Y`4+qxB<9rNt@5hlZ)HG`HKZFPtZ(CdCW@wfOGs!rXe8 z-mBDPnj{HhE4Ayk=DMsy6c5sbcY=`3>S0gZ@AO)^Sd)t$p13pA3PJ#dmLDTD1s}Wz z02ItQF~53Ov+wZ2P`n_U4VAJGo_<)CMpqJ3n-|`KmS8^ z<6NCKAuP(yrPRXiqft#MxAk}%PIb2CItemH*OUB$_E1dAyieI6EigfeNusQvXT~9L zwllbU*O+j+W5Qti)3H?p?*D`9lDN^-b^Q#pv$U8g4>1bxARs=rK5^IfwL5Y4H4Pl{I}`^(PH1gYU{*wqe@3$h1OCneK4J4!&MRe zOI%s;fxPp5H9Bx6x{QqEsK*Hpw`q|yBo$$v_ZDvLxN=kn=g9|eG|t{-cBCa zWSp2ev%7lwBK@tsaE^R7fx&OwUGQ#^arcni@_`qa0+Ih<3e19Mf+3k%g+)@Z0>QL0 z!HU9+@@y$mUhU^$zNMt8xbj1@av;@3!U%#u{N{thykrE-duU`-05?CiI5){L zy%f8$xwgE)K0S*=93sE3FU*{+{yF$b=Jm0O!B_#^eoI(9dVeEu^GYSFGhk6VM2eP; zSzH6(dYAFYJ=IMG-RZ%6^E|!yINDStfqn3^nx(_a*MMt-QOJ6FngYP6Flzi8{}M1u z?#m8_6qlhH0|2mB*E(B$x{iH!qh!(v^CX*om>t8m-!J2T%OyrE@fg!+W!rCupnGfE zR%c(5_C1*?Q|=SfK?@c3?d{0gfIk6Qne%2NAR%5!D1e2lrEA=#=314|^y}mlbdU!h zPIxs%P{lm;bYgjBs1qyXxkN6UD66G>mRl#Xr4z~PvG$je@$TcPPQN{YiFfsV4Ahz{ z;nj44T{SOdcs1301%HU_N_w4#jyn9@;-ar3_x<_h`fhkmBj(Iby8UQuwZ@CP3EK}j zbXm^OyhBqkWQ~AeVy^iVB)4Wh)+=b5--vjbtrvx4823+e>fN%unKd+&T&~@;LSp8#I-|*I=U2LzE0($<|LW%XsA_XQ z3>6@ct56W8`Y2>d{!pjH=F?<22mf_ejVWx&mfsLml615hA!(-FDBnc-jDQv_NKXNy z(=8#eu15MT`JMYUW~~vr%z{`z9S|~|_VAY6Ov4M7#Wa(*O#3EWzRYv@&_zy|0i*@_46?BhYPPEpVGD|(a((4@b>fF)l-3jQvCcv z{o)yqMWo1gDTG1vWp=_AJoP5UPxA^qrdn6*;Qh%^sB8>DcX5d2bXh zu<5X$-n2+RVUy$k%$jmfMxgu4ZWTs$Oy{Q?tryu(5>W>)zs2)w zHL}wWPpTzwL2MM8=lkwHp3#jyMe3%J0Av0)*ixKl2lMvu@{j$n91n^pNe|jd``l0N z0RU<BSv#yWY}G&Kb9IUxK2(l z!4Sz=T3g)J1mqFu!`seMX@O}Bp}gyZ@I7GK*7vWYuax&DJ=8$){{tXS> z7+}lu)M-J126vy;?q&^}iM1!NCf1I@E@@H~O-PIlsM7kknVdsATr@pmBo(C~$G6gS z02;)2O@0&~`#fHDeC1eCZZs;s2N)@A;Z!v}6IRW@+w4GRSlrsuorBjfJ?y*o(0gj> zt+;DN~K1pX*UvM(B(Di$9F6+&eT z#bhNzlMA>q^N?j+@1IqnYvK};_)_77Ts{!elaGqJg{uwb(1mX6u=pkfLJYkfX+`v! zOm>eolNV>Nz$A&W8YqkN#cU|#i6j>Ox+Eu4*8Myq{Eq?u*kn+nT zQ@k8?r`Isov^UI2=T{#K~skC)fRP-aj zcrJyQmQ!u>p5&{_zp7xOM(Q%smb6M%g6o4s^>A8#L41?8Ox^e7CM$W~*3!e8F7P`S zK9!26tqJVBt`?fLxM^Gf`xAacdcbz&)u<6pKM?qA_ms76BOQWg0Le^W#?SMIT$jE7 zyw1!lG*$#k#iqZyl9~L_CjIwBb}$%9+e2Vw!1@$nfpvj1y2o4hJabo7^;(V}>++Tz z{|NtdydBeFpKnv*Vg9BTu3P)+)3J?9`*6t|c{b*k>-L!PvY`#5^i1^XCnxh zky})0T&rp6 zJFwUVv-;Dzt2_z1)}rtpHBQH#<-`N0%%UP1TF^VNx2@~Zh_4nbMMxj7zeHTrB&q)a Dl)1NK literal 0 HcmV?d00001 diff --git a/doc/app/images/macFFBgHack.png b/doc/app/images/macFFBgHack.png new file mode 100644 index 0000000000000000000000000000000000000000..c6473b324ee1dae1faaacc0826639833f551116c GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIEX7WqAsj$Z!;#Vf4nJ za0`Jjl>Qs8<JF;+Fd5q0wCR k?u=~bH}2*0f`J3~k>FVdQ&MBb@0BAfpf&c&j literal 0 HcmV?d00001 diff --git a/doc/app/images/package.png b/doc/app/images/package.png new file mode 100644 index 0000000000000000000000000000000000000000..da3c2a2d74bab159ba0f65d7db601768258afcb2 GIT binary patch literal 853 zcmV-b1FHOqP)5TQ^(M5v$(QKVE?W+9X! z*o}&~6c?_FreF)9NJB7b5Nbn{G0n4+%uJhR9(V5R|NFTpb|HgjefT!tIhLx@DR+N) zV+fHiR5Yt19}k|KnCsND{tH-`IMJ)3AE?OtyZ4>Un|6(d%h#JK`i&a7^xW9>`yBy` zS4SOHeOpC7$?hH5-#7Rswiue_8Ju*2N@$58=a#2OTA3png`w3v->gWif7t%e$ z$NLVS!tFT#8WL|Wa&K~+{%4P2cRfwesYV1_!F=3OaRVHl(>=`%&{x*s30c}#CNE@&;ItrAv!f!)Oy$Q9t$uS=(sD$-J{T*^(8Eez1E-l3}} zPrfHZ1`qsIFe&gipuL8-IZbo2Yg{lFGKs?ZZWcOaOdk*3`5T;$?AjbG1#`B510Er^h2)2r3Y{!8_2Gj=$KzuN5 zaErtW8W_Y2iJJjY)5pmTVJoPJYpanPOEuYHclM^C1F>${hFRpdi8a<2H|Xudf78bm(zwJ9`K%6I?q*Ua~ fW9JvIbn5*B+_J)rUMBs>00000NkvXXu0mjfH&TkY literal 0 HcmV?d00001 diff --git a/doc/app/images/page_green.png b/doc/app/images/page_green.png new file mode 100644 index 0000000000000000000000000000000000000000..de8e003f9fb8752c09e7f3655d5d8664b5c62fc3 GIT binary patch literal 621 zcmV-z0+RiSP)QqUjAtB;_Vvt6}AS_5YgM`Uqu`yva+H8^=4U$e4gHb}u zAQ2N{V3A%pO|?Pv?tb6z=jC}SiRa$G^v3q?*6XcYz$p|cq{uLj@#~Fi`J(>5{@&&N zy%T^+;>8cXx%|o77anP?&W1?1A(>-T49z9pyeCl@7YI+Si zKti7=B~``}TImz(G{0PnlQA3P#MAd}sorMjkP!50B7$nAkU^%#nl{Q9lW0@}9fE-> zN(q7tRuiC_T1r|BBtVBTlQ2+70$Rf;eF`Z;lx46Cpu-rEgb)EBKq(b^W8l<^We(`D z43?0=01z<3G6+UUv6`CsWCk6^93!#+<;ws7007{zS3k2k9-zZKFO~(k`>s0y006+1 zgF_jyIhsL-`FMf~JL~C=cV75(CrJ|q;MVO961G=O zm9d)YpJg5g(4i_HKL75eSE}mq$Y}r}hyVdcV~p>6a}oXr80q`oj%+s700000NkvXX Hu0mjfPs|!l literal 0 HcmV?d00001 diff --git a/doc/app/images/page_white_text.png b/doc/app/images/page_white_text.png new file mode 100644 index 0000000000000000000000000000000000000000..813f712f726c935f9adf8d2f2dd0d7683791ef11 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!60wlNoGJgf6SkfJR9T^zbpD<_bdI{u9mbgZg z1m~xflqVLYGB~E>C#5QQ<|d}62BjvZR2H60wE-%6;pyTSA|c6o&@eC9QG)Hj&ExYL zO&oVL^)+cM^qd@ApywS>pwx0H@RDN}hq;7mU-SKczYQ-hnrr=;iDAQMZQ+*g=YOM= z!QlMQEn7FbaD->uKAYgo_j9)W&$$zS*W9}m(ey0q$&7l-XEWO0Y(9M=SnhLbwy;d>@~SY$Ku*0xPvIOQeV1x7u_z-2-X>_74(yfh7C znXL|3GZ+d2`3re2hs?MKC#5QQ<|d}62BjvZR2H60wE-$R?&;zfqH(@;q9b3Efq-lM(nr^( z=EYR73-9e)UYMWsXy%?aZsD68Yyv^2$~6QgEcljw%kx>O(f-gQ?@fOOx3A-0+Qw?O zRx~W)kn~Qe2d6f9nMG#g9Q04Mk==M~N!Dglvxk!fgVh#w@ZV$IY1+Xc`d{d2UcaP~ zfWp)_Ivqj}l2SPy^9ZWy6rG9Yx4v67_uA&&9|XA~5-#3)W3%em1peD8RWH^#O%XoM zxMPud%}GTj#~*+7JMxTd!`{^Q+>(D3*|@KV`*G2;{QnANOxu1$r2xIe;OXk;vd$@? F2>@zac~<}c literal 0 HcmV?d00001 diff --git a/doc/app/images/plugin.png b/doc/app/images/plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..6187b15aec001b7080b51a5f944f07591f26cc15 GIT binary patch literal 591 zcmV-V0eEcNHZMNv|IbJ-M`( zKwWL~opzjJe^WpCmV9E;(0&ut2;4va_(#>M8)>9$R5viQnf(Nkh~VM$y>J(jqb$cj z+nL1Nm|mV)Gm|9MnHf*7Ja4OEAQz__^LRKOLEwqpiGV^^A*T=#&inGm-62Xs;dnSp zKj&H9T*boh2i)W+(n27l!C)>fq|L%VB1i ziC4p;NwV_}ZjW7$LRW#(_bKF#hp=!IqNO26Z*w2+LEwx{PVnZ&Sn}T;mtzb$;qA*nT@@+ zV5uQ@iXDTPoTbV#FRr~z04|PPh`wXTNoCm9*tG&?e3+fYl>K6+&3|Cc$KOpL`ER+_ dcRl5U#9zn6ZO}GFk7R5;7c zlif>`Q5?tj7Yw@ZCMtTF^Q|ZedeJhM%QPCR*bs8V79p$QTo7e94yQNXRs-{0?hOn_-8n0AMO@u1Ts zNl8QzJs1#rz%RBt?ux>l+amAvh+J!{$lkaqv}+Erb-6j2xp>K4GLQnNB*W`hFg*?P z^AL@~(h~Z+wfcWEXHqV^Tq-#z$7Y#o0;yFxA!00F}F2dX# zjE$iOgT#G4*1TR6kB1Gnn@>$meCh2a>c5YuIvFn-R2W@>4@M*m@-|jiDV?b)bccgA zyPfsMM!rjy>+1O2)5Eg29Z_*2p&qGnmS!OH?vZ(4>QB01d>j%9n4QINxkyT(Dos?I zjaWF$*IQmh`SF-?xU%xMEfjq1=6qY*g&lgG_cXv$BGoIWyfO5 zp>pdV*O+y=&6@N2WWFo(%RtT`Q(H^6zn^a%epE~Kx^mEJ{c8`luC$nc*z9j|4Ms8aJK-ladKLpnAK z!yd|CC&>l1b7`m$MH$ScEIP@XgT41O>|DzL{-38CH68OyX#u=G?d7;y&_o&o)f@3U z2(tr%Ok88caOL`xiQA8o;Vzr-$A$SOu6o|$&0DQAJ1Z7?OACaeoy+)PWu&~aueW<| z*KW^(^2}#30u*~<_mXScFNd6U&sxh5*GGMNytZGxkIGqL%v6329^u`FD6T?b?K!4B z@Hzh?O2Au=((Gu;rvgLMt^pS|u1rEkBgC8$oH%zgT`TvZiK#VDrVG?-i~6a_+WZb> zc1>>lb)xcuo^Cl8k%q3c_d*It_Vtj>RSovF&w;hS=6uYrT2e@-@l@P~uBN`zu!v>e zTm(is&jcQ6vuP?|;!e+(n8w)-Xjd!hwk@r2D0i00ygdKo2Xvs?&w_lajj5DHS@9I! z;_&ji2e{!uusGnVn};Pu|dl5x-FhQyC8^-4Uo_;BLiOXzcE z&4PS2TBWSC=hsw0og;z#(mly@Ed2E1E$_VDaM?kloE4ob2XK&K;OS~-nhIGlA4~UZrJu6*|}wi#TT?|yWUH+_&n($t0xta zBwTzSfE)uAw*L0>+`pTps}L-$jIP5Q_E$Am+l|{XfsKr0Vi~`Em?SJQ#0y)8vsxb1 zMdxJl^){_CDwI^}>)Pw${G?Ajc@P}x{Fvhoi0jbY^427?KPmoA_G)sqK}u$2(79Xg zC%}xm5JDcrsm5^vQEQpGEdJDc^yfuNAlqV1pZQVkOSceV<|{=|=@?=o4i_1RFUZth zC7cu<6%V3dVCI}P6DL4iUgTc@&(nXY)ox}HZ z(a#EgiNj%{kjRLL2t?{m_aKN`{5-&u+HAtQ-Qq#@!I@<(M+B3i@|g=LY6 z90tpW!JuMn_Lcy1q7g&LUSuLE3XS}K#P^nHVUmL`L)dbP| z0bt(+Cp#M-bH!LM*DzJ0Lfn;eTBV@|JvGSgpdoc1RhhV>(G-2(vE|>MrVgA9+?+0m4OzUqbT>-U-jg|v zLZMntq`r?fy1UCMh>z2Koi1SL-~N2ZrIf+dZW|;SWszsde}Dl!HOMc1Fa>K9)e&RI z)A?aK zcviCdKDUg_%#u7YAE`A`Y3$(P4&m^@fEWAvjAwVmRWeUnmkrxA;E!fKoc{9Vi=lvFL}KmoS;g* zdjL?Y!VHUFq63aLj6VZE+tHts?Z1pFkiO9^k*5pGpFpU&5#5G4ATd{t>a&9zKBVB9=Ns^HFU|DTGH8C+Xr2UqOU`Zxe)!|%j4=-QojGePq)pRGe;!f)Czk!u3vP_Jxu8(e6 zf4Q`F$Qio2Jw@N*E@k?c`+Sw}AYQjkT+x)OAe6eq(AT!iRuksKQn%Ao_Ac1T-p#Js I_CnHs0qX}mlmGw# literal 0 HcmV?d00001 diff --git a/doc/app/images/tag_green.png b/doc/app/images/tag_green.png new file mode 100644 index 0000000000000000000000000000000000000000..83ec984bd73364134da0f98d27a800c5d3264180 GIT binary patch literal 613 zcmV-r0-F7aP)^5T)AZ%#@G{_P{NCN^P z(J0zvSn~SSm(Ur);-M~8^*;61*VRI`T1BN&LAhK;sZ>I-SVW;vfUfJv=ko^ugnc0x zhJodBxe>iyk3%w<%wC8holUJ4(iv>tL{`DQt zPOsyUbO_Cmc&*iHkqbm3ku`|GcC^OhF>jj9W*GkH;^g!iUVpib_h*=@udp4h(P+e*zL_~ZmJjh(y^BxULwq>9zXoYE8sq{#pN~U0C6!8vY)5N2 z9P*}mw}7X$O^qTtJef1ACWvJT9^wt-)Zh0r~j#0bT`f;-zv6 z^Tmw22!%rMcs!TaUX<-8s;X-B`+Xbo+_uWuFa z1yIPc?DTrQ7KvRhmt*TG|L=EYQ=LqFX;=Lp`4}jx6BE-@00000NkvXXu0mjf=s_29 literal 0 HcmV?d00001 diff --git a/doc/app/images/transparent.png b/doc/app/images/transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..d665e179efd797451084235f105425247fea0a14 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!D3?x-;bCrM;bAV5X>;M1%mmiTn0pv241o;Is pI6S+N2ITN~x;Tb#$R;N!@B(=T42&&nK2`x)44$rjF6*2UngG277DE64 literal 0 HcmV?d00001 diff --git a/doc/app/images/wrench.png b/doc/app/images/wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..5c8213fef5ab969f03189d4367e32e597e38bd7f GIT binary patch literal 610 zcmV-o0-gPdP)^jb z4`0v}DG1te)wmeb(>p90leRz?_mO+^JKy=v&2<29Od6?F%9%(c8los#f*@G`-%W&* z$)uBj2i@u-@SgX}gtyWPe6d*|w6h%R? zScK2#Yn%$sum0cy>90DmY*i{1XqpClEtktsRTZ)lCUe z<FogV^*tm>8*AlX za4oiR!&85LrobG57qUHUX#{>Vz(RHpB5|@>9O6N$jqB8>%($0wxE5R3)b>Y~xtCo$ zCgEk&A?_#IxHdN)9tqre^o{ho4{?hmPuf@^@I3-wncaRd%|~O3xbrKY=&TiwPYkJroM{;WUQTuMY8vpg}f4o)2%U3C;eEDoiEh?94d(rV57VIF#8VqzW$HrDC|#U`x@QDbgi zVl)t9GGz&YY#D?gc%>hISA+_EBpnXt#pnC`p6@xw0$8TCbULjhlgVx(kuc)%xbgqq zR5+DNDFRN0!y)7Gm}oT0i39}h4h928qY?Rho^UvPGJ#kuW|-Amtrn`Pmd&+bFo@sp z$LI4IQw7BG?|#2ewOS<<3VjL$0=lMY^m;wqZujv5kx1l%Sl;V&Iy4#$ip3&@LV2!7vhhN=PCz%^9v24`qb(+m4W?!q-&~=?ssf5GfnAmJKV;3bvpDm0(NhahZ=&^sqo6Odj6>)Dq_3p~4~ zvb`d3Mydwjt&Df^hVmLtI2x=U&h9(JVYX-!y~z3zi;1>=LY;o(bL$(Yf$lf)dMf0-u^0HrpTG Wk@)HE*94aU0000m+BBgry{~j2fHLegbHP( zrgXNbr0}2;^nywdjLjZe?uxtrd3D(pZH@fFFc0{BW_~jxoO1w7-VX;6vK@ROA$$R6 zEmo;Ht-Mj|>5jUy{bQ^V5@53LRI8AgLpUm|m+15sqcz@QtVSo|oz7ArM8?pIn+>gN z0b=4_b5O|4A*;Q+vc9Vqr~%3V155*NV~@gTz}KSUiKB-uJzjMZ>5%Q#n24H!V{ zTY(LLAE*NAHZ}C#wnj%Bw5OFIkRhkkAW#kDC3j9Wm0YXRaXlyyp>#mVfYG)eC;@ab zDb=T-BCAY4LI(Z@GOTr2V_A{pRwSmz+8Be>CjAw(=gnbVWAeguvZa93JmL(EDxv1m z0OP4q=fpAK1Mq!C2`OkEn37o;m#wF#(t(8Pu#S?2f#x<~4EO{@fmm`p9veD6RZ_jp z@Au4};q&`XuKEYgIiB4((kgxOs#YdqJw0fY>9^K_agEu5+$#k;w#%I2N>n_?)YIqu z`tq&#_^p?-%K*U0^}|7+9U(&k0?s;=r=uCZ%)H9_edH8wK}gB(nUB1FFk+2Ol%BXV zHoFY`D~2x|2 + + + + + +Rails Application Documentation + + + + + + + + + + + + + + + + +

    This is the API documentation for Rails Application Documentation. + + +

    + diff --git a/doc/app/js/darkfish.js b/doc/app/js/darkfish.js new file mode 100644 index 00000000..4be722fa --- /dev/null +++ b/doc/app/js/darkfish.js @@ -0,0 +1,153 @@ +/** + * + * Darkfish Page Functions + * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* Provide console simulation for firebug-less environments */ +if (!("console" in window) || !("firebug" in console)) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +}; + + +/** + * Unwrap the first element that matches the given @expr@ from the targets and return them. + */ +$.fn.unwrap = function( expr ) { + return this.each( function() { + $(this).parents( expr ).eq( 0 ).after( this ).remove(); + }); +}; + + +function showSource( e ) { + var target = e.target; + var codeSections = $(target). + parents('.method-detail'). + find('.method-source-code'); + + $(target). + parents('.method-detail'). + find('.method-source-code'). + slideToggle(); +}; + +function hookSourceViews() { + $('.method-heading').click( showSource ); +}; + +function toggleDebuggingSection() { + $('.debugging-section').slideToggle(); +}; + +function hookDebuggingToggle() { + $('#debugging-toggle img').click( toggleDebuggingSection ); +}; + +function hookTableOfContentsToggle() { + $('.indexpage li .toc-toggle').each( function() { + $(this).click( function() { + $(this).toggleClass('open'); + }); + + var section = $(this).next(); + + $(this).click( function() { + section.slideToggle(); + }); + }); +} + +function hookSearch() { + var input = $('#search-field').eq(0); + var result = $('#search-results').eq(0); + $(result).show(); + + var search_section = $('#search-section').get(0); + $(search_section).show(); + + var search = new Search(search_data, input, result); + + search.renderItem = function(result) { + var li = document.createElement('li'); + var html = ''; + + // TODO add relative path to + + + + + + + + + + +

    Table of Contents - Rails Application Documentation

    + +

    Pages

    + + +

    Classes/Modules

    + + +

    Methods

    + + + + + From 6d0dcb6614fc0743d50ffe68bf61c2c50728c1d6 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 25 Oct 2012 12:16:14 +0300 Subject: [PATCH 032/122] Reduce max commit diff size. Added Commit::DIFF_SAFE_SIZE --- app/assets/stylesheets/gitlab_bootstrap/common.scss | 1 + app/contexts/commit_load_context.rb | 2 +- app/models/commit.rb | 5 +++++ app/views/commits/_diffs.html.haml | 8 ++++---- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss index 85bb5b22..eb3bd06f 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss @@ -26,6 +26,7 @@ .underlined { border-bottom: 1px solid #CCC; } .no-borders { border:none; } .vlink { color: $link_color !important; } +.underlined_link { text-decoration: underline; } .borders { border: 1px solid #ccc; @include shade; } .hint { font-style: italic; color: #999; } diff --git a/app/contexts/commit_load_context.rb b/app/contexts/commit_load_context.rb index b3548ed8..e43e5a07 100644 --- a/app/contexts/commit_load_context.rb +++ b/app/contexts/commit_load_context.rb @@ -21,7 +21,7 @@ class CommitLoadContext < BaseContext result[:notes_count] = line_notes.count + project.commit_notes(commit).count begin - result[:suppress_diff] = true if commit.diffs.size > 200 && !params[:force_show_diff] + result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff] rescue Grit::Git::GitTimeout result[:suppress_diff] = true result[:status] = :huge_commit diff --git a/app/models/commit.rb b/app/models/commit.rb index a070e830..e6a87dd9 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -4,6 +4,11 @@ class Commit include StaticModel extend ActiveModel::Naming + # Safe amount of files with diffs in one commit to render + # Used to prevent 500 error on huge commits by suppressing diff + # + DIFF_SAFE_SIZE = 100 + attr_accessor :commit, :head, :refs delegate :message, :authored_date, :committed_date, :parents, :sha, diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml index 026fe27e..70fff53c 100644 --- a/app/views/commits/_diffs.html.haml +++ b/app/views/commits/_diffs.html.haml @@ -1,11 +1,11 @@ - if @suppress_diff .alert-message.block-message %p - %strong Warning! Large commit with more then 200 files changed. + %strong Warning! Large commit with more then #{Commit::DIFF_SAFE_SIZE} files changed. %p To prevent performance issue we rejected diff information. %p But if you still want to see diff - = link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "dark" + = link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "underlined_link" %p.cgray Showing #{pluralize(diffs.count, "changed file")} @@ -35,10 +35,10 @@ - if file.text? = render "commits/text_file", diff: diff, index: i - elsif file.image? - - if diff.renamed_file || diff.new_file || diff.deleted_file + - if diff.renamed_file || diff.new_file || diff.deleted_file .diff_file_content_image %img{class: image_diff_class(diff), src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} - - else + - else - old_file = (@commit.prev_commit.tree / diff.old_path) .diff_file_content_image.img_compared %img{class: "diff_image_removed", src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"} From 11452c903fc7550921c1965e918524e4ab1b811d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 25 Oct 2012 12:30:09 +0300 Subject: [PATCH 033/122] Fix 500 error on tree view woth submodule --- app/views/tree/_submodule_item.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/tree/_submodule_item.html.haml b/app/views/tree/_submodule_item.html.haml index 43fa7f24..b0562fe1 100644 --- a/app/views/tree/_submodule_item.html.haml +++ b/app/views/tree/_submodule_item.html.haml @@ -1,4 +1,4 @@ -- url = submodule_item.url(@ref) rescue nil +- url = submodule_item.url(@ref) rescue '' - name = submodule_item.basename - return unless url %tr{ class: "tree-item", url: url } From e6cdfb607a3ac87d110d5d200b5900f531d1669e Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Thu, 25 Oct 2012 13:13:01 +0300 Subject: [PATCH 034/122] API: tests for merge_requests --- doc/api/merge_requests.md | 10 ++-- lib/api/merge_requests.rb | 10 ++-- spec/requests/api/merge_requests_spec.rb | 62 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 spec/requests/api/merge_requests_spec.rb diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 2f7c93eb..e5b067a6 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -3,7 +3,7 @@ Get all MR for this project. ``` -GET /:id/merge_requests +GET /projects/:id/merge_requests ``` Parameters: @@ -43,7 +43,7 @@ Parameters: Show information about MR. ``` -GET /:id/merge_request/:merge_request_id +GET /projects/:id/merge_request/:merge_request_id ``` Parameters: @@ -83,7 +83,7 @@ Parameters: Create MR. ``` -POST /:id/merge_requests +POST /projects/:id/merge_requests ``` Parameters: @@ -125,7 +125,7 @@ Parameters: Update MR. You can change branches, title, or even close the MR. ``` -PUT /:id/merge_request/:merge_request_id +PUT /projects/:id/merge_request/:merge_request_id ``` Parameters: @@ -169,7 +169,7 @@ Parameters: Post comment to MR ``` -POST /:id/merge_request/:merge_request_id/comments +POST /projects/:id/merge_request/:merge_request_id/comments ``` Parameters: diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index c9377ad2..b2f4fe0c 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -11,7 +11,7 @@ module Gitlab # id (required) - The ID or code name of a project # # Example: - # GET /:id/merge_requests + # GET /projects/:id/merge_requests # get ":id/merge_requests" do authorize! :read_merge_request, user_project @@ -26,7 +26,7 @@ module Gitlab # merge_request_id (required) - The ID of MR # # Example: - # GET /:id/merge_request/:merge_request_id + # GET /projects/:id/merge_request/:merge_request_id # get ":id/merge_request/:merge_request_id" do merge_request = user_project.merge_requests.find(params[:merge_request_id]) @@ -47,7 +47,7 @@ module Gitlab # title (required) - Title of MR # # Example: - # POST /:id/merge_requests + # POST /projects/:id/merge_requests # post ":id/merge_requests" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title] @@ -75,7 +75,7 @@ module Gitlab # title - Title of MR # closed - Status of MR. true - closed # Example: - # PUT /:id/merge_request/:merge_request_id + # PUT /projects/:id/merge_request/:merge_request_id # put ":id/merge_request/:merge_request_id" do attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :closed] @@ -99,7 +99,7 @@ module Gitlab # merge_request_id (required) - ID of MR # note (required) - Text of comment # Examples: - # POST /:id/merge_request/:merge_request_id/comments + # POST /projects/:id/merge_request/:merge_request_id/comments # post ":id/merge_request/:merge_request_id/comments" do merge_request = user_project.merge_requests.find(params[:merge_request_id]) diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb new file mode 100644 index 00000000..a1f020f4 --- /dev/null +++ b/spec/requests/api/merge_requests_spec.rb @@ -0,0 +1,62 @@ +require "spec_helper" + +describe Gitlab::API do + include ApiHelpers + + let(:user) { Factory :user } + let!(:project) { Factory :project, owner: user } + let!(:merge_request) { Factory :merge_request, author: user, assignee: user, project: project, title: "Test" } + before { project.add_access(user, :read) } + + describe "GET /projects/:id/merge_requests" do + context "when unauthenticated" do + it "should return authentication error" do + get api("/projects/#{project.id}/merge_requests") + response.status.should == 401 + end + end + + context "when authenticated" do + it "should return an array of merge_requests" do + get api("/projects/#{project.id}/merge_requests", user) + response.status.should == 200 + json_response.should be_an Array + json_response.first['title'].should == merge_request.title + end + end + end + + describe "GET /projects/:id/merge_request/:merge_request_id" do + it "should return merge_request" do + get api("/projects/#{project.id}/merge_request/#{merge_request.id}", user) + response.status.should == 200 + json_response['title'].should == merge_request.title + end + end + + describe "POST /projects/:id/merge_requests" do + it "should return merge_request" do + post api("/projects/#{project.id}/merge_requests", user), + title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user + response.status.should == 201 + json_response['title'].should == 'Test merge_request' + end + end + + describe "PUT /projects/:id/merge_request/:merge_request_id" do + it "should return merge_request" do + put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), title: "New title" + response.status.should == 200 + json_response['title'].should == 'New title' + end + end + + describe "POST /projects/:id/merge_request/:merge_request_id/comments" do + it "should return comment" do + post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user), note: "My comment" + response.status.should == 201 + json_response['note'].should == 'My comment' + end + end + +end From 56bf829c753662a880805b278cae87d9cd1aa3ac Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Thu, 25 Oct 2012 13:19:18 +0300 Subject: [PATCH 035/122] API: fix after review --- spec/requests/api/merge_requests_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index a1f020f4..e1c7949f 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -11,14 +11,14 @@ describe Gitlab::API do describe "GET /projects/:id/merge_requests" do context "when unauthenticated" do it "should return authentication error" do - get api("/projects/#{project.id}/merge_requests") + get api("/projects/#{project.code}/merge_requests") response.status.should == 401 end end context "when authenticated" do it "should return an array of merge_requests" do - get api("/projects/#{project.id}/merge_requests", user) + get api("/projects/#{project.code}/merge_requests", user) response.status.should == 200 json_response.should be_an Array json_response.first['title'].should == merge_request.title @@ -28,7 +28,7 @@ describe Gitlab::API do describe "GET /projects/:id/merge_request/:merge_request_id" do it "should return merge_request" do - get api("/projects/#{project.id}/merge_request/#{merge_request.id}", user) + get api("/projects/#{project.code}/merge_request/#{merge_request.id}", user) response.status.should == 200 json_response['title'].should == merge_request.title end @@ -36,7 +36,7 @@ describe Gitlab::API do describe "POST /projects/:id/merge_requests" do it "should return merge_request" do - post api("/projects/#{project.id}/merge_requests", user), + post api("/projects/#{project.code}/merge_requests", user), title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user response.status.should == 201 json_response['title'].should == 'Test merge_request' @@ -45,7 +45,7 @@ describe Gitlab::API do describe "PUT /projects/:id/merge_request/:merge_request_id" do it "should return merge_request" do - put api("/projects/#{project.id}/merge_request/#{merge_request.id}", user), title: "New title" + put api("/projects/#{project.code}/merge_request/#{merge_request.id}", user), title: "New title" response.status.should == 200 json_response['title'].should == 'New title' end @@ -53,7 +53,7 @@ describe Gitlab::API do describe "POST /projects/:id/merge_request/:merge_request_id/comments" do it "should return comment" do - post api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user), note: "My comment" + post api("/projects/#{project.code}/merge_request/#{merge_request.id}/comments", user), note: "My comment" response.status.should == 201 json_response['note'].should == 'My comment' end From 4281de3640dabe6b913b6b0dc3273d52b6906021 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Thu, 25 Oct 2012 13:38:55 +0300 Subject: [PATCH 036/122] API: review 2 --- lib/api/entities.rb | 3 +-- lib/api/merge_requests.rb | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/api/entities.rb b/lib/api/entities.rb index 5804e943..9e605a60 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -65,8 +65,7 @@ module Gitlab end class MergeRequest < Grape::Entity - expose :id, :target_branch, :source_branch, :project_id, - :title, :closed, :merged + expose :id, :target_branch, :source_branch, :project_id, :title, :closed, :merged expose :author, :assignee, using: Entities::UserBasic end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index b2f4fe0c..d8f2c512 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -50,12 +50,12 @@ module Gitlab # POST /projects/:id/merge_requests # post ":id/merge_requests" do + authorize! :write_merge_request, user_project + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title] merge_request = user_project.merge_requests.new(attrs) merge_request.author = current_user - authorize! :write_merge_request, user_project - if merge_request.save merge_request.reload_code present merge_request, with: Entities::MergeRequest @@ -105,6 +105,7 @@ module Gitlab merge_request = user_project.merge_requests.find(params[:merge_request_id]) note = merge_request.notes.new(note: params[:note], project_id: user_project.id) note.author = current_user + if note.save present note, with: Entities::Note else From b5ced56ba4293d426f7f2e2a9872222f8146ef4c Mon Sep 17 00:00:00 2001 From: hardchor Date: Thu, 25 Oct 2012 22:11:06 +0200 Subject: [PATCH 037/122] Some grammatical improvements Nothing too dramatic, just some improvements. --- app/views/help/system_hooks.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/help/system_hooks.html.haml b/app/views/help/system_hooks.html.haml index 736c818b..c25b60de 100644 --- a/app/views/help/system_hooks.html.haml +++ b/app/views/help/system_hooks.html.haml @@ -5,9 +5,10 @@ %hr %p.slead - Your GitLab instance can perform HTTP POST request on next event: create_project, delete_project, create_user, delete_user, change_team_member. + Your GitLab instance can perform HTTP POST requests on the following events: create_project, delete_project, create_user, delete_user, change_team_member. %br - System Hooks can be used for logging or change information in LDAP server. + %br + System Hooks can be used, e.g. for logging or changing information in a LDAP server. %br %h5 Hooks request example: = render "admin/hooks/data_ex" From ff396e0a7eb504e62c79277d2697cbc8c7c9e660 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Thu, 11 Oct 2012 23:41:49 +0200 Subject: [PATCH 038/122] Extract search field into a partial --- app/views/layouts/_head_panel.html.haml | 12 +----------- app/views/layouts/_search.html.haml | 11 +++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) create mode 100644 app/views/layouts/_search.html.haml diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index 7f89bdf0..4eed58e2 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -8,9 +8,7 @@ GITLAB %span.separator %h1.project_name= title - .search - = form_tag search_path, method: :get do |f| - = text_field_tag "search", nil, placeholder: "Search", class: "search-input" + = render "layouts/search" .fbtn - if current_user.is_admin? = link_to admin_root_path, class: "btn small", title: "Admin area" do @@ -29,11 +27,3 @@ = link_to 'Logout', destroy_user_session_path, class: "logout", method: :delete = render "layouts/init_auto_complete" - -:javascript - $(function(){ - $("#search").autocomplete({ - source: #{raw search_autocomplete_source}, - select: function(event, ui) { location.href = ui.item.url } - }); - }); diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml new file mode 100644 index 00000000..80ecc530 --- /dev/null +++ b/app/views/layouts/_search.html.haml @@ -0,0 +1,11 @@ +.search + = form_tag search_path, method: :get do |f| + = text_field_tag "search", nil, placeholder: "Search", class: "search-input" + +:javascript + $(function(){ + $("#search").autocomplete({ + source: #{raw search_autocomplete_source}, + select: function(event, ui) { location.href = ui.item.url } + }); + }); From 0447ab375a988a328823d20cae0ddbbba652d74a Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Mon, 22 Oct 2012 19:30:42 +0200 Subject: [PATCH 039/122] Extract shared/clone_panel partial --- app/views/blame/_head.html.haml | 5 +---- app/views/projects/_clone_panel.html.haml | 6 +----- app/views/shared/_clone_panel.html.haml | 4 ++++ app/views/tree/_head.html.haml | 5 +---- 4 files changed, 7 insertions(+), 13 deletions(-) create mode 100644 app/views/shared/_clone_panel.html.haml diff --git a/app/views/blame/_head.html.haml b/app/views/blame/_head.html.haml index 175719b1..85da1805 100644 --- a/app/views/blame/_head.html.haml +++ b/app/views/blame/_head.html.haml @@ -4,7 +4,4 @@ = nav_link(controller: :refs) do = link_to 'Source', project_tree_path(@project, @ref) %li.right - .input-prepend.project_clone_holder - %button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH - %button{class: "btn small", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase - = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5" + = render "shared/clone_panel" diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml index 4411ff17..aa1a9cdc 100644 --- a/app/views/projects/_clone_panel.html.haml +++ b/app/views/projects/_clone_panel.html.haml @@ -1,11 +1,7 @@ .project_clone_panel .row .span7 - .form-horizontal - .input-prepend.project_clone_holder - %button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH - %button{class: "btn small", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase - = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5" + .form-horizontal= render "shared/clone_panel" .span4.right .right - unless @project.empty_repo? diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml new file mode 100644 index 00000000..947dc478 --- /dev/null +++ b/app/views/shared/_clone_panel.html.haml @@ -0,0 +1,4 @@ +.input-prepend.project_clone_holder + %button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH + %button{class: "btn small", :"data-clone" => @project.http_url_to_repo}= Gitlab.config.web_protocol.upcase + = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5" diff --git a/app/views/tree/_head.html.haml b/app/views/tree/_head.html.haml index f1b3f63f..f8e5c99f 100644 --- a/app/views/tree/_head.html.haml +++ b/app/views/tree/_head.html.haml @@ -4,7 +4,4 @@ = nav_link(controller: :tree) do = link_to 'Source', project_tree_path(@project, @ref) %li.right - .input-prepend.project_clone_holder - %button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH - %button{class: "btn small", :"data-clone" => @project.http_url_to_repo} HTTP - = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5" + = render "shared/clone_panel" \ No newline at end of file From 643ed9cbf3b0dd09e0ae22df55662d5b33b1d6c7 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Thu, 25 Oct 2012 23:49:49 +0200 Subject: [PATCH 040/122] Fix typos in Gitlab::Merge --- lib/gitlab/merge.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/merge.rb b/lib/gitlab/merge.rb index bf7aaa51..28c20689 100644 --- a/lib/gitlab/merge.rb +++ b/lib/gitlab/merge.rb @@ -19,7 +19,7 @@ module Gitlab # It also removes the source branch if requested in the merge request. # # Returns false if the merge produced conflicts - # Returns false if pushing from the satallite to Gitolite failed or was rejected + # Returns false if pushing from the satellite to Gitolite failed or was rejected # Returns true otherwise def merge! in_locked_and_timed_satellite do |merge_repo| @@ -46,7 +46,7 @@ module Gitlab # * Sets a 30s timeout for Git # * Locks the satellite repo - # * Yields the prepared satallite repo + # * Yields the prepared satellite repo def in_locked_and_timed_satellite Grit::Git.with_timeout(30.seconds) do lock_file = Rails.root.join("tmp", "#{project.path}.lock") @@ -78,7 +78,7 @@ module Gitlab # Returns false if the merge produced conflicts # Returns true otherwise def merge_in_satellite!(repo) - prepare_satelite!(repo) + prepare_satellite!(repo) # create target branch in satellite at the corresponding commit from Gitolite repo.git.checkout({b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") @@ -93,7 +93,7 @@ module Gitlab # * Clears the satellite # * Updates the satellite from Gitolite # * Sets up Git variables for the user - def prepare_satelite!(repo) + def prepare_satellite!(repo) project.satellite.clear repo.git.reset(hard: true) From 847bba926929c4d64dcc5065b9b2762a62a87c87 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:10:40 +0200 Subject: [PATCH 041/122] Add Gitlab::Satellite::Action --- lib/gitlab/satellite/action.rb | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 lib/gitlab/satellite/action.rb diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb new file mode 100644 index 00000000..23f81856 --- /dev/null +++ b/lib/gitlab/satellite/action.rb @@ -0,0 +1,47 @@ +module Gitlab + module Satellite + class Action + DEFAULT_OPTIONS = { git_timeout: 30.seconds } + + attr_accessor :options, :project + + def initialize(project, options = {}) + @project = project + @options = DEFAULT_OPTIONS.merge(options) + end + + protected + + # * Sets a 30s timeout for Git + # * Locks the satellite repo + # * Yields the prepared satellite repo + def in_locked_and_timed_satellite + Grit::Git.with_timeout(options[:git_timeout]) do + File.open(lock_file, "w+") do |f| + f.flock(File::LOCK_EX) + + unless project.satellite.exists? + raise "Satellite doesn't exist" + end + + Dir.chdir(project.satellite.path) do + repo = Grit::Repo.new('.') + + return yield repo + end + end + end + rescue Errno::ENOMEM => ex + Gitlab::GitLogger.error(ex.message) + return false + rescue Grit::Git::GitTimeout => ex + Gitlab::GitLogger.error(ex.message) + return false + end + + def lock_file + Rails.root.join("tmp", "#{project.path}.lock") + end + end + end +end From 78235edda8009e7dcec3f15b3ec79a0c17d9d797 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:19:01 +0200 Subject: [PATCH 042/122] Renamed Gitlab::Merge to Gitlab::Satellite::MergeAction --- app/models/merge_request.rb | 4 +- lib/gitlab/merge.rb | 106 --------------------------- lib/gitlab/satellite/merge_action.rb | 83 +++++++++++++++++++++ 3 files changed, 85 insertions(+), 108 deletions(-) delete mode 100644 lib/gitlab/merge.rb create mode 100644 lib/gitlab/satellite/merge_action.rb diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 70780b75..9a79be12 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -60,7 +60,7 @@ class MergeRequest < ActiveRecord::Base end def check_if_can_be_merged - self.state = if Gitlab::Merge.new(self, self.author).can_be_merged? + self.state = if Gitlab::Satellite::MergeAction.new(self, self.author).can_be_merged? CAN_BE_MERGED else CANNOT_BE_MERGED @@ -167,7 +167,7 @@ class MergeRequest < ActiveRecord::Base end def automerge!(current_user) - if Gitlab::Merge.new(self, current_user).merge! && self.unmerged_commits.empty? + if Gitlab::Satellite::MergeAction.new(self, current_user).merge! && self.unmerged_commits.empty? self.merge!(current_user.id) true end diff --git a/lib/gitlab/merge.rb b/lib/gitlab/merge.rb deleted file mode 100644 index 28c20689..00000000 --- a/lib/gitlab/merge.rb +++ /dev/null @@ -1,106 +0,0 @@ -module Gitlab - class Merge - attr_accessor :merge_request, :project, :user - - def initialize(merge_request, user) - @merge_request = merge_request - @project = merge_request.project - @user = user - end - - def can_be_merged? - in_locked_and_timed_satellite do |merge_repo| - merge_in_satellite!(merge_repo) - end - end - - # Merges the source branch into the target branch in the satellite and - # pushes it back to Gitolite. - # It also removes the source branch if requested in the merge request. - # - # Returns false if the merge produced conflicts - # Returns false if pushing from the satellite to Gitolite failed or was rejected - # Returns true otherwise - def merge! - in_locked_and_timed_satellite do |merge_repo| - if merge_in_satellite!(merge_repo) - # push merge back to Gitolite - # will raise CommandFailed when push fails - merge_repo.git.push({raise: true}, :origin, merge_request.target_branch) - - # remove source branch - if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch) - # will raise CommandFailed when push fails - merge_repo.git.push({raise: true}, :origin, ":#{merge_request.source_branch}") - end - - # merge, push and branch removal successful - true - end - end - rescue Grit::Git::CommandFailed - false - end - - private - - # * Sets a 30s timeout for Git - # * Locks the satellite repo - # * Yields the prepared satellite repo - def in_locked_and_timed_satellite - Grit::Git.with_timeout(30.seconds) do - lock_file = Rails.root.join("tmp", "#{project.path}.lock") - - File.open(lock_file, "w+") do |f| - f.flock(File::LOCK_EX) - - unless project.satellite.exists? - raise "Satellite doesn't exist" - end - - Dir.chdir(project.satellite.path) do - repo = Grit::Repo.new('.') - - return yield repo - end - end - end - rescue Errno::ENOMEM => ex - Gitlab::GitLogger.error(ex.message) - rescue Grit::Git::GitTimeout - return false - end - - # Merges the source_branch into the target_branch in the satellite. - # - # Note: it will clear out the satellite before doing anything - # - # Returns false if the merge produced conflicts - # Returns true otherwise - def merge_in_satellite!(repo) - prepare_satellite!(repo) - - # create target branch in satellite at the corresponding commit from Gitolite - repo.git.checkout({b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") - - # merge the source branch from Gitolite into the satellite - # will raise CommandFailed when merge fails - repo.git.pull({no_ff: true, raise: true}, :origin, merge_request.source_branch) - rescue Grit::Git::CommandFailed - false - end - - # * Clears the satellite - # * Updates the satellite from Gitolite - # * Sets up Git variables for the user - def prepare_satellite!(repo) - project.satellite.clear - - repo.git.reset(hard: true) - repo.git.fetch({}, :origin) - - repo.git.config({}, "user.name", user.name) - repo.git.config({}, "user.email", user.email) - end - end -end diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb new file mode 100644 index 00000000..067a9ce8 --- /dev/null +++ b/lib/gitlab/satellite/merge_action.rb @@ -0,0 +1,83 @@ +module Gitlab + module Satellite + class MergeAction < Action + attr_accessor :merge_request, :user + + def initialize(merge_request, user) + super merge_request.project + @merge_request = merge_request + @user = user + end + + def can_be_merged? + in_locked_and_timed_satellite do |merge_repo| + merge_in_satellite!(merge_repo) + end + end + + # Merges the source branch into the target branch in the satellite and + # pushes it back to Gitolite. + # It also removes the source branch if requested in the merge request. + # + # Returns false if the merge produced conflicts + # Returns false if pushing from the satellite to Gitolite failed or was rejected + # Returns true otherwise + def merge! + in_locked_and_timed_satellite do |merge_repo| + if merge_in_satellite!(merge_repo) + # push merge back to Gitolite + # will raise CommandFailed when push fails + merge_repo.git.push({raise: true}, :origin, merge_request.target_branch) + + # remove source branch + if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch) + # will raise CommandFailed when push fails + merge_repo.git.push({raise: true}, :origin, ":#{merge_request.source_branch}") + end + + # merge, push and branch removal successful + true + end + end + rescue Grit::Git::CommandFailed => ex + Gitlab::GitLogger.error(ex.message) + false + end + + private + + # Merges the source_branch into the target_branch in the satellite. + # + # Note: it will clear out the satellite before doing anything + # + # Returns false if the merge produced conflicts + # Returns true otherwise + def merge_in_satellite!(repo) + prepare_satellite!(repo) + + # create target branch in satellite at the corresponding commit from Gitolite + repo.git.checkout({b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") + + # merge the source branch from Gitolite into the satellite + # will raise CommandFailed when merge fails + repo.git.pull({no_ff: true, raise: true}, :origin, merge_request.source_branch) + rescue Grit::Git::CommandFailed => ex + Gitlab::GitLogger.error(ex.message) + false + end + + # * Clears the satellite + # * Updates the satellite from Gitolite + # * Sets up Git variables for the user + def prepare_satellite!(repo) + project.satellite.clear + + repo.git.reset(hard: true) + repo.git.fetch({}, :origin) + + repo.git.config({}, "user.name", user.name) + repo.git.config({}, "user.email", user.email) + end + end + end +end From 8778961d33c15938f4ed3de301fd9b865b9299d8 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:24:02 +0200 Subject: [PATCH 043/122] Move prepare_satellite! to Gitlab::Satelite::Action --- lib/gitlab/satellite/action.rb | 20 ++++++++++++++++++-- lib/gitlab/satellite/merge_action.rb | 18 ++---------------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb index 23f81856..0d7eecdb 100644 --- a/lib/gitlab/satellite/action.rb +++ b/lib/gitlab/satellite/action.rb @@ -3,10 +3,11 @@ module Gitlab class Action DEFAULT_OPTIONS = { git_timeout: 30.seconds } - attr_accessor :options, :project + attr_accessor :options, :project, :user - def initialize(project, options = {}) + def initialize(project, user, options = {}) @project = project + @user = user @options = DEFAULT_OPTIONS.merge(options) end @@ -42,6 +43,21 @@ module Gitlab def lock_file Rails.root.join("tmp", "#{project.path}.lock") end + + # * Clears the satellite + # * Updates the satellite from Gitolite + # * Sets up Git variables for the user + # + # Note: use this within #in_locked_and_timed_satellite + def prepare_satellite!(repo) + project.satellite.clear + + repo.git.reset(hard: true) + repo.git.fetch({}, :origin) + + repo.git.config({}, "user.name", user.name) + repo.git.config({}, "user.email", user.email) + end end end end diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index 067a9ce8..fc4cd752 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -1,12 +1,11 @@ module Gitlab module Satellite class MergeAction < Action - attr_accessor :merge_request, :user + attr_accessor :merge_request def initialize(merge_request, user) - super merge_request.project + super merge_request.project, user @merge_request = merge_request - @user = user end def can_be_merged? @@ -65,19 +64,6 @@ module Gitlab Gitlab::GitLogger.error(ex.message) false end - - # * Clears the satellite - # * Updates the satellite from Gitolite - # * Sets up Git variables for the user - def prepare_satellite!(repo) - project.satellite.clear - - repo.git.reset(hard: true) - repo.git.fetch({}, :origin) - - repo.git.config({}, "user.name", user.name) - repo.git.config({}, "user.email", user.email) - end end end end From 35b7a5395524d25e3bb9c20b473f1a1eb6970b6f Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:24:16 +0200 Subject: [PATCH 044/122] Reorder methods in Gitlab::Satellite --- lib/gitlab/satellite.rb | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/gitlab/satellite.rb b/lib/gitlab/satellite.rb index 9d8dfb8e..64875f3f 100644 --- a/lib/gitlab/satellite.rb +++ b/lib/gitlab/satellite.rb @@ -5,20 +5,8 @@ module Gitlab attr_accessor :project - def initialize project - self.project = project - end - - def create - `git clone #{project.url_to_repo} #{path}` - end - - def path - Rails.root.join("tmp", "repo_satellites", project.path) - end - - def exists? - File.exists? path + def initialize(project) + @project = project end #will be deleted all branches except PARKING_BRANCH @@ -37,5 +25,16 @@ module Gitlab end end + def create + `git clone #{project.url_to_repo} #{path}` + end + + def exists? + File.exists? path + end + + def path + Rails.root.join("tmp", "repo_satellites", project.path) + end end end From 8c89beb6f9bca14dd79fb1e0a81ebb65354edf73 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:26:47 +0200 Subject: [PATCH 045/122] Change argument order for satellite actions to always start with the user --- app/models/merge_request.rb | 4 ++-- lib/gitlab/satellite/action.rb | 4 ++-- lib/gitlab/satellite/merge_action.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 9a79be12..9238aa48 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -60,7 +60,7 @@ class MergeRequest < ActiveRecord::Base end def check_if_can_be_merged - self.state = if Gitlab::Satellite::MergeAction.new(self, self.author).can_be_merged? + self.state = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged? CAN_BE_MERGED else CANNOT_BE_MERGED @@ -167,7 +167,7 @@ class MergeRequest < ActiveRecord::Base end def automerge!(current_user) - if Gitlab::Satellite::MergeAction.new(self, current_user).merge! && self.unmerged_commits.empty? + if Gitlab::Satellite::MergeAction.new(current_user, self).merge! && self.unmerged_commits.empty? self.merge!(current_user.id) true end diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb index 0d7eecdb..d50e28fa 100644 --- a/lib/gitlab/satellite/action.rb +++ b/lib/gitlab/satellite/action.rb @@ -5,10 +5,10 @@ module Gitlab attr_accessor :options, :project, :user - def initialize(project, user, options = {}) + def initialize(user, project, options = {}) + @options = DEFAULT_OPTIONS.merge(options) @project = project @user = user - @options = DEFAULT_OPTIONS.merge(options) end protected diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index fc4cd752..ffca6938 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -3,8 +3,8 @@ module Gitlab class MergeAction < Action attr_accessor :merge_request - def initialize(merge_request, user) - super merge_request.project, user + def initialize(user, merge_request) + super user, merge_request.project @merge_request = merge_request end From 55779b00ea695463056338af993c6332b710ea8f Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:33:53 +0200 Subject: [PATCH 046/122] Rename Gitlab::FileEditor to Gitlab::Satellite::EditFileAction --- app/controllers/tree_controller.rb | 2 +- lib/gitlab/file_editor.rb | 58 ------------------------ lib/gitlab/satellite/edit_file_action.rb | 43 ++++++++++++++++++ lib/gitlab/satellite/merge_action.rb | 4 +- 4 files changed, 46 insertions(+), 61 deletions(-) delete mode 100644 lib/gitlab/file_editor.rb create mode 100644 lib/gitlab/satellite/edit_file_action.rb diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb index e507fb51..60da719c 100644 --- a/app/controllers/tree_controller.rb +++ b/app/controllers/tree_controller.rb @@ -26,7 +26,7 @@ class TreeController < ProjectResourceController end def update - file_editor = Gitlab::FileEditor.new(current_user, @project, @ref) + file_editor = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref) update_status = file_editor.update( @path, params[:content], diff --git a/lib/gitlab/file_editor.rb b/lib/gitlab/file_editor.rb deleted file mode 100644 index dc3f9480..00000000 --- a/lib/gitlab/file_editor.rb +++ /dev/null @@ -1,58 +0,0 @@ -module Gitlab - # GitLab file editor - # - # It gives you ability to make changes to files - # & commit this changes from GitLab UI. - class FileEditor - attr_accessor :user, :project, :ref - - def initialize(user, project, ref) - self.user = user - self.project = project - self.ref = ref - end - - def update(path, content, commit_message, last_commit) - return false unless can_edit?(path, last_commit) - - Grit::Git.with_timeout(10.seconds) do - lock_file = Rails.root.join("tmp", "#{project.path}.lock") - - File.open(lock_file, "w+") do |f| - f.flock(File::LOCK_EX) - - unless project.satellite.exists? - raise "Satellite doesn't exist" - end - - project.satellite.clear - - Dir.chdir(project.satellite.path) do - r = Grit::Repo.new('.') - r.git.sh "git reset --hard" - r.git.sh "git fetch origin" - r.git.sh "git config user.name \"#{user.name}\"" - r.git.sh "git config user.email \"#{user.email}\"" - r.git.sh "git checkout -b #{ref} origin/#{ref}" - File.open(path, 'w'){|f| f.write(content)} - r.git.sh "git add ." - r.git.sh "git commit -am '#{commit_message}'" - output = r.git.sh "git push origin #{ref}" - - if output =~ /reject/ - return false - end - end - end - end - true - end - - protected - - def can_edit?(path, last_commit) - current_last_commit = @project.last_commit_for(ref, path).sha - last_commit == current_last_commit - end - end -end diff --git a/lib/gitlab/satellite/edit_file_action.rb b/lib/gitlab/satellite/edit_file_action.rb new file mode 100644 index 00000000..8949f54c --- /dev/null +++ b/lib/gitlab/satellite/edit_file_action.rb @@ -0,0 +1,43 @@ +module Gitlab + module Satellite + # GitLab file editor + # + # It gives you ability to make changes to files + # & commit this changes from GitLab UI. + class EditFileAction < Action + attr_accessor :ref + + def initialize(user, project, ref) + super user, project + @ref = ref + end + + def update(path, content, commit_message, last_commit) + return false unless can_edit?(path, last_commit) + + in_locked_and_timed_satellite do |repo| + prepare_satellite!(repo) + + repo.git.sh "git checkout -b #{ref} origin/#{ref}" + File.open(path, 'w'){|f| f.write(content)} + repo.git.sh "git add ." + repo.git.sh "git commit -am '#{commit_message}'" + output = repo.git.sh "git push origin #{ref}" + + # everything worked + true + end + rescue Grit::Git::CommandFailed => ex + Gitlab::GitLogger.error(ex.message) + false + end + + protected + + def can_edit?(path, last_commit) + current_last_commit = @project.last_commit_for(ref, path).sha + last_commit == current_last_commit + end + end + end +end diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index ffca6938..edef8f6a 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -55,11 +55,11 @@ module Gitlab prepare_satellite!(repo) # create target branch in satellite at the corresponding commit from Gitolite - repo.git.checkout({b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") + repo.git.checkout({raise: true, b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") # merge the source branch from Gitolite into the satellite # will raise CommandFailed when merge fails - repo.git.pull({no_ff: true, raise: true}, :origin, merge_request.source_branch) + repo.git.pull({raise: true, no_ff: true}, :origin, merge_request.source_branch) rescue Grit::Git::CommandFailed => ex Gitlab::GitLogger.error(ex.message) false From 5f16687805b4daa98f7227849d064345e68210d2 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:39:23 +0200 Subject: [PATCH 047/122] Update arguments for Gitlab::Satellite::EditFileAction#initialize --- app/controllers/tree_controller.rb | 3 +-- lib/gitlab/satellite/edit_file_action.rb | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb index 60da719c..7b527041 100644 --- a/app/controllers/tree_controller.rb +++ b/app/controllers/tree_controller.rb @@ -26,9 +26,8 @@ class TreeController < ProjectResourceController end def update - file_editor = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref) + file_editor = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path) update_status = file_editor.update( - @path, params[:content], params[:commit_message], params[:last_commit] diff --git a/lib/gitlab/satellite/edit_file_action.rb b/lib/gitlab/satellite/edit_file_action.rb index 8949f54c..0a5e753b 100644 --- a/lib/gitlab/satellite/edit_file_action.rb +++ b/lib/gitlab/satellite/edit_file_action.rb @@ -5,15 +5,16 @@ module Gitlab # It gives you ability to make changes to files # & commit this changes from GitLab UI. class EditFileAction < Action - attr_accessor :ref + attr_accessor :path, :ref - def initialize(user, project, ref) + def initialize(user, project, ref, path) super user, project + @path = path @ref = ref end - def update(path, content, commit_message, last_commit) - return false unless can_edit?(path, last_commit) + def update(content, commit_message, last_commit) + return false unless can_edit?(last_commit) in_locked_and_timed_satellite do |repo| prepare_satellite!(repo) @@ -34,7 +35,7 @@ module Gitlab protected - def can_edit?(path, last_commit) + def can_edit?(last_commit) current_last_commit = @project.last_commit_for(ref, path).sha last_commit == current_last_commit end From fba8ad560797500063df84089a99c24fdc5cacd7 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 00:56:24 +0200 Subject: [PATCH 048/122] Move Gitlab::Satellite into the Satellite module --- app/roles/repository.rb | 2 +- lib/gitlab/satellite.rb | 40 ------------------------------ lib/gitlab/satellite/satellite.rb | 41 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 41 deletions(-) delete mode 100644 lib/gitlab/satellite.rb create mode 100644 lib/gitlab/satellite/satellite.rb diff --git a/app/roles/repository.rb b/app/roles/repository.rb index 8942eaea..88468117 100644 --- a/app/roles/repository.rb +++ b/app/roles/repository.rb @@ -41,7 +41,7 @@ module Repository end def satellite - @satellite ||= Gitlab::Satellite.new(self) + @satellite ||= Gitlab::Satellite::Satellite.new(self) end def has_post_receive_file? diff --git a/lib/gitlab/satellite.rb b/lib/gitlab/satellite.rb deleted file mode 100644 index 64875f3f..00000000 --- a/lib/gitlab/satellite.rb +++ /dev/null @@ -1,40 +0,0 @@ -module Gitlab - class Satellite - - PARKING_BRANCH = "__parking_branch" - - attr_accessor :project - - def initialize(project) - @project = project - end - - #will be deleted all branches except PARKING_BRANCH - def clear - Dir.chdir(path) do - heads = Grit::Repo.new(".").heads.map{|head| head.name} - if heads.include? PARKING_BRANCH - `git checkout #{PARKING_BRANCH}` - else - `git checkout -b #{PARKING_BRANCH}` - end - heads.delete(PARKING_BRANCH) - heads.each do |head| - `git branch -D #{head}` - end - end - end - - def create - `git clone #{project.url_to_repo} #{path}` - end - - def exists? - File.exists? path - end - - def path - Rails.root.join("tmp", "repo_satellites", project.path) - end - end -end diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb new file mode 100644 index 00000000..5137cd4c --- /dev/null +++ b/lib/gitlab/satellite/satellite.rb @@ -0,0 +1,41 @@ +module Gitlab + module Satellite + class Satellite + PARKING_BRANCH = "__parking_branch" + + attr_accessor :project + + def initialize(project) + @project = project + end + + #will be deleted all branches except PARKING_BRANCH + def clear + Dir.chdir(path) do + heads = Grit::Repo.new(".").heads.map{|head| head.name} + if heads.include? PARKING_BRANCH + `git checkout #{PARKING_BRANCH}` + else + `git checkout -b #{PARKING_BRANCH}` + end + heads.delete(PARKING_BRANCH) + heads.each do |head| + `git branch -D #{head}` + end + end + end + + def create + `git clone #{project.url_to_repo} #{path}` + end + + def exists? + File.exists? path + end + + def path + Rails.root.join("tmp", "repo_satellites", project.path) + end + end + end +end From 0e9d4f30f4961cc7ee768995a37c5bf9a123c08a Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 01:32:33 +0200 Subject: [PATCH 049/122] Refactor Satellite#clear and rename it to clear_and_update! --- lib/gitlab/satellite/action.rb | 5 +-- lib/gitlab/satellite/satellite.rb | 56 +++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb index d50e28fa..9dd52b34 100644 --- a/lib/gitlab/satellite/action.rb +++ b/lib/gitlab/satellite/action.rb @@ -50,10 +50,7 @@ module Gitlab # # Note: use this within #in_locked_and_timed_satellite def prepare_satellite!(repo) - project.satellite.clear - - repo.git.reset(hard: true) - repo.git.fetch({}, :origin) + project.satellite.clear_and_update! repo.git.config({}, "user.name", user.name) repo.git.config({}, "user.email", user.email) diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index 5137cd4c..2147f40a 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -9,20 +9,10 @@ module Gitlab @project = project end - #will be deleted all branches except PARKING_BRANCH - def clear - Dir.chdir(path) do - heads = Grit::Repo.new(".").heads.map{|head| head.name} - if heads.include? PARKING_BRANCH - `git checkout #{PARKING_BRANCH}` - else - `git checkout -b #{PARKING_BRANCH}` - end - heads.delete(PARKING_BRANCH) - heads.each do |head| - `git branch -D #{head}` - end - end + def clear_and_update! + delete_heads! + clear_working_dir! + update_from_source! end def create @@ -36,6 +26,44 @@ module Gitlab def path Rails.root.join("tmp", "repo_satellites", project.path) end + + private + + # Clear the working directory + def clear_working_dir! + repo.git.reset(hard: true) + end + + # Deletes all branches except the parking branch + # + # This ensures we have no name clashes or issues updating branches when + # working with the satellite. + def delete_heads! + heads = repo.heads.map{|head| head.name} + + # update or create the parking branch + if heads.include? PARKING_BRANCH + repo.git.checkout({}, PARKING_BRANCH) + else + repo.git.checkout({b: true}, PARKING_BRANCH) + end + + # remove the parking branch from the list of heads ... + heads.delete(PARKING_BRANCH) + # ... and delete all others + heads.each { |head| repo.git.branch({D: true}, head) } + end + + def repo + @repo ||= Grit::Repo.new(path) + end + + # Updates the satellite from Gitolite + # + # Note: this will only update remote branches (i.e. origin/*) + def update_from_source! + repo.git.fetch({}, :origin) + end end end end From 0ebcc60a33f5aba9e7740f43a108b96461dd3fbf Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 01:44:20 +0200 Subject: [PATCH 050/122] Move locking from Satellite::Action to Satellite and add checks --- lib/gitlab/satellite/action.rb | 18 ++---------------- lib/gitlab/satellite/satellite.rb | 31 +++++++++++++++++++++++++------ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb index 9dd52b34..ed2541f3 100644 --- a/lib/gitlab/satellite/action.rb +++ b/lib/gitlab/satellite/action.rb @@ -18,18 +18,8 @@ module Gitlab # * Yields the prepared satellite repo def in_locked_and_timed_satellite Grit::Git.with_timeout(options[:git_timeout]) do - File.open(lock_file, "w+") do |f| - f.flock(File::LOCK_EX) - - unless project.satellite.exists? - raise "Satellite doesn't exist" - end - - Dir.chdir(project.satellite.path) do - repo = Grit::Repo.new('.') - - return yield repo - end + project.satellite.lock do + return yield project.satellite.repo end end rescue Errno::ENOMEM => ex @@ -40,10 +30,6 @@ module Gitlab return false end - def lock_file - Rails.root.join("tmp", "#{project.path}.lock") - end - # * Clears the satellite # * Updates the satellite from Gitolite # * Sets up Git variables for the user diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index 2147f40a..0b8d42ae 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -10,6 +10,8 @@ module Gitlab end def clear_and_update! + raise "Satellite doesn't exist" unless exists? + delete_heads! clear_working_dir! update_from_source! @@ -23,10 +25,31 @@ module Gitlab File.exists? path end + # Locks the satellite and yields + def lock + raise "Satellite doesn't exist" unless exists? + + File.open(lock_file, "w+") do |f| + f.flock(File::LOCK_EX) + + return yield + end + end + + def lock_file + Rails.root.join("tmp", "#{project.path}.lock") + end + def path Rails.root.join("tmp", "repo_satellites", project.path) end + def repo + raise "Satellite doesn't exist" unless exists? + + @repo ||= Grit::Repo.new(path) + end + private # Clear the working directory @@ -39,7 +62,7 @@ module Gitlab # This ensures we have no name clashes or issues updating branches when # working with the satellite. def delete_heads! - heads = repo.heads.map{|head| head.name} + heads = repo.heads.map(&:name) # update or create the parking branch if heads.include? PARKING_BRANCH @@ -54,15 +77,11 @@ module Gitlab heads.each { |head| repo.git.branch({D: true}, head) } end - def repo - @repo ||= Grit::Repo.new(path) - end - # Updates the satellite from Gitolite # # Note: this will only update remote branches (i.e. origin/*) def update_from_source! - repo.git.fetch({}, :origin) + repo.git.fetch({timeout: true}, :origin) end end end From 3080127354a2c92fd3ceecc05fe93e091e3b5eec Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 01:44:50 +0200 Subject: [PATCH 051/122] Fix timeouts in MergeAction --- lib/gitlab/satellite/merge_action.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index edef8f6a..6818e780 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -26,12 +26,12 @@ module Gitlab if merge_in_satellite!(merge_repo) # push merge back to Gitolite # will raise CommandFailed when push fails - merge_repo.git.push({raise: true}, :origin, merge_request.target_branch) + merge_repo.git.push({raise: true, timeout: true}, :origin, merge_request.target_branch) # remove source branch if merge_request.should_remove_source_branch && !project.root_ref?(merge_request.source_branch) # will raise CommandFailed when push fails - merge_repo.git.push({raise: true}, :origin, ":#{merge_request.source_branch}") + merge_repo.git.push({raise: true, timeout: true}, :origin, ":#{merge_request.source_branch}") end # merge, push and branch removal successful @@ -55,11 +55,11 @@ module Gitlab prepare_satellite!(repo) # create target branch in satellite at the corresponding commit from Gitolite - repo.git.checkout({raise: true, b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") + repo.git.checkout({raise: true, timeout: true, b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") # merge the source branch from Gitolite into the satellite # will raise CommandFailed when merge fails - repo.git.pull({raise: true, no_ff: true}, :origin, merge_request.source_branch) + repo.git.pull({raise: true, timeout: true, no_ff: true}, :origin, merge_request.source_branch) rescue Grit::Git::CommandFailed => ex Gitlab::GitLogger.error(ex.message) false From 700a784bc91c0ee24cbe2f1c36589e40b92ac28d Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 01:59:50 +0200 Subject: [PATCH 052/122] Refactor EditFileAction#update and rename it to commit! --- app/controllers/tree_controller.rb | 6 ++--- lib/gitlab/satellite/edit_file_action.rb | 32 ++++++++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb index 7b527041..725f48fa 100644 --- a/app/controllers/tree_controller.rb +++ b/app/controllers/tree_controller.rb @@ -26,14 +26,14 @@ class TreeController < ProjectResourceController end def update - file_editor = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path) - update_status = file_editor.update( + edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, @project, @ref, @path) + updated_successfully = edit_file_action.commit!( params[:content], params[:commit_message], params[:last_commit] ) - if update_status + if updated_successfully redirect_to project_tree_path(@project, @id), notice: "Your changes have been successfully commited" else flash[:notice] = "Your changes could not be commited, because the file has been changed" diff --git a/lib/gitlab/satellite/edit_file_action.rb b/lib/gitlab/satellite/edit_file_action.rb index 0a5e753b..1e2a2163 100644 --- a/lib/gitlab/satellite/edit_file_action.rb +++ b/lib/gitlab/satellite/edit_file_action.rb @@ -5,25 +5,35 @@ module Gitlab # It gives you ability to make changes to files # & commit this changes from GitLab UI. class EditFileAction < Action - attr_accessor :path, :ref + attr_accessor :file_path, :ref - def initialize(user, project, ref, path) - super user, project - @path = path + def initialize(user, project, ref, file_path) + super user, project, git_timeout: 10.seconds + @file_path = file_path @ref = ref end - def update(content, commit_message, last_commit) + def commit!(content, commit_message, last_commit) return false unless can_edit?(last_commit) in_locked_and_timed_satellite do |repo| prepare_satellite!(repo) - repo.git.sh "git checkout -b #{ref} origin/#{ref}" - File.open(path, 'w'){|f| f.write(content)} - repo.git.sh "git add ." - repo.git.sh "git commit -am '#{commit_message}'" - output = repo.git.sh "git push origin #{ref}" + # create target branch in satellite at the corresponding commit from Gitolite + repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") + + # update the file in the satellite's working dir + file_path_in_satellite = File.join(repo.working_dir, file_path) + File.open(file_path_in_satellite, 'w') { |f| f.write(content) } + + # commit the changes + # will raise CommandFailed when commit fails + repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) + + + # push commit back to Gitolite + # will raise CommandFailed when push fails + repo.git.push({raise: true, timeout: true}, :origin, ref) # everything worked true @@ -36,7 +46,7 @@ module Gitlab protected def can_edit?(last_commit) - current_last_commit = @project.last_commit_for(ref, path).sha + current_last_commit = @project.last_commit_for(ref, file_path).sha last_commit == current_last_commit end end From 7192f86ed0e2eec1bee94ee148253c1e65f925e3 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 02:32:17 +0200 Subject: [PATCH 053/122] Fix Satellite#lock --- lib/gitlab/satellite/satellite.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb index 0b8d42ae..28b6f538 100644 --- a/lib/gitlab/satellite/satellite.rb +++ b/lib/gitlab/satellite/satellite.rb @@ -25,14 +25,18 @@ module Gitlab File.exists? path end - # Locks the satellite and yields + # * Locks the satellite + # * Changes the current directory to the satellite's working dir + # * Yields def lock raise "Satellite doesn't exist" unless exists? File.open(lock_file, "w+") do |f| f.flock(File::LOCK_EX) - return yield + Dir.chdir(path) do + return yield + end end end From 904615c1509b0923ba9b785d41cafcd264952d54 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Fri, 26 Oct 2012 02:50:24 +0200 Subject: [PATCH 054/122] Update satellite action docs --- lib/gitlab/satellite/edit_file_action.rb | 11 +++++++---- lib/gitlab/satellite/merge_action.rb | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/gitlab/satellite/edit_file_action.rb b/lib/gitlab/satellite/edit_file_action.rb index 1e2a2163..336afc88 100644 --- a/lib/gitlab/satellite/edit_file_action.rb +++ b/lib/gitlab/satellite/edit_file_action.rb @@ -1,9 +1,6 @@ module Gitlab module Satellite - # GitLab file editor - # - # It gives you ability to make changes to files - # & commit this changes from GitLab UI. + # GitLab server-side file update and commit class EditFileAction < Action attr_accessor :file_path, :ref @@ -13,6 +10,12 @@ module Gitlab @ref = ref end + # Updates the files content and creates a new commit for it + # + # Returns false if the ref has been updated while editing the file + # Returns false if commiting the change fails + # Returns false if pushing from the satellite to Gitolite failed or was rejected + # Returns true otherwise def commit!(content, commit_message, last_commit) return false unless can_edit?(last_commit) diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index 6818e780..832db662 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -1,5 +1,6 @@ module Gitlab module Satellite + # GitLab server-side merge class MergeAction < Action attr_accessor :merge_request @@ -8,6 +9,7 @@ module Gitlab @merge_request = merge_request end + # Checks if a merge request can be executed without user interaction def can_be_merged? in_locked_and_timed_satellite do |merge_repo| merge_in_satellite!(merge_repo) From bd50a9f466b3df15917b32142bfc325114ef811a Mon Sep 17 00:00:00 2001 From: Markus Grobelin Date: Fri, 26 Oct 2012 14:05:57 +0200 Subject: [PATCH 055/122] grack: allow repositories to have dots in name, e.g. serverconfigs-example.com.git --- config/routes.rb | 2 +- lib/gitlab/backend/grack_auth.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index adaf6a1e..e597c61e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,7 +18,7 @@ Gitlab::Application.routes.draw do project_root: Gitlab.config.git_base_path, upload_pack: Gitlab.config.git_upload_pack, receive_pack: Gitlab.config.git_receive_pack - }), at: '/:path', constraints: { path: /[\w-]+\.git/ } + }), at: '/:path', constraints: { path: /[\w\.-]+\.git/ } # # Help diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb index 766e3874..dd5a9bec 100644 --- a/lib/gitlab/backend/grack_auth.rb +++ b/lib/gitlab/backend/grack_auth.rb @@ -18,7 +18,7 @@ module Grack @env['SCRIPT_NAME'] = "" # Find project by PATH_INFO from env - if m = /^\/([\w-]+).git/.match(@request.path_info).to_a + if m = /^\/([\w\.-]+)\.git/.match(@request.path_info).to_a self.project = Project.find_by_path(m.last) return false unless project end @@ -65,7 +65,7 @@ module Grack end # Need to reset seek point @request.body.rewind - /refs\/heads\/([\w-]+)/.match(input).to_a.first + /refs\/heads\/([\w\.-]+)/.match(input).to_a.first end protected From a7d0816933497a9e2db6abac7fac3ad73ac58582 Mon Sep 17 00:00:00 2001 From: Sergio Visinoni Date: Fri, 26 Oct 2012 14:52:10 +0200 Subject: [PATCH 056/122] Add Milestone information in Merge Requests Step 1: * Add milestone_id in the model for merge_requests * Make it possible to create or update a Merge Request with an attached Milestone detail * Add the possibility to filter by Milestone and / or Assignee in the Merge Requests listing page --- app/assets/javascripts/merge_requests.js | 11 ++++++ .../stylesheets/sections/merge_requests.scss | 17 +++++++++ app/contexts/merge_requests_load_context.rb | 15 +++++++- app/models/merge_request.rb | 9 ++++- app/views/merge_requests/_form.html.haml | 18 ++++++--- app/views/merge_requests/index.html.haml | 37 ++++++++++++------- ...4600_add_milestone_id_to_merge_requests.rb | 5 +++ db/schema.rb | 3 +- 8 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 db/migrate/20121026114600_add_milestone_id_to_merge_requests.rb diff --git a/app/assets/javascripts/merge_requests.js b/app/assets/javascripts/merge_requests.js index 0ab6f6e2..cc6b0771 100644 --- a/app/assets/javascripts/merge_requests.js +++ b/app/assets/javascripts/merge_requests.js @@ -115,4 +115,15 @@ var MergeRequest = { $(".merge_in_progress").hide(); $(".automerge_widget.already_cannot_be_merged").show(); } +}; + +/* + * Filter merge requests + */ +function merge_requestsPage() { + $("#assignee_id").chosen(); + $("#milestone_id").chosen(); + $("#milestone_id, #assignee_id").on("change", function(){ + $(this).closest("form").submit(); + }); } diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index c932f0fc..fc9ad472 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -121,3 +121,20 @@ li.merge_request { .mr_direction_tip { margin-top:40px } + +.merge_requests_form_box { + @extend .main_box; + .merge_requests_middle_box { + @extend .middle_box_content; + height:30px; + .merge_requests_assignee { + @extend .span6; + float:left; + } + .merge_requests_milestone { + @extend .span4; + float:left; + } + } +} + diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb index e7dbdd28..45adb110 100644 --- a/app/contexts/merge_requests_load_context.rb +++ b/app/contexts/merge_requests_load_context.rb @@ -2,7 +2,7 @@ class MergeRequestsLoadContext < BaseContext def execute type = params[:f] - merge_requests = project.merge_requests + merge_requests = @project.merge_requests merge_requests = case type when 'all' then merge_requests @@ -12,5 +12,18 @@ class MergeRequestsLoadContext < BaseContext end.page(params[:page]).per(20) merge_requests.includes(:author, :project).order("closed, created_at desc") + + @merge_requests = merge_requests + + # Filter by specific assignee_id (or lack thereof)? + if params[:assignee_id].present? + @merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) + end + + # Filter by specific milestone_id (or lack thereof)? + if params[:milestone_id].present? + @merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) + end + @merge_requests end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 70780b75..8a521583 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -4,11 +4,13 @@ class MergeRequest < ActiveRecord::Base include IssueCommonality include Votes - attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, + attr_accessible :title, :assignee_id, :closed, :target_branch, :source_branch, :milestone_id, :author_id_of_changes attr_accessor :should_remove_source_branch + belongs_to :milestone + BROKEN_DIFF = "--broken-diff" UNCHECKED = 1 @@ -26,6 +28,10 @@ class MergeRequest < ActiveRecord::Base where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) end + def self.find_all_by_milestone(milestone) + where("milestone_id = :milestone_id", milestone_id: milestone) + end + def human_state states = { CAN_BE_MERGED => "can_be_merged", @@ -212,5 +218,6 @@ end # st_diffs :text(4294967295 # merged :boolean default(FALSE), not null # state :integer default(1), not null +# milestone_id :integer # diff --git a/app/views/merge_requests/_form.html.haml b/app/views/merge_requests/_form.html.haml index 30f88102..bf8e0c58 100644 --- a/app/views/merge_requests/_form.html.haml +++ b/app/views/merge_requests/_form.html.haml @@ -28,16 +28,22 @@ %h4.cdark 2. Fill info .clearfix - .main_box + .merge_requests_form_box .top_box_content = f.label :title do %strong= "Title *" .input= f.text_field :title, class: "input-xxlarge pad gfm-input", maxlength: 255, rows: 5 - .middle_box_content - = f.label :assignee_id do - %i.icon-user - Assign to - .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'}) + .merge_requests_middle_box + .merge_requests_assignee + = f.label :assignee_id do + %i.icon-user + Assign to + .input= f.select(:assignee_id, @project.users.all.collect {|p| [ p.name, p.id ] }, { include_blank: "Select user" }, {class: 'chosen span3'}) + .merge_requests_milestone + = f.label :milestone_id do + %i.icon-time + Milestone + .input= f.select(:milestone_id, @project.milestones.active.all.collect {|p| [ p.title, p.id ] }, { include_blank: "Select milestone" }, {class: 'chosen'}) .control-group diff --git a/app/views/merge_requests/index.html.haml b/app/views/merge_requests/index.html.haml index bbf35dc7..7bcb7a81 100644 --- a/app/views/merge_requests/index.html.haml +++ b/app/views/merge_requests/index.html.haml @@ -9,19 +9,26 @@ .ui-box .title - %ul.nav.nav-pills - %li{class: ("active" if (params[:f] == 'open' || !params[:f]))} - = link_to project_merge_requests_path(@project, f: 'open') do - Open - %li{class: ("active" if params[:f] == "closed")} - = link_to project_merge_requests_path(@project, f: "closed") do - Closed - %li{class: ("active" if params[:f] == 'assigned-to-me')} - = link_to project_merge_requests_path(@project, f: 'assigned-to-me') do - To Me - %li{class: ("active" if params[:f] == 'all')} - = link_to project_merge_requests_path(@project, f: 'all') do - All + .left + %ul.nav.nav-pills + %li{class: ("active" if (params[:f] == 'open' || !params[:f]))} + = link_to project_merge_requests_path(@project, f: 'open', milestone_id: params[:milestone_id]) do + Open + %li{class: ("active" if params[:f] == "closed")} + = link_to project_merge_requests_path(@project, f: "closed", milestone_id: params[:milestone_id]) do + Closed + %li{class: ("active" if params[:f] == 'assigned-to-me')} + = link_to project_merge_requests_path(@project, f: 'assigned-to-me', milestone_id: params[:milestone_id]) do + To Me + %li{class: ("active" if params[:f] == 'all')} + = link_to project_merge_requests_path(@project, f: 'all', milestone_id: params[:milestone_id]) do + All + .right + = form_tag project_merge_requests_path(@project), id: "merge_requests_search_form", method: :get, class: :right do + = select_tag(:assignee_id, options_from_collection_for_select([unassigned_filter] + @project.users.all, "id", "name", params[:assignee_id]), prompt: "Assignee") + = select_tag(:milestone_id, options_from_collection_for_select([unassigned_filter] + @project.milestones.order("id desc").all, "id", "title", params[:milestone_id]), prompt: "Milestone") + = hidden_field_tag :f, params[:f] + .clearfix %ul.unstyled = render @merge_requests @@ -35,3 +42,7 @@ .span4.right %span.cgray.right #{@merge_requests.total_count} merge requests for this filter +:javascript + $(function() { + merge_requestsPage(); + }) diff --git a/db/migrate/20121026114600_add_milestone_id_to_merge_requests.rb b/db/migrate/20121026114600_add_milestone_id_to_merge_requests.rb new file mode 100644 index 00000000..b5167724 --- /dev/null +++ b/db/migrate/20121026114600_add_milestone_id_to_merge_requests.rb @@ -0,0 +1,5 @@ +class AddMilestoneIdToMergeRequests < ActiveRecord::Migration + def change + add_column :merge_requests, :milestone_id, :integer, :null => true + end +end diff --git a/db/schema.rb b/db/schema.rb index a7037811..51ab2072 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20121009205010) do +ActiveRecord::Schema.define(:version => 20121026114600) do create_table "events", :force => true do |t| t.string "target_type" @@ -73,6 +73,7 @@ ActiveRecord::Schema.define(:version => 20121009205010) do t.text "st_diffs", :limit => 2147483647 t.boolean "merged", :default => false, :null => false t.integer "state", :default => 1, :null => false + t.integer "milestone_id" end add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" From e51c37bdbda1822f93e1f8bcc21e970686eec464 Mon Sep 17 00:00:00 2001 From: Sergio Visinoni Date: Fri, 26 Oct 2012 15:53:45 +0200 Subject: [PATCH 057/122] Display Merge Requests <-> Milestone relations Show the relation between Merge Requests and Mileston in different places: - Merge Request page - Milestone list page - Milestone details page --- app/controllers/milestones_controller.rb | 1 + app/models/milestone.rb | 1 + app/views/merge_requests/show/_mr_box.html.haml | 6 +++++- app/views/milestones/_milestone.html.haml | 4 ++++ app/views/milestones/show.html.haml | 16 ++++++++++++++++ 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb index fa202cf4..ac28f000 100644 --- a/app/controllers/milestones_controller.rb +++ b/app/controllers/milestones_controller.rb @@ -32,6 +32,7 @@ class MilestonesController < ProjectResourceController def show @issues = @milestone.issues @users = @milestone.participants + @merge_requests = @milestone.merge_requests respond_to do |format| format.html diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 06c09431..b924dc5f 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -3,6 +3,7 @@ class Milestone < ActiveRecord::Base belongs_to :project has_many :issues + has_many :merge_requests validates :title, presence: true validates :project, presence: true diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml index 89c3110b..26636435 100644 --- a/app/views/merge_requests/show/_mr_box.html.haml +++ b/app/views/merge_requests/show/_mr_box.html.haml @@ -14,9 +14,13 @@ %strong.author= link_to_merge_request_author(@merge_request) - if @merge_request.assignee - %cite.cgray and currently assigned to + %cite.cgray , currently assigned to = image_tag gravatar_icon(@merge_request.assignee_email), width: 16, class: "lil_av" %strong.author= link_to_merge_request_assignee(@merge_request) + - if @merge_request.milestone + - milestone = @merge_request.milestone + %cite.cgray and attached to milestone + %strong= link_to_gfm truncate(milestone.title, length: 20), project_milestone_path(milestone.project, milestone) - if @merge_request.closed diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 205b864f..3ccd9360 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -4,6 +4,10 @@ %span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'issues' - if milestone.issues.count > 0 = link_to 'Browse Issues', project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped" + - if milestone.merge_requests.any? + %span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'Merge Requests' + - if milestone.merge_requests.count > 0 + = link_to 'Browse Merge Requests', project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped" - if can? current_user, :admin_milestone, milestone.project = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" %h4 diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml index c113c81f..ad4580d4 100644 --- a/app/views/milestones/show.html.haml +++ b/app/views/milestones/show.html.haml @@ -60,6 +60,22 @@ = link_to_gfm truncate(issue.title, length: 60), [@project, issue] %br + .span6 + %table.milestone-merge_requests-filter + %thead + %th + %ul.nav.nav-pills + %li.active= link_to('Open Merge Requests', '#') + %li=link_to('All Merge Requests', '#') + - @merge_requests.each do |merge_request| + %tr{data: {closed: merge_request.closed}} + %td + = link_to [@project, merge_request] do + %span.badge.badge-info ##{merge_request.id} + – + = link_to_gfm truncate(merge_request.title, length: 60), [@project, merge_request] + %br + .span6 %table %thead From f73e46eece9e4f43703fa9bf6583ec7b38bb6c8f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 26 Oct 2012 17:13:24 +0300 Subject: [PATCH 058/122] Remove gitolite config sed because our gitolite fork already has it in sources --- doc/install/installation.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/install/installation.md b/doc/install/installation.md index b9b82a72..03c35c76 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -103,8 +103,7 @@ Setup: sudo chmod 0444 /home/git/gitlab.pub sudo -u git -H sh -c "PATH=/home/git/bin:$PATH; gitolite setup -pk /home/git/gitlab.pub" - sudo -u git -H sed -i 's/0077/0007/g' /home/git/.gitolite.rc - sudo -u git -H sed -i "s/\(GIT_CONFIG_KEYS\s*=>*\s*\).\{2\}/\1'\.\*'/g" /home/git/.gitolite.rc + Permissions: From b4708d006c7a423a1682916403cfab848a9a48b8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 26 Oct 2012 18:37:12 +0300 Subject: [PATCH 059/122] Restyled git tags page. Added truncated tags message --- .../stylesheets/gitlab_bootstrap/common.scss | 1 + .../stylesheets/gitlab_bootstrap/tables.scss | 5 +++++ app/decorators/commit_decorator.rb | 2 +- app/views/repositories/tags.html.haml | 22 ++++++++++--------- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss index eb3bd06f..aa9c421f 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss @@ -29,6 +29,7 @@ .underlined_link { text-decoration: underline; } .borders { border: 1px solid #ccc; @include shade; } .hint { font-style: italic; color: #999; } +.light { color: #888 } /** PILLS & TABS**/ .nav-pills a:hover { background-color:#888; } diff --git a/app/assets/stylesheets/gitlab_bootstrap/tables.scss b/app/assets/stylesheets/gitlab_bootstrap/tables.scss index 7a3bda2b..549cdfee 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/tables.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/tables.scss @@ -34,6 +34,11 @@ table { border-color:#f1f1f1; line-height:28px; + .s16 { + margin-top: 5px; + margin-right: 5px; + } + &:first-child { border-left:1px solid #bbb; } diff --git a/app/decorators/commit_decorator.rb b/app/decorators/commit_decorator.rb index 24723941..652b41f6 100644 --- a/app/decorators/commit_decorator.rb +++ b/app/decorators/commit_decorator.rb @@ -50,7 +50,7 @@ class CommitDecorator < ApplicationDecorator # avatar: true will prepend avatar image def author_link(options) text = if options[:avatar] - avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar", width: 16 + avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar s16", width: 16 "#{avatar} #{author_name}" else author_name diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml index 38cc3aca..ba4692ff 100644 --- a/app/views/repositories/tags.html.haml +++ b/app/views/repositories/tags.html.haml @@ -5,27 +5,29 @@ %tr %th Name %th Last commit - %th Updated at %th - @tags.each do |tag| - commit = Commit.new(tag.commit) - commit = CommitDecorator.decorate(commit) %tr %td - %strong= link_to tag.name, project_commits_path(@project, tag.name), class: "" + %strong + = link_to project_commits_path(@project, tag.name), class: "" do + %i.icon-tag + = tag.name + %small.light= truncate(tag.message, length: 70) %td - = link_to project_commit_path(@project, commit.id) do - %code= commit.short_id - = image_tag gravatar_icon(commit.author_email), class: "", width: 16 - = gfm escape_once(truncate(commit.title, length: 40)) - %td - %span.update-author.right + = image_tag gravatar_icon(commit.author_email), class: "avatar s16" + = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do + = commit.short_id + %span.light = time_ago_in_words(commit.committed_date) ago -   %td - if can? current_user, :download_code, @project - = link_to "Download", archive_project_repository_path(@project, ref: tag.name), class: "visible_link download_repo_link" + = link_to archive_project_repository_path(@project, ref: tag.name) do + %i.icon-download + Download - else %h3 No tags From 1c9351abf015ef3fc1375511cd0138d2759ca8f5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 26 Oct 2012 19:00:09 +0300 Subject: [PATCH 060/122] Restyle branches list. Remove unneccesary styles from tree avatar --- app/assets/stylesheets/sections/tree.scss | 5 +---- app/views/repositories/_branch.html.haml | 20 ++++++++++++------- .../repositories/_branches_head.html.haml | 4 +++- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss index e17487fd..e7d20874 100644 --- a/app/assets/stylesheets/sections/tree.scss +++ b/app/assets/stylesheets/sections/tree.scss @@ -57,10 +57,7 @@ padding-right: 8px; img.avatar { - border: 0 none; - float: none; - margin-right: 0; - padding: 0; + margin-top: 0; width: 16px; } } diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml index 3c1fe47c..2728b100 100644 --- a/app/views/repositories/_branch.html.haml +++ b/app/views/repositories/_branch.html.haml @@ -3,19 +3,25 @@ %tr %td = link_to project_commits_path(@project, branch.name) do + - if @project.protected_branch? branch.name + %i.icon-lock + - else + %i.icon-unlock %strong= truncate(branch.name, length: 60) - if branch.name == @project.root_ref %span.label default %td - = link_to project_commit_path(@project, commit) do - %code= commit.short_id - - = image_tag gravatar_icon(commit.author_email), class: "", width: 16 - = gfm escape_once(truncate(commit.title, length: 40)) - %span.update-author.right + = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do + = commit.short_id + = image_tag gravatar_icon(commit.author_email), class: "avatar s16" + %span.light + = gfm escape_once(truncate(commit.title, length: 40)) + %span = time_ago_in_words(commit.committed_date) ago %td - if can? current_user, :download_code, @project - = link_to "Download", archive_project_repository_path(@project, ref: branch.name), class: "visible_link download_repo_link" + = link_to archive_project_repository_path(@project, ref: branch.name) do + %i.icon-download + Download diff --git a/app/views/repositories/_branches_head.html.haml b/app/views/repositories/_branches_head.html.haml index 25a988cf..8f3e1ba3 100644 --- a/app/views/repositories/_branches_head.html.haml +++ b/app/views/repositories/_branches_head.html.haml @@ -3,6 +3,8 @@ = nav_link(path: 'repositories#show') do = link_to 'Recent', project_repository_path(@project) = nav_link(path: 'protected_branches#index') do - = link_to 'Protected', project_protected_branches_path(@project) + = link_to project_protected_branches_path(@project) do + %i.icon-lock + Protected = nav_link(path: 'repositories#branches') do = link_to 'All', branches_project_repository_path(@project) From 72f984e3d3505c5ff3dd1096f92d4be075fee04f Mon Sep 17 00:00:00 2001 From: randx Date: Fri, 26 Oct 2012 21:52:26 +0300 Subject: [PATCH 061/122] Prevent grit from caching graph commits --- app/views/repositories/tags.html.haml | 2 +- lib/gitlab/graph_commit.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml index ba4692ff..193cb2e3 100644 --- a/app/views/repositories/tags.html.haml +++ b/app/views/repositories/tags.html.haml @@ -15,7 +15,7 @@ = link_to project_commits_path(@project, tag.name), class: "" do %i.icon-tag = tag.name - %small.light= truncate(tag.message, length: 70) + %small.light= truncate(tag.message || '', length: 70) %td = image_tag gravatar_icon(commit.author_email), class: "avatar s16" = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do diff --git a/lib/gitlab/graph_commit.rb b/lib/gitlab/graph_commit.rb index d3668a99..188fc422 100644 --- a/lib/gitlab/graph_commit.rb +++ b/lib/gitlab/graph_commit.rb @@ -9,7 +9,7 @@ module Gitlab def self.to_graph(project) @repo = project.repo - commits = Grit::Commit.find_all(@repo, nil, {max_count: 650}) + commits = Grit::Commit.find_all(@repo, nil, {max_count: 650}).dup ref_cache = {} From cec97c27083c00070513914a0063de349f0afcbb Mon Sep 17 00:00:00 2001 From: randx Date: Fri, 26 Oct 2012 22:10:17 +0300 Subject: [PATCH 062/122] we dont show commit message on tags page any more --- spec/requests/gitlab_flavored_markdown_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb index 106f6451..014f99eb 100644 --- a/spec/requests/gitlab_flavored_markdown_spec.rb +++ b/spec/requests/gitlab_flavored_markdown_spec.rb @@ -80,12 +80,6 @@ describe "Gitlab Flavored Markdown" do page.should have_link("##{issue.id}") end - - it "should render title in repositories#tags" do - visit tags_project_repository_path(project) - - page.should have_link("##{issue.id}") - end end describe "for issues" do From d2c7a75970be4037846019fe612754e87a2140e2 Mon Sep 17 00:00:00 2001 From: Aiden Scandella Date: Fri, 26 Oct 2012 14:05:20 -0700 Subject: [PATCH 063/122] Fix PostgreSQL setup instructions The config skeleton for postgres is called `database.yml.postgresql`, not `database.yml.postgres`. --- doc/install/databases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/install/databases.md b/doc/install/databases.md index 8ca3d8fe..fd87eee4 100644 --- a/doc/install/databases.md +++ b/doc/install/databases.md @@ -58,7 +58,7 @@ GitLab use mysql as default database but you are free to use PostgreSQL or SQLit sudo -u gitlab cp config/database.yml.mysql config/database.yml # PostgreSQL - sudo -u gitlab cp config/database.yml.postgres config/database.yml + sudo -u gitlab cp config/database.yml.postgresql config/database.yml # make sure to update username/password in config/database.yml From c370c1b389fe4411b2c1740c23fb7396aa5e9698 Mon Sep 17 00:00:00 2001 From: Michele Franzin Date: Sat, 27 Oct 2012 16:12:01 +0200 Subject: [PATCH 064/122] gitolite's repositories folder symlinked patch --- lib/tasks/gitlab/status.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/gitlab/status.rake b/lib/tasks/gitlab/status.rake index 302f417c..3878823c 100644 --- a/lib/tasks/gitlab/status.rake +++ b/lib/tasks/gitlab/status.rake @@ -49,7 +49,7 @@ namespace :gitlab do end print "UMASK for .gitolite.rc is 0007? ............" - if open("#{git_base_path}/../.gitolite.rc").grep(/UMASK([ \t]*)=([ \t>]*)0007/).any? + if open(File.absolute_path("#{git_base_path}/../.gitolite.rc")).grep(/UMASK([ \t]*)=([ \t>]*)0007/).any? puts "YES".green else puts "NO".red From 2f5e44a02d536b6c05a278ac63b022c9cae1fbfd Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 27 Oct 2012 17:00:51 +0200 Subject: [PATCH 065/122] Enable/disable from buttons on all input events (not just key events) Fixes #1836 --- app/assets/javascripts/main.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 93b122d9..fb82f799 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -14,7 +14,7 @@ window.disableButtonIfEmptyField = (field_selector, button_selector) -> closest_submit.disable() if field.val() is "" - field.on "keyup", -> + field.on "input", -> if $(@).val() is "" closest_submit.disable() else From 17cec0508776ee577b67b2542f8757accef32c79 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 27 Oct 2012 17:35:15 +0200 Subject: [PATCH 066/122] Make new/edit issue forms use containers on the page instead of adding their own Fixes #1830 --- app/assets/javascripts/issues.js | 10 ++++------ app/views/issues/edit.js.haml | 5 ++--- app/views/issues/index.html.haml | 2 ++ app/views/issues/new.js.haml | 5 ++--- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js index c3cf364f..db3ad7f7 100644 --- a/app/assets/javascripts/issues.js +++ b/app/assets/javascripts/issues.js @@ -1,6 +1,5 @@ -function switchToNewIssue(form){ +function switchToNewIssue(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ - $(".issues_content").after(form); $('select#issue_assignee_id').chosen(); $('select#issue_milestone_id').chosen(); $("#new_issue_dialog").show("fade", { direction: "right" }, 150); @@ -10,9 +9,8 @@ function switchToNewIssue(form){ }); } -function switchToEditIssue(form){ +function switchToEditIssue(){ $(".issues_content").hide("fade", { direction: "left" }, 150, function(){ - $(".issues_content").after(form); $('select#issue_assignee_id').chosen(); $('select#issue_milestone_id').chosen(); $("#edit_issue_dialog").show("fade", { direction: "right" }, 150); @@ -33,8 +31,8 @@ function switchFromEditIssue(){ function backToIssues(){ $("#edit_issue_dialog, #new_issue_dialog").hide("fade", { direction: "right" }, 150, function(){ $(".issues_content").show("fade", { direction: "left" }, 150, function() { - $("#edit_issue_dialog").remove(); - $("#new_issue_dialog").remove(); + $("#edit_issue_dialog").html(""); + $("#new_issue_dialog").html(""); $('.add_new').show(); }); }); diff --git a/app/views/issues/edit.js.haml b/app/views/issues/edit.js.haml index 76d9e02e..a994572f 100644 --- a/app/views/issues/edit.js.haml +++ b/app/views/issues/edit.js.haml @@ -1,5 +1,4 @@ :plain - var edit_issue_dialog = $("
    "); - edit_issue_dialog.html("#{escape_javascript(render('form'))}"); - switchToEditIssue(edit_issue_dialog); + $("#edit_issue_dialog").html("#{escape_javascript(render('form'))}"); + switchToEditIssue(); diff --git a/app/views/issues/index.html.haml b/app/views/issues/index.html.haml index 22c34baa..d89b183d 100644 --- a/app/views/issues/index.html.haml +++ b/app/views/issues/index.html.haml @@ -58,6 +58,8 @@ %ul#issues-table.unstyled.issues_table = render "issues" +#new_issue_dialog +#edit_issue_dialog :javascript $(function(){ diff --git a/app/views/issues/new.js.haml b/app/views/issues/new.js.haml index afa2b86e..4cbcc563 100644 --- a/app/views/issues/new.js.haml +++ b/app/views/issues/new.js.haml @@ -1,4 +1,3 @@ :plain - var new_issue_dialog = $("
    "); - new_issue_dialog.html("#{escape_javascript(render('form'))}"); - switchToNewIssue(new_issue_dialog); + $("#new_issue_dialog").html("#{escape_javascript(render('form'))}"); + switchToNewIssue(); From c78359a84bc958c7e6d4fca84dc77b25f6b28cf7 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 27 Oct 2012 18:15:00 +0200 Subject: [PATCH 067/122] Generalize CommitDecorator#author_link to #person_link --- app/decorators/commit_decorator.rb | 48 +++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/app/decorators/commit_decorator.rb b/app/decorators/commit_decorator.rb index 652b41f6..69d5b178 100644 --- a/app/decorators/commit_decorator.rb +++ b/app/decorators/commit_decorator.rb @@ -47,21 +47,15 @@ class CommitDecorator < ApplicationDecorator # Otherwise it will link to the author email as specified in the commit. # # options: - # avatar: true will prepend avatar image - def author_link(options) - text = if options[:avatar] - avatar = h.image_tag h.gravatar_icon(author_email), class: "avatar s16", width: 16 - "#{avatar} #{author_name}" - else - author_name - end - team_member = @project.try(:team_member_by_name_or_email, author_name, author_email) + # avatar: true will prepend the avatar image + # size: size of the avatar image in px + def author_link(options = {}) + person_link(options.merge source: :author) + end - if team_member.nil? - h.mail_to author_email, text.html_safe, class: "commit-author-link" - else - h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-author-link" - end + # Just like #author_link but for the committer. + def committer_link(options = {}) + person_link(options.merge source: :committer) end protected @@ -69,4 +63,30 @@ class CommitDecorator < ApplicationDecorator def no_commit_message "--no commit message" end + + # Private: Returns a link to a person. If the person has a matching user and + # is a member of the current @project it will link to the team member page. + # Otherwise it will link to the person email as specified in the commit. + # + # options: + # source: one of :author or :committer + # avatar: true will prepend the avatar image + # size: size of the avatar image in px + def person_link(options = {}) + source_name = send "#{options[:source]}_name".to_sym + source_email = send "#{options[:source]}_email".to_sym + text = if options[:avatar] + avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size] + %Q{#{avatar} #{source_name}} + else + source_name + end + team_member = @project.try(:team_member_by_name_or_email, source_name, source_email) + + if team_member.nil? + h.mail_to source_email, text.html_safe, class: "commit-#{options[:source]}-link" + else + h.link_to text, h.project_team_member_path(@project, team_member), class: "commit-#{options[:source]}-link" + end + end end From 3d0197246ebd382d1bbfe8501177cef7fd269e7d Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 27 Oct 2012 18:27:47 +0200 Subject: [PATCH 068/122] Use #author_link for blame, commits and tree --- app/views/blame/show.html.haml | 4 +--- app/views/commits/_commit.html.haml | 3 +-- app/views/commits/_commit_box.html.haml | 5 ++--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml index 5c3231e2..29fac7a4 100644 --- a/app/views/blame/show.html.haml +++ b/app/views/blame/show.html.haml @@ -24,9 +24,7 @@ - commit = Commit.new(commit) - commit = CommitDecorator.decorate(commit) %tr - %td.author - = image_tag gravatar_icon(commit.author_email, 16) - = commit.author_name + %td.author= commit.author_link avatar: true, size: 16 %td.blame_commit   %code= link_to commit.short_id, project_commit_path(@project, commit) diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml index 9abadc5d..8e96d16a 100644 --- a/app/views/commits/_commit.html.haml +++ b/app/views/commits/_commit.html.haml @@ -4,9 +4,8 @@ %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right" %p = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" - %strong.commit-author-name= commit.author_name + %strong= commit.author_link avatar: true, size: 24 %span.dash – - = image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16 = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title" %span.committed_ago diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commits/_commit_box.html.haml index ece0df22..26753a14 100644 --- a/app/views/commits/_commit_box.html.haml +++ b/app/views/commits/_commit_box.html.haml @@ -18,16 +18,15 @@ .commit-info .row .span5 - = image_tag gravatar_icon(@commit.author_email, 40), class: "avatar" .author - %strong= @commit.author_name + %strong= @commit.author_link avatar: true, size: 40 authored %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")} #{time_ago_in_words(@commit.authored_date)} ago - if @commit.different_committer? .committer → - %strong= @commit.committer_name + %strong= @commit.committer_link committed %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")} #{time_ago_in_words(@commit.committed_date)} ago From 646bad43e97482333648522917aefc83b69e2e9a Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Thu, 18 Oct 2012 00:49:20 +0200 Subject: [PATCH 069/122] Fix styles --- app/assets/stylesheets/sections/commits.scss | 10 ++++++++-- app/assets/stylesheets/sections/tree.scss | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index 139d7347..4f9360ad 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -47,12 +47,15 @@ padding-left: 32px; } - .author, - .committer { + .author a, + .committer a { font-size:14px; line-height:22px; text-shadow:0 1px 1px #fff; color:#777; + &:hover { + color: #999; + } } .avatar { @@ -227,6 +230,9 @@ .commit-author-name { color: #777; + &:hover { + color: #999; + } } } diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss index e7d20874..f6bdb0f3 100644 --- a/app/assets/stylesheets/sections/tree.scss +++ b/app/assets/stylesheets/sections/tree.scss @@ -72,6 +72,15 @@ } } } + + .blame { + img.avatar { + border: 0 none; + float: none; + margin: 0; + padding: 0; + } + } } .tree-btn-group { From 263282dec926451d2db39162c99d479277a52e72 Mon Sep 17 00:00:00 2001 From: Sergio Visinoni Date: Sun, 28 Oct 2012 09:22:03 +0100 Subject: [PATCH 070/122] Show Milestone information in MR Listing When a MR belongs to a Milestone, show this information in the listing with a small box telling the Milestone title. --- app/views/merge_requests/_merge_request.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml index 419419d2..ed8ffc0b 100644 --- a/app/views/merge_requests/_merge_request.html.haml +++ b/app/views/merge_requests/_merge_request.html.haml @@ -10,6 +10,10 @@ %span.btn.small.disabled.grouped %i.icon-comment = merge_request.mr_and_commit_notes.count + - if merge_request.milestone_id? + %span.btn.small.disabled.grouped + %i.icon-time + = merge_request.project.milestones.find(merge_request.milestone_id).title %span.btn.small.disabled.grouped = merge_request.source_branch → From d4e070cfadcccfe503402dd5d0524ca102d372d4 Mon Sep 17 00:00:00 2001 From: randx Date: Mon, 29 Oct 2012 22:40:00 +0200 Subject: [PATCH 071/122] Improve styles. Add merge request completness to milestone percentage --- app/assets/stylesheets/common.scss | 5 ++++ app/contexts/merge_requests_load_context.rb | 18 ++++++++------ app/models/milestone.rb | 10 +++++++- app/views/milestones/_milestone.html.haml | 27 ++++++++++----------- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 8ebbb53b..dfb43697 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -670,3 +670,8 @@ pre { padding:0; } } + +.milestone .progress { + margin-bottom: 0; + margin-top:4px; +} diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb index 45adb110..4ec66cd9 100644 --- a/app/contexts/merge_requests_load_context.rb +++ b/app/contexts/merge_requests_load_context.rb @@ -1,29 +1,31 @@ +# Build collection of Merge Requests +# based on filtering passed via params for @project class MergeRequestsLoadContext < BaseContext def execute type = params[:f] - merge_requests = @project.merge_requests + merge_requests = project.merge_requests merge_requests = case type when 'all' then merge_requests when 'closed' then merge_requests.closed when 'assigned-to-me' then merge_requests.opened.assigned(current_user) else merge_requests.opened - end.page(params[:page]).per(20) + end - merge_requests.includes(:author, :project).order("closed, created_at desc") - - @merge_requests = merge_requests + merge_requests = merge_requests.page(params[:page]).per(20) + merge_requests = merge_requests.includes(:author, :project).order("closed, created_at desc") # Filter by specific assignee_id (or lack thereof)? if params[:assignee_id].present? - @merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) + merge_requests = merge_requests.where(assignee_id: (params[:assignee_id] == '0' ? nil : params[:assignee_id])) end # Filter by specific milestone_id (or lack thereof)? if params[:milestone_id].present? - @merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) + merge_requests = merge_requests.where(milestone_id: (params[:milestone_id] == '0' ? nil : params[:milestone_id])) end - @merge_requests + + merge_requests end end diff --git a/app/models/milestone.rb b/app/models/milestone.rb index b924dc5f..233270ed 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -16,8 +16,16 @@ class Milestone < ActiveRecord::Base User.where(id: issues.pluck(:assignee_id)) end - def percent_complete + def issues_percent_complete ((self.issues.closed.count * 100) / self.issues.count).abs + end + + def merge_requests_percent_complete + ((self.merge_requests.closed.count * 100) / self.merge_requests.count).abs + end + + def percent_complete + (issues_percent_complete + merge_requests_percent_complete) / 2 rescue ZeroDivisionError 100 end diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 3ccd9360..2bb78975 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -1,22 +1,21 @@ %li{class: "milestone", id: dom_id(milestone) } .right - - if milestone.issues.any? - %span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'issues' - - if milestone.issues.count > 0 - = link_to 'Browse Issues', project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped" - - if milestone.merge_requests.any? - %span.btn.small.disabled.grouped= pluralize milestone.issues.count, 'Merge Requests' - - if milestone.merge_requests.count > 0 - = link_to 'Browse Merge Requests', project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "btn small grouped" - if can? current_user, :admin_milestone, milestone.project - = link_to 'Edit', edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" + = link_to edit_project_milestone_path(milestone.project, milestone), class: "btn small edit-milestone-link grouped" do + %i.icon-edit + Edit %h4 - = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone), class: "row_title" + = link_to_gfm truncate(milestone.title, length: 100), project_milestone_path(milestone.project, milestone) %small = milestone.expires_at - %br - .progress.progress-success.span3 + .row + .progress.progress-success.span4 .bar{style: "width: #{milestone.percent_complete}%;"} + .span6 + - if milestone.issues.any? + = link_to project_issues_path(milestone.project, milestone_id: milestone.id), class: "padded" do + %strong= pluralize milestone.issues.count, 'Issue' - -   + - if milestone.merge_requests.any? + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "padded" do + %strong= pluralize milestone.issues.count, 'Merge Request' From 0a9adbbe4a049e0af405feb1e5ce80b28bbbd292 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Mon, 29 Oct 2012 21:51:28 +0100 Subject: [PATCH 072/122] Fix no SSH key warning --- app/views/shared/_no_ssh.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml index b6ab666b..c2d00654 100644 --- a/app/views/shared/_no_ssh.html.haml +++ b/app/views/shared/_no_ssh.html.haml @@ -1,8 +1,8 @@ - if current_user.require_ssh_key? %h6.error_message %span - You wont be able to pull/push project code unless you + You won't be able to pull or push project code until you %strong = link_to new_key_path, class: "vlink" do - add SSH key + add a SSH key to your profile From f417a265d7783cb10e4b55556f5de9fd0a7c9696 Mon Sep 17 00:00:00 2001 From: randx Date: Mon, 29 Oct 2012 23:45:11 +0200 Subject: [PATCH 073/122] Finalize milestones for Merge Requests --- app/assets/javascripts/milestones.js.coffee | 7 +++++ app/assets/stylesheets/common.scss | 8 ++++++ app/controllers/milestones_controller.rb | 2 +- app/decorators/user_decorator.rb | 11 ++++++++ app/helpers/projects_helper.rb | 4 +++ app/models/merge_request.rb | 1 + app/models/milestone.rb | 14 ++++++---- app/views/milestones/_milestone.html.haml | 6 ++--- app/views/milestones/show.html.haml | 29 +++++++++------------ 9 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 app/decorators/user_decorator.rb diff --git a/app/assets/javascripts/milestones.js.coffee b/app/assets/javascripts/milestones.js.coffee index 13aba860..e40a69eb 100644 --- a/app/assets/javascripts/milestones.js.coffee +++ b/app/assets/javascripts/milestones.js.coffee @@ -5,3 +5,10 @@ $ -> $('.milestone-issue-filter li').toggleClass('active') $('.milestone-issue-filter tr[data-closed]').toggleClass('hide') false + + $('.milestone-merge-requests-filter tr[data-closed]').addClass('hide') + + $('.milestone-merge-requests-filter ul.nav li a').click -> + $('.milestone-merge-requests-filter li').toggleClass('active') + $('.milestone-merge-requests-filter tr[data-closed]').toggleClass('hide') + false diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index dfb43697..843b683f 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -675,3 +675,11 @@ pre { margin-bottom: 0; margin-top:4px; } + +.float-link { + float:left; + margin-right:15px; + .s16 { + margin-right:5px; + } +} diff --git a/app/controllers/milestones_controller.rb b/app/controllers/milestones_controller.rb index ac28f000..fadfee2d 100644 --- a/app/controllers/milestones_controller.rb +++ b/app/controllers/milestones_controller.rb @@ -31,7 +31,7 @@ class MilestonesController < ProjectResourceController def show @issues = @milestone.issues - @users = @milestone.participants + @users = UserDecorator.decorate(@milestone.participants) @merge_requests = @milestone.merge_requests respond_to do |format| diff --git a/app/decorators/user_decorator.rb b/app/decorators/user_decorator.rb new file mode 100644 index 00000000..af9c6a63 --- /dev/null +++ b/app/decorators/user_decorator.rb @@ -0,0 +1,11 @@ +class UserDecorator < ApplicationDecorator + decorates :user + + def avatar_image size = 16 + h.image_tag h.gravatar_icon(self.email, size), class: "avatar #{"s#{size}"}", width: size + end + + def tm_of(project) + project.team_member_by_id(self.id) + end +end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 468ace15..7c302ef4 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -10,5 +10,9 @@ module ProjectsHelper def link_to_project project link_to project.name, project end + + def tm_path team_member + project_team_member_path(@project, team_member) + end end diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 7dc00958..c737258d 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1,4 +1,5 @@ require Rails.root.join("app/models/commit") +require Rails.root.join("app/roles/static_model") class MergeRequest < ActiveRecord::Base include IssueCommonality diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 233270ed..41412a13 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -16,16 +16,20 @@ class Milestone < ActiveRecord::Base User.where(id: issues.pluck(:assignee_id)) end - def issues_percent_complete - ((self.issues.closed.count * 100) / self.issues.count).abs + def open_items_count + self.issues.opened.count + self.merge_requests.opened.count end - def merge_requests_percent_complete - ((self.merge_requests.closed.count * 100) / self.merge_requests.count).abs + def closed_items_count + self.issues.closed.count + self.merge_requests.closed.count + end + + def total_items_count + self.issues.count + self.merge_requests.count end def percent_complete - (issues_percent_complete + merge_requests_percent_complete) / 2 + ((closed_items_count * 100) / total_items_count).abs rescue ZeroDivisionError 100 end diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 2bb78975..05532c38 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -9,13 +9,13 @@ %small = milestone.expires_at .row - .progress.progress-success.span4 + .progress.progress-info.span4 .bar{style: "width: #{milestone.percent_complete}%;"} .span6 - if milestone.issues.any? - = link_to project_issues_path(milestone.project, milestone_id: milestone.id), class: "padded" do + = link_to project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn very_small" do %strong= pluralize milestone.issues.count, 'Issue' - if milestone.merge_requests.any? - = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "padded" do + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "btn very_small" do %strong= pluralize milestone.issues.count, 'Merge Request' diff --git a/app/views/milestones/show.html.haml b/app/views/milestones/show.html.haml index ad4580d4..b8bc788c 100644 --- a/app/views/milestones/show.html.haml +++ b/app/views/milestones/show.html.haml @@ -31,10 +31,10 @@ %h5 Progress: %small - #{@milestone.issues.closed.count} closed + #{@milestone.closed_items_count} closed – - #{@milestone.issues.opened.count} open - .progress.progress-success + #{@milestone.open_items_count} open + .progress.progress-info .bar{style: "width: #{@milestone.percent_complete}%;"} @@ -58,10 +58,9 @@ %span.badge.badge-info ##{issue.id} – = link_to_gfm truncate(issue.title, length: 60), [@project, issue] - %br .span6 - %table.milestone-merge_requests-filter + %table.milestone-merge-requests-filter %thead %th %ul.nav.nav-pills @@ -74,15 +73,13 @@ %span.badge.badge-info ##{merge_request.id} – = link_to_gfm truncate(merge_request.title, length: 60), [@project, merge_request] - %br - .span6 - %table - %thead - %th Participants - - @users.each do |user| - %tr - %td - = image_tag gravatar_icon(user.email, 24), width: "24" -   - = user.name +%hr +%h6 Participants: +%div + - @users.each do |user| + = link_to tm_path(user.tm_of(@project)), class: 'float-link' do + = user.avatar_image + = user.name + +.clearfix From a8398e5124fe14d211e2c1aaadb5109cfa1d7b8c Mon Sep 17 00:00:00 2001 From: randx Date: Mon, 29 Oct 2012 23:50:35 +0200 Subject: [PATCH 074/122] Fix merge request count for milestone index --- app/views/milestones/_milestone.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 05532c38..0d57cb58 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -18,4 +18,4 @@ - if milestone.merge_requests.any? = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "btn very_small" do - %strong= pluralize milestone.issues.count, 'Merge Request' + %strong= pluralize milestone.merge_requests.count, 'Merge Request' From 9d56c7f6571bf2c4d8650cb07d070f90b79a6c5e Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Tue, 30 Oct 2012 00:29:13 +0200 Subject: [PATCH 075/122] Update app/views/shared/_no_ssh.html.haml TYPO --- app/views/shared/_no_ssh.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml index c2d00654..a11f2bc4 100644 --- a/app/views/shared/_no_ssh.html.haml +++ b/app/views/shared/_no_ssh.html.haml @@ -4,5 +4,5 @@ You won't be able to pull or push project code until you %strong = link_to new_key_path, class: "vlink" do - add a SSH key + add an SSH key to your profile From 53a3be03fc5a118991eb3903c1e763135187ef3c Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Tue, 30 Oct 2012 00:32:32 +0200 Subject: [PATCH 076/122] Update app/views/profile/account.html.haml TYPO #1870 --- app/views/profile/account.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/profile/account.html.haml b/app/views/profile/account.html.haml index 6707a8ff..112963cc 100644 --- a/app/views/profile/account.html.haml +++ b/app/views/profile/account.html.haml @@ -14,7 +14,7 @@ %h3.page_title Private token %span.cred.right - keep it in secret! + keep it secret! .padded = form_for @user, url: profile_reset_private_token_path, method: :put do |f| .data From e4cf99db4615f406dfc60bfc8bca473581b4f910 Mon Sep 17 00:00:00 2001 From: randx Date: Tue, 30 Oct 2012 09:22:24 +0200 Subject: [PATCH 077/122] Refactor milestones related functionality. Added seeds for Milestine and MR --- app/models/issue.rb | 2 -- app/models/merge_request.rb | 2 -- app/roles/issue_commonality.rb | 1 + .../merge_requests/_merge_request.html.haml | 2 +- app/views/milestones/_milestone.html.haml | 10 +++++----- db/fixtures/development/007_milestones.rb | 13 +++++++++++++ db/fixtures/development/008_merge_requests.rb | 19 +++++++++++++++++++ 7 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 db/fixtures/development/007_milestones.rb create mode 100644 db/fixtures/development/008_merge_requests.rb diff --git a/app/models/issue.rb b/app/models/issue.rb index 3dd1c8c8..1acdfdd3 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -7,8 +7,6 @@ class Issue < ActiveRecord::Base acts_as_taggable_on :labels - belongs_to :milestone - validates :description, length: { within: 0..2000 } def self.open_for(user) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index c737258d..16e13db7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -10,8 +10,6 @@ class MergeRequest < ActiveRecord::Base attr_accessor :should_remove_source_branch - belongs_to :milestone - BROKEN_DIFF = "--broken-diff" UNCHECKED = 1 diff --git a/app/roles/issue_commonality.rb b/app/roles/issue_commonality.rb index 2d10bfec..79831cdc 100644 --- a/app/roles/issue_commonality.rb +++ b/app/roles/issue_commonality.rb @@ -6,6 +6,7 @@ module IssueCommonality belongs_to :project belongs_to :author, class_name: "User" belongs_to :assignee, class_name: "User" + belongs_to :milestone has_many :notes, as: :noteable, dependent: :destroy validates :project, presence: true diff --git a/app/views/merge_requests/_merge_request.html.haml b/app/views/merge_requests/_merge_request.html.haml index ed8ffc0b..4f68c5f2 100644 --- a/app/views/merge_requests/_merge_request.html.haml +++ b/app/views/merge_requests/_merge_request.html.haml @@ -13,7 +13,7 @@ - if merge_request.milestone_id? %span.btn.small.disabled.grouped %i.icon-time - = merge_request.project.milestones.find(merge_request.milestone_id).title + = merge_request.milestone.title %span.btn.small.disabled.grouped = merge_request.source_branch → diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index 0d57cb58..c28fb186 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -13,9 +13,9 @@ .bar{style: "width: #{milestone.percent_complete}%;"} .span6 - if milestone.issues.any? - = link_to project_issues_path(milestone.project, milestone_id: milestone.id), class: "btn very_small" do - %strong= pluralize milestone.issues.count, 'Issue' - + = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.issues.count, 'Issue' +   - if milestone.merge_requests.any? - = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id), class: "btn very_small" do - %strong= pluralize milestone.merge_requests.count, 'Merge Request' + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.merge_requests.count, 'Merge Request' diff --git a/db/fixtures/development/007_milestones.rb b/db/fixtures/development/007_milestones.rb new file mode 100644 index 00000000..a77f619f --- /dev/null +++ b/db/fixtures/development/007_milestones.rb @@ -0,0 +1,13 @@ +Milestone.seed(:id, [ + { :id => 1, :project_id => 1, :title => 'v' + Faker::Address.zip_code }, + { :id => 2, :project_id => 1, :title => 'v' + Faker::Address.zip_code }, + { :id => 3, :project_id => 1, :title => 'v' + Faker::Address.zip_code }, + { :id => 4, :project_id => 2, :title => 'v' + Faker::Address.zip_code }, + { :id => 5, :project_id => 2, :title => 'v' + Faker::Address.zip_code }, + + { :id => 6, :project_id => 2, :title => 'v' + Faker::Address.zip_code }, + { :id => 7, :project_id => 2, :title => 'v' + Faker::Address.zip_code }, + { :id => 8, :project_id => 3, :title => 'v' + Faker::Address.zip_code }, + { :id => 9, :project_id => 3, :title => 'v' + Faker::Address.zip_code }, + { :id => 11, :project_id => 3, :title => 'v' + Faker::Address.zip_code }, +]) diff --git a/db/fixtures/development/008_merge_requests.rb b/db/fixtures/development/008_merge_requests.rb new file mode 100644 index 00000000..6e0d67c4 --- /dev/null +++ b/db/fixtures/development/008_merge_requests.rb @@ -0,0 +1,19 @@ +MergeRequest.seed(:id, [ + { :id => 1, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6) }, + { :id => 2, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6) }, + { :id => 3, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6) }, + { :id => 4, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6) }, + { :id => 5, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6) }, + + { :id => 6, milestone_id: 5, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6) }, + { :id => 7, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6) }, + { :id => 8, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6) }, + { :id => 9, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6) }, + { :id => 11, milestone_id: 5, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6) }, + + { :id => 12, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6)}, + { :id => 13, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6)}, + { :id => 14, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6)}, + { :id => 15, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6)}, + { :id => 16, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6)}, +]) From 36dbac2fd90c12a74781c9982db8f18bae938265 Mon Sep 17 00:00:00 2001 From: randx Date: Tue, 30 Oct 2012 10:03:21 +0200 Subject: [PATCH 078/122] More seeds --- app/views/milestones/_milestone.html.haml | 17 ++++---- db/fixtures/development/005_issues.rb | 40 ------------------- .../{007_milestones.rb => 005_milestones.rb} | 0 db/fixtures/development/007_issues.rb | 20 ++++++++++ db/fixtures/development/008_merge_requests.rb | 37 +++++++++-------- 5 files changed, 49 insertions(+), 65 deletions(-) delete mode 100644 db/fixtures/development/005_issues.rb rename db/fixtures/development/{007_milestones.rb => 005_milestones.rb} (100%) create mode 100644 db/fixtures/development/007_issues.rb diff --git a/app/views/milestones/_milestone.html.haml b/app/views/milestones/_milestone.html.haml index c28fb186..7c4c0e67 100644 --- a/app/views/milestones/_milestone.html.haml +++ b/app/views/milestones/_milestone.html.haml @@ -9,13 +9,14 @@ %small = milestone.expires_at .row - .progress.progress-info.span4 - .bar{style: "width: #{milestone.percent_complete}%;"} + .span4 + .progress.progress-info + .bar{style: "width: #{milestone.percent_complete}%;"} .span6 - - if milestone.issues.any? - = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do - = pluralize milestone.issues.count, 'Issue' + = link_to project_issues_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.issues.count, 'Issue'   - - if milestone.merge_requests.any? - = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do - = pluralize milestone.merge_requests.count, 'Merge Request' + = link_to project_merge_requests_path(milestone.project, milestone_id: milestone.id) do + = pluralize milestone.merge_requests.count, 'Merge Request' +   + %span.light #{milestone.percent_complete}% complete diff --git a/db/fixtures/development/005_issues.rb b/db/fixtures/development/005_issues.rb deleted file mode 100644 index 32375387..00000000 --- a/db/fixtures/development/005_issues.rb +++ /dev/null @@ -1,40 +0,0 @@ -Issue.seed(:id, [ - { :id => 1, :project_id => 1, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6) }, - { :id => 2, :project_id => 1, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6) }, - { :id => 3, :project_id => 1, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6) }, - { :id => 4, :project_id => 1, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6) }, - { :id => 5, :project_id => 1, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6) }, - - { :id => 6, :project_id => 2, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6) }, - { :id => 7, :project_id => 2, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6) }, - { :id => 8, :project_id => 2, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6) }, - { :id => 9, :project_id => 2, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6) }, - { :id => 11, :project_id => 2, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6) }, - - { :id => 12, :project_id => 3, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6)}, - { :id => 13, :project_id => 3, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6)}, - { :id => 14, :project_id => 3, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6)}, - { :id => 15, :project_id => 3, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6)}, - { :id => 16, :project_id => 3, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6)}, - - { :id => 21, :project_id => 1, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6) }, - { :id => 22, :project_id => 1, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6) }, - { :id => 23, :project_id => 1, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6) }, - { :id => 24, :project_id => 1, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6) }, - { :id => 25, :project_id => 1, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6) }, - - { :id => 26, :project_id => 2, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6) }, - { :id => 27, :project_id => 2, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6) }, - { :id => 28, :project_id => 2, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6) }, - { :id => 29, :project_id => 2, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6) }, - { :id => 30, :project_id => 2, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6) }, - - { :id => 32, :project_id => 3, :author_id => 1, :assignee_id => 1, :title => Faker::Lorem.sentence(6)}, - { :id => 33, :project_id => 3, :author_id => 2, :assignee_id => 2, :title => Faker::Lorem.sentence(6)}, - { :id => 34, :project_id => 3, :author_id => 3, :assignee_id => 3, :title => Faker::Lorem.sentence(6)}, - { :id => 35, :project_id => 3, :author_id => 4, :assignee_id => 4, :title => Faker::Lorem.sentence(6)}, - { :id => 36, :project_id => 3, :author_id => 5, :assignee_id => 5, :title => Faker::Lorem.sentence(6)} -]) - - - diff --git a/db/fixtures/development/007_milestones.rb b/db/fixtures/development/005_milestones.rb similarity index 100% rename from db/fixtures/development/007_milestones.rb rename to db/fixtures/development/005_milestones.rb diff --git a/db/fixtures/development/007_issues.rb b/db/fixtures/development/007_issues.rb new file mode 100644 index 00000000..d60af71e --- /dev/null +++ b/db/fixtures/development/007_issues.rb @@ -0,0 +1,20 @@ +(1..300).each do |i| + # Random Project + project_id = rand(2) + 1 + project = Project.find(project_id) + + # Random user + user = project.users.sample + user_id = user.id + IssueObserver.current_user = user + + Issue.seed(:id, [{ + id: i, + project_id: project_id, + author_id: user_id, + assignee_id: user_id, + closed: [true, false].sample, + milestone: project.milestones.sample, + title: Faker::Lorem.sentence(6) + }]) +end diff --git a/db/fixtures/development/008_merge_requests.rb b/db/fixtures/development/008_merge_requests.rb index 6e0d67c4..8d20e628 100644 --- a/db/fixtures/development/008_merge_requests.rb +++ b/db/fixtures/development/008_merge_requests.rb @@ -1,19 +1,22 @@ -MergeRequest.seed(:id, [ - { :id => 1, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6) }, - { :id => 2, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6) }, - { :id => 3, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6) }, - { :id => 4, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6) }, - { :id => 5, milestone_id: 1, project_id: 1, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6) }, +(1..300).each do |i| + # Random Project + project_id = rand(2) + 1 + project = Project.find(project_id) - { :id => 6, milestone_id: 5, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6) }, - { :id => 7, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6) }, - { :id => 8, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6) }, - { :id => 9, milestone_id: 6, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6) }, - { :id => 11, milestone_id: 5, project_id: 2, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6) }, + # Random user + user = project.users.sample + user_id = user.id + MergeRequestObserver.current_user = user - { :id => 12, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 1, assignee_id: 1, title: Faker::Lorem.sentence(6)}, - { :id => 13, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 2, assignee_id: 2, title: Faker::Lorem.sentence(6)}, - { :id => 14, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 3, assignee_id: 3, title: Faker::Lorem.sentence(6)}, - { :id => 15, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 4, assignee_id: 4, title: Faker::Lorem.sentence(6)}, - { :id => 16, milestone_id: 9, project_id: 3, source_branch: 'master', target_branch: 'feature', author_id: 5, assignee_id: 5, title: Faker::Lorem.sentence(6)}, -]) + MergeRequest.seed(:id, [{ + id: i, + source_branch: 'master', + target_branch: 'feature', + project_id: project_id, + author_id: user_id, + assignee_id: user_id, + closed: [true, false].sample, + milestone: project.milestones.sample, + title: Faker::Lorem.sentence(6) + }]) +end From 37e39e4176757019fb6e9d437b86229497e63b57 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 30 Oct 2012 13:04:56 +0200 Subject: [PATCH 079/122] Added bare import script. Removed old unworking script --- lib/tasks/bulk_import.rake | 83 ------------------------------------ lib/tasks/gitlab/import.rake | 54 +++++++++++++++++++++++ 2 files changed, 54 insertions(+), 83 deletions(-) delete mode 100644 lib/tasks/bulk_import.rake create mode 100644 lib/tasks/gitlab/import.rake diff --git a/lib/tasks/bulk_import.rake b/lib/tasks/bulk_import.rake deleted file mode 100644 index 914f920a..00000000 --- a/lib/tasks/bulk_import.rake +++ /dev/null @@ -1,83 +0,0 @@ -desc "Imports existing Git repos from a directory into new projects in git_base_path" -task :import_projects, [:directory,:email] => :environment do |t, args| - user_email, import_directory = args.email, args.directory - repos_to_import = Dir.glob("#{import_directory}/*") - git_base_path = Gitlab.config.git_base_path - imported_count, skipped_count, failed_count = 0 - - puts "Found #{repos_to_import.size} repos to import" - - repos_to_import.each do |repo_path| - repo_name = File.basename repo_path - clone_path = "#{git_base_path}#{repo_name}.git" - - puts " Processing #{repo_name}" - - if Dir.exists? clone_path - if Project.find_by_code(repo_name) - puts " INFO: #{clone_path} already exists in repositories directory, skipping." - skipped_count += 1 - next - else - puts " INFO: Project doesn't exist for #{repo_name} (but the repo does)." - end - else - # Clone the repo - unless clone_bare_repo_as_git(repo_path, clone_path) - failed_count += 1 - next - end - end - - # Create the project and repo - if create_repo_project(repo_name, user_email) - imported_count += 1 - else - failed_count += 1 - end - end - - puts "Finished importing #{imported_count} projects (skipped #{skipped_count}, failed #{failed_count})." -end - -# Clones a repo as bare git repo using the git_user -def clone_bare_repo_as_git(existing_path, new_path) - git_user = Gitlab.config.ssh_user - begin - sh "sudo -u #{git_user} -i git clone --bare '#{existing_path}' #{new_path}" - rescue Exception => msg - puts " ERROR: Failed to clone #{existing_path} to #{new_path}" - puts " Make sure #{git_user} can reach #{existing_path}" - puts " Exception-MSG: #{msg}" - end -end - -# Creates a project in GitLab given a `project_name` to use -# (for name, web url, and code url) and a `user_email` that will be -# assigned as the owner of the project. -def create_repo_project(project_name, user_email) - if user = User.find_by_email(user_email) - # Using find_by_code since that's the most important identifer to be unique - if Project.find_by_code(project_name) - puts " INFO: Project #{project_name} already exists in Gitlab, skipping." - else - project = Project.create( - name: project_name, - code: project_name, - path: project_name, - owner: user, - description: "Automatically created from 'import_projects' rake task on #{Time.now}" - ) - - if project.valid? - # Add user as admin for project - project.users_projects.create!(:project_access => UsersProject::MASTER, :user => user) - project.update_repository - else - puts " ERROR: Failed to create project #{project} because #{project.errors.first}" - end - end - else - puts " ERROR: user with #{user_email} not found, skipping" - end -end diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake new file mode 100644 index 00000000..09f0dc9e --- /dev/null +++ b/lib/tasks/gitlab/import.rake @@ -0,0 +1,54 @@ +namespace :gitlab do + namespace :import do + # How to use: + # + # 1. copy your bare repos under git base_path + # 2. run bundle exec rake gitlab:import:repos RAILS_ENV=production + # + # Notes: + # * project owner will be a first admin + # * existing projects will be skipped + # + desc "GITLAB | Import bare repositories from git_host -> base_path into GitLab project instance" + task :repos => :environment do + + git_base_path = Gitlab.config.git_base_path + repos_to_import = Dir.glob(git_base_path + '/*') + + repos_to_import.each do |repo_path| + repo_name = File.basename repo_path + + # skip gitolite admin + next if repo_name == 'gitolite-admin.git' + + path = repo_name.sub(/\.git$/, '') + + project = Project.find_by_path(path) + + puts "Processing #{repo_name}".yellow + + if project + puts " * #{project.name} (#{repo_name}) exists" + else + user = User.admins.first + + project_params = { + :name => path, + :code => path, + :path => path, + } + + project = Project.create_by_user(project_params, user) + + if project.valid? + puts " * Created #{project.name} (#{repo_name})".green + else + puts " * Failed trying to create #{project.name} (#{repo_name})".red + end + end + end + + puts "Done!".green + end + end +end From 8272e18e57fd93e9adac789353a5b3640d781041 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 30 Oct 2012 13:27:15 +0200 Subject: [PATCH 080/122] Project path validation: array of not allowed paths --- app/models/project.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 53fe0ee1..5b59f227 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -104,8 +104,10 @@ class Project < ActiveRecord::Base end def repo_name - if path == "gitolite-admin" - errors.add(:path, " like 'gitolite-admin' is not allowed") + denied_paths = %w(gitolite-admin groups projects dashboard) + + if denied_paths.include?(path) + errors.add(:path, "like #{path} is not allowed") end end From 404040d7ae01d1542acc998d6dd4467fb7f049c4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 30 Oct 2012 13:35:57 +0200 Subject: [PATCH 081/122] Fix invalid template path for huge commit --- app/views/{commits => commit}/huge_commit.html.haml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/views/{commits => commit}/huge_commit.html.haml (100%) diff --git a/app/views/commits/huge_commit.html.haml b/app/views/commit/huge_commit.html.haml similarity index 100% rename from app/views/commits/huge_commit.html.haml rename to app/views/commit/huge_commit.html.haml From 1d15586fee7b3bcb773db702e571b2453d107aca Mon Sep 17 00:00:00 2001 From: Mike TUMS Date: Tue, 30 Oct 2012 15:58:10 +0400 Subject: [PATCH 082/122] Update doc/install/databases.md Update docs for PostgreSQL installation --- doc/install/databases.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/install/databases.md b/doc/install/databases.md index fd87eee4..b7beff26 100644 --- a/doc/install/databases.md +++ b/doc/install/databases.md @@ -26,7 +26,7 @@ GitLab use mysql as default database but you are free to use PostgreSQL or SQLit ## PostgreSQL - sudo apt-get install -y postgresql-9.2 postgresql-server-dev-9.2 + sudo apt-get install -y postgresql-9.1 postgresql-server-dev-9.1 # Connect to database server sudo -u postgres psql -d template1 @@ -34,18 +34,14 @@ GitLab use mysql as default database but you are free to use PostgreSQL or SQLit # Add a user called gitlab. Change $password to a real password template1=# CREATE USER gitlab WITH PASSWORD '$password'; - # Create the GitLab production database - template1=# CREATE DATABASE IF NOT EXISTS gitlabhq_production; - - # Grant all privileges on database - template1=# GRANT ALL PRIVILEGES ON DATABASE gitlabhq_production to gitlab; + # Create the GitLab production database & grant all privileges on database + template1=# CREATE DATABASE gitlabhq_production OWNER gitlab; # Quit from PostgreSQL server template1=# \q # Try connect to new database - $ su - gitlab - $ psql -d gitlabhq_production -U gitlab + sudo -u gitlab psql -d gitlabhq_production From b6fc0310316eb61f68551a3b37f340b0fb4d0b20 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 31 Oct 2012 13:53:38 +0200 Subject: [PATCH 083/122] Update Gemfile with 1.9 syntax. Define ref for forks --- Gemfile | 26 +++++++++++++------------- Gemfile.lock | 2 ++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index 65c69e7e..95070221 100644 --- a/Gemfile +++ b/Gemfile @@ -11,9 +11,9 @@ end gem "rails", "3.2.8" # Supported DBs -gem "sqlite3", :group => :sqlite -gem "mysql2", :group => :mysql -gem "pg", :group => :postgres +gem "sqlite3", group: :sqlite +gem "mysql2", group: :mysql +gem "pg", group: :postgres # Auth gem "devise", "~> 2.1.0" @@ -23,10 +23,10 @@ gem 'omniauth-twitter' gem 'omniauth-github' # GITLAB patched libs -gem "grit", :git => "https://github.com/gitlabhq/grit.git", :ref => "7f35cb98ff17d534a07e3ce6ec3d580f67402837" -gem "omniauth-ldap", :git => "https://github.com/gitlabhq/omniauth-ldap.git", :ref => "f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e" -gem 'yaml_db', :git => "https://github.com/gitlabhq/yaml_db.git" -gem 'grack', :git => "https://github.com/gitlabhq/grack.git" +gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837' +gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e' +gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd' +gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8' # Gitolite client (for work with gitolite-admin repo) gem "gitolite", '1.1.0' @@ -35,7 +35,7 @@ gem "gitolite", '1.1.0' gem "pygments.rb", "0.3.1" # Language detection -gem "github-linguist", "~> 2.3.4" , :require => "linguist" +gem "github-linguist", "~> 2.3.4" , require: "linguist" # API gem "grape", "~> 0.2.1" @@ -115,7 +115,7 @@ end group :development do gem "letter_opener" - gem "annotate", :git => "https://github.com/ctran/annotate_models.git" + gem "annotate", git: "https://github.com/ctran/annotate_models.git" gem 'rack-mini-profiler' end @@ -137,13 +137,13 @@ group :development, :test do gem 'guard-spinach' # Notification - gem 'rb-fsevent', :require => darwin_only('rb-fsevent') - gem 'growl', :require => darwin_only('growl') - gem 'rb-inotify', :require => linux_only('rb-inotify') + gem 'rb-fsevent', require: darwin_only('rb-fsevent') + gem 'growl', require: darwin_only('growl') + gem 'rb-inotify', require: linux_only('rb-inotify') end group :test do - gem "simplecov", :require => false + gem "simplecov", require: false gem "shoulda-matchers" gem 'email_spec' gem 'resque_spec' diff --git a/Gemfile.lock b/Gemfile.lock index 7dd69034..bed83dee 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -7,6 +7,7 @@ GIT GIT remote: https://github.com/gitlabhq/grack.git revision: ba46f3b0845c6a09d488ae6abdce6ede37e227e8 + ref: ba46f3b0845c6a09d488ae6abdce6ede37e227e8 specs: grack (1.0.0) rack (~> 1.4.1) @@ -35,6 +36,7 @@ GIT GIT remote: https://github.com/gitlabhq/yaml_db.git revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd + ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd specs: yaml_db (0.2.2) From d9c20cf5a63dd1f337e408d26eb3f68750dadb75 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 31 Oct 2012 14:29:42 +0200 Subject: [PATCH 084/122] Fix 404 errors on Merge Request -> new --- app/helpers/commits_helper.rb | 5 +++++ app/views/merge_requests/branch_from.js.haml | 2 +- app/views/merge_requests/branch_to.js.haml | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 4b35b0ac..135d002f 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -65,4 +65,9 @@ module CommitsHelper end end + def commit_to_html commit + if commit.model + escape_javascript(render 'commits/commit', commit: commit) + end + end end diff --git a/app/views/merge_requests/branch_from.js.haml b/app/views/merge_requests/branch_from.js.haml index 156b4f0d..0637fdcb 100644 --- a/app/views/merge_requests/branch_from.js.haml +++ b/app/views/merge_requests/branch_from.js.haml @@ -1,2 +1,2 @@ :plain - $(".mr_source_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}"); + $(".mr_source_commit").html("#{commit_to_html(@commit)}"); diff --git a/app/views/merge_requests/branch_to.js.haml b/app/views/merge_requests/branch_to.js.haml index 8a201d42..974100d1 100644 --- a/app/views/merge_requests/branch_to.js.haml +++ b/app/views/merge_requests/branch_to.js.haml @@ -1,3 +1,2 @@ :plain - $(".mr_target_commit").html("#{escape_javascript(render 'commits/commit', commit: @commit)}"); - + $(".mr_target_commit").html("#{commit_to_html(@commit)}"); From 9014fb7525504dedaaca3b586af028455dc4004b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 31 Oct 2012 14:39:05 +0200 Subject: [PATCH 085/122] Init Roadmap --- ROADMAP.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ROADMAP.md diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000..093a23f5 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,19 @@ +## GitLab Roadmap + +### Common + +* Help page for service tasks like repos import, backup etc +* Hide last push widget after following link +* Add comment events +* Dashboard/Project activity events filter + +### Issues + +* labels autocomplete via jquery autocomplete +* Import/Export issues +* Form: Assign to me link right to the selectbox + +### Merge Request + +* CI build status +* Save code fragments with MR comments From 2032f4cd9665d0b4244e30160c64996dc37c0a0e Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 31 Oct 2012 15:22:13 +0200 Subject: [PATCH 086/122] Fix tests fail cause of issue with grit stub --- .../steps/project/project_network_graph.rb | 8 +++----- features/steps/shared/paths.rb | 5 ++--- lib/gitlab/graph_commit.rb | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/features/steps/project/project_network_graph.rb b/features/steps/project/project_network_graph.rb index f34a81a4..e8aadf91 100644 --- a/features/steps/project/project_network_graph.rb +++ b/features/steps/project/project_network_graph.rb @@ -11,12 +11,10 @@ class ProjectNetworkGraph < Spinach::FeatureSteps end And 'I visit project "Shop" network page' do + # Stub GraphCommit max_size to speed up test (10 commits vs. 650) + Gitlab::GraphCommit.stub(max_count: 10) + project = Project.find_by_name("Shop") - - # Stub out find_all to speed this up (10 commits vs. 650) - commits = Grit::Commit.find_all(project.repo, nil, {max_count: 10}) - Grit::Commit.stub(:find_all).and_return(commits) - visit graph_project_path(project) end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index b4e4b810..21936f19 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -122,9 +122,8 @@ module SharedPaths end Given "I visit my project's network page" do - # Stub out find_all to speed this up (10 commits vs. 650) - commits = Grit::Commit.find_all(@project.repo, nil, {max_count: 10}) - Grit::Commit.stub(:find_all).and_return(commits) + # Stub GraphCommit max_size to speed up test (10 commits vs. 650) + Gitlab::GraphCommit.stub(max_count: 10) visit graph_project_path(@project) end diff --git a/lib/gitlab/graph_commit.rb b/lib/gitlab/graph_commit.rb index 188fc422..b1ac1a02 100644 --- a/lib/gitlab/graph_commit.rb +++ b/lib/gitlab/graph_commit.rb @@ -2,18 +2,18 @@ require "grit" module Gitlab class GraphCommit - attr_accessor :time, :space - attr_accessor :refs + attr_accessor :time, :space, :refs include ActionView::Helpers::TagHelper def self.to_graph(project) @repo = project.repo - commits = Grit::Commit.find_all(@repo, nil, {max_count: 650}).dup + + commits = collect_commits(@repo).dup ref_cache = {} - commits.map! {|c| GraphCommit.new(Commit.new(c))} + commits.map! { |commit| GraphCommit.new(Commit.new(commit))} commits.each { |commit| commit.add_refs(ref_cache, @repo) } days = GraphCommit.index_commits(commits) @@ -23,6 +23,16 @@ module Gitlab return @days_json, @commits_json end + # Get commits from repository + # + def self.collect_commits repo + Grit::Commit.find_all(repo, nil, {max_count: self.max_count}) + end + + def self.max_count + @max_count ||= 650 + end + # Method is adding time and space on the # list of commits. As well as returns date list # corelated with time set on commits. From f61ca97648b4438c9177a523214e6332cee32763 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 1 Nov 2012 16:45:31 -0400 Subject: [PATCH 087/122] Add quiet_assets gem, remove initializer --- Gemfile | 3 ++- Gemfile.lock | 3 +++ config/initializers/quite_assets.rb | 13 ------------- 3 files changed, 5 insertions(+), 14 deletions(-) delete mode 100644 config/initializers/quite_assets.rb diff --git a/Gemfile b/Gemfile index 95070221..ff16abad 100644 --- a/Gemfile +++ b/Gemfile @@ -114,8 +114,9 @@ group :assets do end group :development do - gem "letter_opener" gem "annotate", git: "https://github.com/ctran/annotate_models.git" + gem "letter_opener" + gem 'quiet_assets', '1.0.1' gem 'rack-mini-profiler' end diff --git a/Gemfile.lock b/Gemfile.lock index bed83dee..7b21a629 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -262,6 +262,8 @@ GEM posix-spawn (~> 0.3.6) yajl-ruby (~> 1.1.0) pyu-ruby-sasl (0.0.3.3) + quiet_assets (1.0.1) + railties (~> 3.1) rack (1.4.1) rack-cache (1.2) rack (>= 0.4) @@ -456,6 +458,7 @@ DEPENDENCIES pg pry pygments.rb (= 0.3.1) + quiet_assets (= 1.0.1) rack-mini-profiler rails (= 3.2.8) rails-dev-tweaks diff --git a/config/initializers/quite_assets.rb b/config/initializers/quite_assets.rb deleted file mode 100644 index 6fed1803..00000000 --- a/config/initializers/quite_assets.rb +++ /dev/null @@ -1,13 +0,0 @@ -if Rails.env.development? - Rails.application.assets.logger = Logger.new('/dev/null') - Rails::Rack::Logger.class_eval do - def call_with_quiet_assets(env) - previous_level = Rails.logger.level - Rails.logger.level = Logger::ERROR if env['PATH_INFO'] =~ %r{^/assets/} - call_without_quiet_assets(env) - ensure - Rails.logger.level = previous_level - end - alias_method_chain :call, :quiet_assets - end -end From 57e6777b3c3059c96b76776098b8eff4535770d0 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 1 Nov 2012 17:56:39 -0400 Subject: [PATCH 088/122] Remove "remote" attribute from Tree breadcrumb links See https://github.com/gitlabhq/gitlabhq/pull/1665#discussion_r1804447 --- app/decorators/tree_decorator.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb index eb3859a9..c12227af 100644 --- a/app/decorators/tree_decorator.rb +++ b/app/decorators/tree_decorator.rb @@ -8,14 +8,14 @@ class TreeDecorator < ApplicationDecorator #parts = parts[0...-1] if is_blob? - yield(h.link_to("..", "#", remote: true)) if parts.count > max_links + yield(h.link_to("..", "#")) if parts.count > max_links parts.each do |part| part_path = File.join(part_path, part) unless part_path.empty? part_path = part if part_path.empty? next unless parts.last(2).include?(part) if parts.count > max_links - yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: true)) + yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)))) end end end From badb092a2d7e90ccf5358f1e8e6af9c9592351c4 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 1 Nov 2012 17:57:12 -0400 Subject: [PATCH 089/122] Don't initialize Tree History unless tree-slider is present This was breaking breadcrumb links on non-Tree pages --- app/assets/javascripts/tree.js.coffee | 32 +++++++++++++-------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee index 47d49abc..37adef70 100644 --- a/app/assets/javascripts/tree.js.coffee +++ b/app/assets/javascripts/tree.js.coffee @@ -17,23 +17,21 @@ $ -> "ajax:beforeSend": -> $('.tree_progress').addClass("loading") "ajax:complete": -> $('.tree_progress').removeClass("loading") -# Maintain forward/back history while browsing the file tree + # Maintain forward/back history while browsing the file tree + ((window) -> + History = window.History + $ = window.jQuery + document = window.document -((window) -> - History = window.History - $ = window.jQuery - document = window.document + # Check to see if History.js is enabled for our Browser + unless History.enabled + return false - # Check to see if History.js is enabled for our Browser - unless History.enabled - return false + $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) -> + History.pushState(null, null, $(@).attr('href')) + return false - $ -> - $('#tree-slider .tree-item-file-name a, .breadcrumb li > a').live 'click', (e) -> - History.pushState(null, null, $(@).attr('href')) - return false - - History.Adapter.bind window, 'statechange', -> - state = History.getState() - window.ajaxGet(state.url) -)(window) + History.Adapter.bind window, 'statechange', -> + state = History.getState() + window.ajaxGet(state.url) + )(window) From b1be377fb0b5e76fc1b0d78700eb3e714b66f1c2 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 1 Nov 2012 17:57:44 -0400 Subject: [PATCH 090/122] Add Spinach feature for Commit breadcrumbs --- features/project/commits/commits.feature | 4 ++++ features/steps/project/project_browse_commits.rb | 9 +++++++++ features/steps/shared/paths.rb | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature index df795ef7..f5a11048 100644 --- a/features/project/commits/commits.feature +++ b/features/project/commits/commits.feature @@ -19,3 +19,7 @@ Feature: Project Browse commits Given I visit compare refs page And I fill compare fields with refs Then I see compared refs + + Scenario: I browse commits for a specific path + Given I visit my project's commits page for a specific path + Then I see breadcrumb links diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb index cb5cabe9..036b6297 100644 --- a/features/steps/project/project_browse_commits.rb +++ b/features/steps/project/project_browse_commits.rb @@ -42,4 +42,13 @@ class ProjectBrowseCommits < Spinach::FeatureSteps page.should have_content "Commits (1)" page.should have_content "Showing 2 changed files" end + + Then 'I see breadcrumb links' do + page.should have_selector('ul.breadcrumb') + page.should have_selector('ul.breadcrumb span.divider', count: 3) + page.should have_selector('ul.breadcrumb a', count: 4) + + find('ul.breadcrumb li:first a')['href'].should match(/#{@project.path}\/commits\/master\z/) + find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z}) + end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 21936f19..5ce419d3 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -121,6 +121,10 @@ module SharedPaths visit project_commits_path(@project, @project.root_ref, {limit: 5}) end + Given "I visit my project's commits page for a specific path" do + visit project_commits_path(@project, @project.root_ref + "/app/models/project.rb", {limit: 5}) + end + Given "I visit my project's network page" do # Stub GraphCommit max_size to speed up test (10 commits vs. 650) Gitlab::GraphCommit.stub(max_count: 10) From e60185699b0cd34fe3ae37db6db318478232c84b Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Thu, 1 Nov 2012 17:58:13 -0400 Subject: [PATCH 091/122] Add 'breadcrumbs' helper for Commit breadcrumb links Closes #1731 --- app/helpers/tree_helper.rb | 25 +++++++++++++++++++++++++ app/views/commits/show.html.haml | 9 +-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb index 4fe87a25..0f2b695e 100644 --- a/app/helpers/tree_helper.rb +++ b/app/helpers/tree_helper.rb @@ -67,4 +67,29 @@ module TreeHelper can?(current_user, :push_code, @project) end end + + # Breadcrumb links for a Project and, if applicable, a tree path + def breadcrumbs + return unless @project && @ref + + # Add the root project link and the arrow icon + crumbs = content_tag(:li) do + content_tag(:span, nil, class: 'arrow') + + link_to(@project.name, project_commits_path(@project, @ref)) + end + + if @path + parts = @path.split('/') + + parts.each_with_index do |part, i| + crumbs += content_tag(:span, '/', class: 'divider') + crumbs += content_tag(:li) do + # The text is just the individual part, but the link needs all the parts before it + link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/'))) + end + end + end + + crumbs.html_safe + end end diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml index ac063638..9451a038 100644 --- a/app/views/commits/show.html.haml +++ b/app/views/commits/show.html.haml @@ -2,14 +2,7 @@ - if @path.present? %ul.breadcrumb - %li - %span.arrow - = link_to project_commits_path(@project) do - = @project.name - %span.divider - \/ - %li - %a{href: "#"}= @path.split("/").join(" / ") + = breadcrumbs %div{id: dom_id(@project)} #commits_list= render "commits" From 48de0ba867133232d5dc91c39333afd1d936e9bb Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Thu, 1 Nov 2012 23:34:16 +0100 Subject: [PATCH 092/122] Fix source for iframe on Resque admin page --- app/views/admin/resque/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/resque/show.html.haml b/app/views/admin/resque/show.html.haml index 8850e378..41254a6b 100644 --- a/app/views/admin/resque/show.html.haml +++ b/app/views/admin/resque/show.html.haml @@ -1,4 +1,4 @@ %h3.page_title Resque %br .ui-box - %iframe{src: resque_url, width: '100%', height: 600, style: "border: none"} + %iframe{src: resque_path, width: '100%', height: 600, style: "border: none"} From 97bf7ac39799619aa4fb4818678cb01373b72388 Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 4 Nov 2012 16:29:44 -0500 Subject: [PATCH 093/122] Fix double icon on header button hover --- app/assets/stylesheets/themes/ui_mars.scss | 3 --- app/assets/stylesheets/themes/ui_modern.scss | 3 --- 2 files changed, 6 deletions(-) diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss index c630f388..77507569 100644 --- a/app/assets/stylesheets/themes/ui_mars.scss +++ b/app/assets/stylesheets/themes/ui_mars.scss @@ -37,9 +37,6 @@ background-image: -o-linear-gradient(#595D63 6.6%, #202227); background-position:0 0; color:#fff; - i { - @extend .icon-white; - } } border: 1px solid #31363E; diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss index 1f0d7955..8b942149 100644 --- a/app/assets/stylesheets/themes/ui_modern.scss +++ b/app/assets/stylesheets/themes/ui_modern.scss @@ -70,9 +70,6 @@ color:#ccc; &:hover { color:#fff; - i { - @extend .icon-white; - } } border: none; box-shadow:none; From f082c8ae2a12188be6bd1c1e3f1b5b6edca8ebb3 Mon Sep 17 00:00:00 2001 From: randx Date: Sun, 4 Nov 2012 23:43:33 +0200 Subject: [PATCH 094/122] Decouple and refactor GraphCommit --- app/controllers/projects_controller.rb | 6 +- .../steps/project/project_network_graph.rb | 4 +- features/steps/shared/paths.rb | 4 +- lib/gitlab/graph/' | 165 +++++++++++++++ lib/gitlab/graph/commit.rb | 48 +++++ lib/gitlab/graph/json_builder.rb | 172 +++++++++++++++ lib/gitlab/graph_commit.rb | 195 ------------------ 7 files changed, 393 insertions(+), 201 deletions(-) create mode 100644 lib/gitlab/graph/' create mode 100644 lib/gitlab/graph/commit.rb create mode 100644 lib/gitlab/graph/json_builder.rb delete mode 100644 lib/gitlab/graph_commit.rb diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 13b264a4..7d70852f 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -1,4 +1,4 @@ -require Rails.root.join('lib', 'gitlab', 'graph_commit') +require Rails.root.join('lib', 'gitlab', 'graph', 'json_builder') class ProjectsController < ProjectResourceController skip_before_filter :project, only: [:new, :create] @@ -79,7 +79,9 @@ class ProjectsController < ProjectResourceController end def graph - @days_json, @commits_json = Gitlab::GraphCommit.to_graph(project) + graph = Gitlab::Graph::JsonBuilder.new(project) + + @days_json, @commits_json = graph.days_json, graph.commits_json end def destroy diff --git a/features/steps/project/project_network_graph.rb b/features/steps/project/project_network_graph.rb index e8aadf91..6fde532f 100644 --- a/features/steps/project/project_network_graph.rb +++ b/features/steps/project/project_network_graph.rb @@ -11,8 +11,8 @@ class ProjectNetworkGraph < Spinach::FeatureSteps end And 'I visit project "Shop" network page' do - # Stub GraphCommit max_size to speed up test (10 commits vs. 650) - Gitlab::GraphCommit.stub(max_count: 10) + # Stub Graph::JsonBuilder max_size to speed up test (10 commits vs. 650) + Gitlab::Graph::JsonBuilder.stub(max_count: 10) project = Project.find_by_name("Shop") visit graph_project_path(project) diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index 5ce419d3..e2455554 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -126,8 +126,8 @@ module SharedPaths end Given "I visit my project's network page" do - # Stub GraphCommit max_size to speed up test (10 commits vs. 650) - Gitlab::GraphCommit.stub(max_count: 10) + # Stub Graph::JsonBuilder max_size to speed up test (10 commits vs. 650) + Gitlab::Graph::JsonBuilder.stub(max_count: 10) visit graph_project_path(@project) end diff --git a/lib/gitlab/graph/' b/lib/gitlab/graph/' new file mode 100644 index 00000000..2e45c7d6 --- /dev/null +++ b/lib/gitlab/graph/' @@ -0,0 +1,165 @@ +require "grit" + +module Gitlab + module Graph + class JsonBuilder + attr_accessor :max_count, :days, :commits + + def initialize project + @project = project + @repo = project.repo + @commits = collect_commits(@repo).dup + @ref_cache = {} + + @commits.map! { |commit| Graph::Commit.new(Commit.new(commit))} + @commits.each { |commit| commit.add_refs(ref_cache, @repo) } + + days = Graph::Commit.index_commits(@commits) + + return @days_json, @commits_json + end + + def collect_commits + end + + def days_json + @days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json + end + + def commits_json + @commits_json = @commits.map(&:to_graph_hash).to_json + end + + # Get commits from repository + # + def collect_commits repo + Grit::Commit.find_all(repo, nil, {max_count: self.max_count}) + end + + def max_count + @max_count ||= 650 + end + + # Method is adding time and space on the + # list of commits. As well as returns date list + # corelated with time set on commits. + # + # @param [Array] comits to index + # + # @return [Array] list of commit dates corelated with time on commits + def index_commits(commits) + days, heads = [], [] + map = {} + + commits.reverse.each_with_index do |c,i| + c.time = i + days[i] = c.committed_date + map[c.id] = c + heads += c.refs unless c.refs.nil? + end + + heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} + # sort heads so the master is top and current branches are closer + heads.sort! do |a,b| + if a.name == "master" + -1 + elsif b.name == "master" + 1 + else + b.commit.committed_date <=> a.commit.committed_date + end + end + + @_reserved = {} + days.each_index do |i| + @_reserved[i] = [] + end + + heads.each do |h| + if map.include? h.commit.id then + place_chain(map[h.commit.id], map) + end + end + days + end + + # Add space mark on commit and its parents + # + # @param [Graph::Commit] the commit object. + # @param [Hash] map of commits + def place_chain(commit, map, parent_time = nil) + leaves = take_left_leaves(commit, map) + if leaves.empty? then + return + end + space = find_free_space(leaves.last.time..leaves.first.time) + leaves.each{|l| l.space = space} + # and mark it as reserved + min_time = leaves.last.time + parents = leaves.last.parents.collect + parents.each do |p| + if map.include? p.id then + parent = map[p.id] + if parent.time < min_time then + min_time = parent.time + end + end + end + if parent_time.nil? then + max_time = leaves.first.time + else + max_time = parent_time - 1 + end + mark_reserved(min_time..max_time, space) + # Visit branching chains + leaves.each do |l| + parents = l.parents.collect + .select{|p| map.include? p.id and map[p.id].space == 0} + for p in parents + place_chain(map[p.id], map, l.time) + end + end + end + + def mark_reserved(time_range, space) + for day in time_range + @_reserved[day].push(space) + end + end + + def find_free_space(time_range) + reserved = [] + for day in time_range + reserved += @_reserved[day] + end + space = 1 + while reserved.include? space do + space += 1 + end + space + end + + # Takes most left subtree branch of commits + # which don't have space mark yet. + # + # @param [Graph::Commit] the commit object. + # @param [Hash] map of commits + # + # @return [Array] list of branch commits + def take_left_leaves(commit, map) + leaves = [] + leaves.push(commit) if commit.space == 0 + while true + parent = commit.parents.collect + self.select{|p| map.include? p.id and map[p.id].space == 0} + if parent.count == 0 then + return leaves + else + commit = map[parent.first.id] + leaves.push(commit) + end + end + end + end + end +end diff --git a/lib/gitlab/graph/commit.rb b/lib/gitlab/graph/commit.rb new file mode 100644 index 00000000..e26dd4a6 --- /dev/null +++ b/lib/gitlab/graph/commit.rb @@ -0,0 +1,48 @@ +require "grit" + +module Gitlab + module Graph + class Commit + include ActionView::Helpers::TagHelper + + attr_accessor :time, :space, :refs + + def initialize(commit) + @_commit = commit + @time = -1 + @space = 0 + end + + def method_missing(m, *args, &block) + @_commit.send(m, *args, &block) + end + + def to_graph_hash + h = {} + h[:parents] = self.parents.collect do |p| + [p.id,0,0] + end + h[:author] = Gitlab::Encode.utf8(author.name) + h[:time] = time + h[:space] = space + h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? + h[:id] = sha + h[:date] = date + h[:message] = escape_once(Gitlab::Encode.utf8(message)) + h[:login] = author.email + h + end + + def add_refs(ref_cache, repo) + if ref_cache.empty? + repo.refs.each do |ref| + ref_cache[ref.commit.id] ||= [] + ref_cache[ref.commit.id] << ref + end + end + @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id) + @refs ||= [] + end + end + end +end diff --git a/lib/gitlab/graph/json_builder.rb b/lib/gitlab/graph/json_builder.rb new file mode 100644 index 00000000..c2c3fa66 --- /dev/null +++ b/lib/gitlab/graph/json_builder.rb @@ -0,0 +1,172 @@ +require "grit" + +module Gitlab + module Graph + class JsonBuilder + attr_accessor :days, :commits, :ref_cache, :repo + + def self.max_count + @max_count ||= 650 + end + + def initialize project + @project = project + @repo = project.repo + @ref_cache = {} + + @commits = collect_commits + @days = index_commits + end + + def days_json + @days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json + end + + def commits_json + @commits_json = @commits.map(&:to_graph_hash).to_json + end + + protected + + # Get commits from repository + # + def collect_commits + @commits = Grit::Commit.find_all(repo, nil, {max_count: self.class.max_count}).dup + + # Decorate with app/models/commit.rb + @commits.map! { |commit| ::Commit.new(commit) } + + # Decorate with lib/gitlab/graph/commit.rb + @commits.map! { |commit| Gitlab::Graph::Commit.new(commit) } + + # add refs to each commit + @commits.each { |commit| commit.add_refs(ref_cache, repo) } + + @commits + end + + # Method is adding time and space on the + # list of commits. As well as returns date list + # corelated with time set on commits. + # + # @param [Array] comits to index + # + # @return [Array] list of commit dates corelated with time on commits + def index_commits + days, heads = [], [] + map = {} + + commits.reverse.each_with_index do |c,i| + c.time = i + days[i] = c.committed_date + map[c.id] = c + heads += c.refs unless c.refs.nil? + end + + heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} + # sort heads so the master is top and current branches are closer + heads.sort! do |a,b| + if a.name == "master" + -1 + elsif b.name == "master" + 1 + else + b.commit.committed_date <=> a.commit.committed_date + end + end + + @_reserved = {} + days.each_index do |i| + @_reserved[i] = [] + end + + heads.each do |h| + if map.include? h.commit.id then + place_chain(map[h.commit.id], map) + end + end + + days + end + + # Add space mark on commit and its parents + # + # @param [Graph::Commit] the commit object. + # @param [Hash] map of commits + def place_chain(commit, map, parent_time = nil) + leaves = take_left_leaves(commit, map) + if leaves.empty? + return + end + space = find_free_space(leaves.last.time..leaves.first.time) + leaves.each{|l| l.space = space} + # and mark it as reserved + min_time = leaves.last.time + parents = leaves.last.parents.collect + parents.each do |p| + if map.include? p.id + parent = map[p.id] + if parent.time < min_time + min_time = parent.time + end + end + end + if parent_time.nil? + max_time = leaves.first.time + else + max_time = parent_time - 1 + end + mark_reserved(min_time..max_time, space) + + # Visit branching chains + leaves.each do |l| + parents = l.parents.collect.select{|p| map.include? p.id and map[p.id].space == 0} + for p in parents + place_chain(map[p.id], map, l.time) + end + end + end + + def mark_reserved(time_range, space) + for day in time_range + @_reserved[day].push(space) + end + end + + def find_free_space(time_range) + reserved = [] + for day in time_range + reserved += @_reserved[day] + end + space = 1 + while reserved.include? space do + space += 1 + end + space + end + + # Takes most left subtree branch of commits + # which don't have space mark yet. + # + # @param [Graph::Commit] the commit object. + # @param [Hash] map of commits + # + # @return [Array] list of branch commits + def take_left_leaves(commit, map) + leaves = [] + leaves.push(commit) if commit.space.zero? + + while true + parent = commit.parents.collect.select do |p| + map.include? p.id and map[p.id].space == 0 + end + + return leaves if parent.count.zero? + + commit = map[parent.first.id] + leaves.push(commit) + end + end + end + end +end diff --git a/lib/gitlab/graph_commit.rb b/lib/gitlab/graph_commit.rb deleted file mode 100644 index b1ac1a02..00000000 --- a/lib/gitlab/graph_commit.rb +++ /dev/null @@ -1,195 +0,0 @@ -require "grit" - -module Gitlab - class GraphCommit - attr_accessor :time, :space, :refs - - include ActionView::Helpers::TagHelper - - def self.to_graph(project) - @repo = project.repo - - commits = collect_commits(@repo).dup - - ref_cache = {} - - commits.map! { |commit| GraphCommit.new(Commit.new(commit))} - commits.each { |commit| commit.add_refs(ref_cache, @repo) } - - days = GraphCommit.index_commits(commits) - @days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json - @commits_json = commits.map(&:to_graph_hash).to_json - - return @days_json, @commits_json - end - - # Get commits from repository - # - def self.collect_commits repo - Grit::Commit.find_all(repo, nil, {max_count: self.max_count}) - end - - def self.max_count - @max_count ||= 650 - end - - # Method is adding time and space on the - # list of commits. As well as returns date list - # corelated with time set on commits. - # - # @param [Array] comits to index - # - # @return [Array] list of commit dates corelated with time on commits - def self.index_commits(commits) - days, heads = [], [] - map = {} - - commits.reverse.each_with_index do |c,i| - c.time = i - days[i] = c.committed_date - map[c.id] = c - heads += c.refs unless c.refs.nil? - end - - heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} - # sort heads so the master is top and current branches are closer - heads.sort! do |a,b| - if a.name == "master" - -1 - elsif b.name == "master" - 1 - else - b.commit.committed_date <=> a.commit.committed_date - end - end - - @_reserved = {} - days.each_index do |i| - @_reserved[i] = [] - end - - heads.each do |h| - if map.include? h.commit.id then - place_chain(map[h.commit.id], map) - end - end - days - end - - # Add space mark on commit and its parents - # - # @param [GraphCommit] the commit object. - # @param [Hash] map of commits - def self.place_chain(commit, map, parent_time = nil) - leaves = take_left_leaves(commit, map) - if leaves.empty? then - return - end - space = find_free_space(leaves.last.time..leaves.first.time) - leaves.each{|l| l.space = space} - # and mark it as reserved - min_time = leaves.last.time - parents = leaves.last.parents.collect - parents.each do |p| - if map.include? p.id then - parent = map[p.id] - if parent.time < min_time then - min_time = parent.time - end - end - end - if parent_time.nil? then - max_time = leaves.first.time - else - max_time = parent_time - 1 - end - mark_reserved(min_time..max_time, space) - # Visit branching chains - leaves.each do |l| - parents = l.parents.collect - .select{|p| map.include? p.id and map[p.id].space == 0} - for p in parents - place_chain(map[p.id], map, l.time) - end - end - end - - def self.mark_reserved(time_range, space) - for day in time_range - @_reserved[day].push(space) - end - end - - def self.find_free_space(time_range) - reserved = [] - for day in time_range - reserved += @_reserved[day] - end - space = 1 - while reserved.include? space do - space += 1 - end - space - end - - # Takes most left subtree branch of commits - # which don't have space mark yet. - # - # @param [GraphCommit] the commit object. - # @param [Hash] map of commits - # - # @return [Array] list of branch commits - def self.take_left_leaves(commit, map) - leaves = [] - leaves.push(commit) if commit.space == 0 - while true - parent = commit.parents.collect - .select{|p| map.include? p.id and map[p.id].space == 0} - if parent.count == 0 then - return leaves - else - commit = map[parent.first.id] - leaves.push(commit) - end - end - end - - - def initialize(commit) - @_commit = commit - @time = -1 - @space = 0 - end - - def method_missing(m, *args, &block) - @_commit.send(m, *args, &block) - end - - def to_graph_hash - h = {} - h[:parents] = self.parents.collect do |p| - [p.id,0,0] - end - h[:author] = Gitlab::Encode.utf8(author.name) - h[:time] = time - h[:space] = space - h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? - h[:id] = sha - h[:date] = date - h[:message] = escape_once(Gitlab::Encode.utf8(message)) - h[:login] = author.email - h - end - - def add_refs(ref_cache, repo) - if ref_cache.empty? - repo.refs.each do |ref| - ref_cache[ref.commit.id] ||= [] - ref_cache[ref.commit.id] << ref - end - end - @refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id) - @refs ||= [] - end - end -end From dd4d124832c387ddfc694fdcdae694dc5289cb6c Mon Sep 17 00:00:00 2001 From: randx Date: Sun, 4 Nov 2012 23:44:58 +0200 Subject: [PATCH 095/122] remove accidently created file --- lib/gitlab/graph/' | 165 --------------------------------------------- 1 file changed, 165 deletions(-) delete mode 100644 lib/gitlab/graph/' diff --git a/lib/gitlab/graph/' b/lib/gitlab/graph/' deleted file mode 100644 index 2e45c7d6..00000000 --- a/lib/gitlab/graph/' +++ /dev/null @@ -1,165 +0,0 @@ -require "grit" - -module Gitlab - module Graph - class JsonBuilder - attr_accessor :max_count, :days, :commits - - def initialize project - @project = project - @repo = project.repo - @commits = collect_commits(@repo).dup - @ref_cache = {} - - @commits.map! { |commit| Graph::Commit.new(Commit.new(commit))} - @commits.each { |commit| commit.add_refs(ref_cache, @repo) } - - days = Graph::Commit.index_commits(@commits) - - return @days_json, @commits_json - end - - def collect_commits - end - - def days_json - @days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json - end - - def commits_json - @commits_json = @commits.map(&:to_graph_hash).to_json - end - - # Get commits from repository - # - def collect_commits repo - Grit::Commit.find_all(repo, nil, {max_count: self.max_count}) - end - - def max_count - @max_count ||= 650 - end - - # Method is adding time and space on the - # list of commits. As well as returns date list - # corelated with time set on commits. - # - # @param [Array] comits to index - # - # @return [Array] list of commit dates corelated with time on commits - def index_commits(commits) - days, heads = [], [] - map = {} - - commits.reverse.each_with_index do |c,i| - c.time = i - days[i] = c.committed_date - map[c.id] = c - heads += c.refs unless c.refs.nil? - end - - heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} - # sort heads so the master is top and current branches are closer - heads.sort! do |a,b| - if a.name == "master" - -1 - elsif b.name == "master" - 1 - else - b.commit.committed_date <=> a.commit.committed_date - end - end - - @_reserved = {} - days.each_index do |i| - @_reserved[i] = [] - end - - heads.each do |h| - if map.include? h.commit.id then - place_chain(map[h.commit.id], map) - end - end - days - end - - # Add space mark on commit and its parents - # - # @param [Graph::Commit] the commit object. - # @param [Hash] map of commits - def place_chain(commit, map, parent_time = nil) - leaves = take_left_leaves(commit, map) - if leaves.empty? then - return - end - space = find_free_space(leaves.last.time..leaves.first.time) - leaves.each{|l| l.space = space} - # and mark it as reserved - min_time = leaves.last.time - parents = leaves.last.parents.collect - parents.each do |p| - if map.include? p.id then - parent = map[p.id] - if parent.time < min_time then - min_time = parent.time - end - end - end - if parent_time.nil? then - max_time = leaves.first.time - else - max_time = parent_time - 1 - end - mark_reserved(min_time..max_time, space) - # Visit branching chains - leaves.each do |l| - parents = l.parents.collect - .select{|p| map.include? p.id and map[p.id].space == 0} - for p in parents - place_chain(map[p.id], map, l.time) - end - end - end - - def mark_reserved(time_range, space) - for day in time_range - @_reserved[day].push(space) - end - end - - def find_free_space(time_range) - reserved = [] - for day in time_range - reserved += @_reserved[day] - end - space = 1 - while reserved.include? space do - space += 1 - end - space - end - - # Takes most left subtree branch of commits - # which don't have space mark yet. - # - # @param [Graph::Commit] the commit object. - # @param [Hash] map of commits - # - # @return [Array] list of branch commits - def take_left_leaves(commit, map) - leaves = [] - leaves.push(commit) if commit.space == 0 - while true - parent = commit.parents.collect - self.select{|p| map.include? p.id and map[p.id].space == 0} - if parent.count == 0 then - return leaves - else - commit = map[parent.first.id] - leaves.push(commit) - end - end - end - end - end -end From 89d9319a791fd49dea734414bdbfe840816fb14c Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Sun, 4 Nov 2012 16:47:37 -0500 Subject: [PATCH 096/122] Fix rendered action for password change failure Closes #1912 --- app/controllers/profile_controller.rb | 2 +- features/profile/profile.feature | 5 +++++ features/steps/profile/profile.rb | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb index 2b8e18f6..38cfa896 100644 --- a/app/controllers/profile_controller.rb +++ b/app/controllers/profile_controller.rb @@ -22,7 +22,7 @@ class ProfileController < ApplicationController flash[:notice] = "Password was successfully updated. Please login with it" redirect_to new_user_session_path else - render action: "password" + render 'account' end end diff --git a/features/profile/profile.feature b/features/profile/profile.feature index d07a6db1..a98988b8 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -16,6 +16,11 @@ Feature: Profile Then I change my password And I should be redirected to sign in page + Scenario: I unsuccessfully change my password + Given I visit profile account page + When I unsuccessfully change my password + Then I should see a password error message + Scenario: I reset my token Given I visit profile account page Then I reset my token diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 605936ba..efab1010 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -28,6 +28,16 @@ class Profile < Spinach::FeatureSteps click_button "Save" end + When 'I unsuccessfully change my password' do + fill_in "user_password", with: "password" + fill_in "user_password_confirmation", with: "confirmation" + click_button "Save" + end + + Then "I should see a password error message" do + page.should have_content "Password doesn't match confirmation" + end + And 'I should be redirected to sign in page' do current_path.should == new_user_session_path end From f555578414347855be452cc8ee095c1304768c2b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 5 Nov 2012 20:12:26 +0200 Subject: [PATCH 097/122] Added EventFilter class. Compeleted first version of dashbaord filtering --- app/assets/images/event_filter_comments.png | Bin 0 -> 750 bytes app/assets/images/event_filter_merged.png | Bin 0 -> 463 bytes app/assets/images/event_filter_push.png | Bin 0 -> 632 bytes app/assets/images/event_filter_team.png | Bin 0 -> 1337 bytes app/assets/javascripts/main.js.coffee | 3 + app/assets/stylesheets/sections/events.scss | 31 +++++++++ app/controllers/dashboard_controller.rb | 11 +++- app/helpers/events_helper.rb | 18 ++++++ app/views/dashboard/index.html.haml | 7 ++ lib/event_filter.rb | 68 ++++++++++++++++++++ 10 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 app/assets/images/event_filter_comments.png create mode 100644 app/assets/images/event_filter_merged.png create mode 100644 app/assets/images/event_filter_push.png create mode 100644 app/assets/images/event_filter_team.png create mode 100644 lib/event_filter.rb diff --git a/app/assets/images/event_filter_comments.png b/app/assets/images/event_filter_comments.png new file mode 100644 index 0000000000000000000000000000000000000000..aed113faa7ae70e5c5fbe307ff24d5be39258d1f GIT binary patch literal 750 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyw< z5E>e|PZtIN00M4FL_t(Y$F-GBh>lSd$AAB~x1o&kvA{yc*1|}N#iWsh)hv_+&m9XE zLXsjZrYtm?Qj$VR={#9j84Dj%YFH_=o5{*Xp?u_HiWt)z3-_7s`*eLY!>Omz+%~gI(*#9Ptd}$hEMXSr z-jevqvMkRkgdpIeyC0C$vOWrMcYh6xNqPW$0y=@sz%qBAC&`nFRQuk$`>JNF`I?Lx zNg4;vNjh(44d?3&8%Q$v+9|;4y>I8sR|l8{l{pb{MD# zKF3%KU^9CirR6okeo3F){e+~sz;#J)fG5eac{#D!5&=D_Q&$HIcjF<1&<5Oc_wC6=t8i8{ zV%NXddLVb7V%A(%{_9bHlU>vvxJOgf; z*;_Kh>8~w>&<)%N+F~Zp&1_}v1)7nW*)XsLcvs8h-w;HSN5BqupZL`~J}ZKXMABAZ glK*KTgw9<22g1kw?GASPt^fc407*qoM6N<$g1Qw^R{#J2 literal 0 HcmV?d00001 diff --git a/app/assets/images/event_filter_merged.png b/app/assets/images/event_filter_merged.png new file mode 100644 index 0000000000000000000000000000000000000000..30aea0b6e55985cc8e881d952d1f4282cc80a046 GIT binary patch literal 463 zcmV;=0WkiFP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iye{ z2@)MQM<#Fp00B=)L_t(I%iWW)N&`U>B?r-G$o6;>qnTBxX}7J`_wnZUB-%q4aXEZoff`|bRG>s4j@B>kWXKTjC0O|k$002ovPDHLk FV1kZ7yrKXA literal 0 HcmV?d00001 diff --git a/app/assets/images/event_filter_push.png b/app/assets/images/event_filter_push.png new file mode 100644 index 0000000000000000000000000000000000000000..930faee6aa2a441ab0805910cf815212f95cfe83 GIT binary patch literal 632 zcmV-;0*C#HP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iye{ z2@)=dmq%s*00H<(L_t(I%dOPEYZOrs2k_5rB!qySkQ9rWUSc5#Tck)33yF|2!Y#qG zNm8Xxy88ptd5wwDhdL)eaTyKl;~k!2x6HHe)whirusJ-#2oCWWUG#7jO^o3f3uT_YI1w-n#X45- z2JJG>-k(sxHLPI{oifjs>w?zPQ1sGJEY;j4X()zj{H-(;f6`EN`o3hK%oQw`dDf{( z>H!{Aon@YFqJ_mY6isME0zTtynP;;#Smm4Gx9<9Hd_?OPAe(@0wKX}6#Cj3vRjQL?IdvpEnqGUMXM6{6W{P9 zp0CkYRnk0`$~-%23|!pDB3gs;iqafp|3?Mv3AV~SyH~fqIuZ1BTwmQ&dbS!f+w6m# zv|yXqh>F;c3g|D`$=IHW*t4ZF&o)lo*b($Rrs6ow#0?Dx*hauknP*4Uw|@aR*tis< Sh#*h^0000002t}0ssI2w=C_w00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyw< z5&{UyX)1XD00g;7L_t(|+TB~rZt5@)C5}TvLWo<0D4=#j|NnQoVON1lQ4vY=bnN&p zA|Z4Gf#5L>%&v$UAJ5~=jK|tyvFJRspw6Sq<0Hhk`5Df6Q52kWA;kVeP1AH;M+oV< zey<3H5R}q9&kuneN}lH>RMRvK!?-hqS(Z^si=w#X%W)j*x^5VTX_|L{PzVvnF=MQ$ zC3DUhW43K;n%3S(BZP>es42X?Fvg-NI<#uedAks%X)3uV&UqZi`#&Y)5C&1&-l!<0 zS(eGKndf7n(+zroCS8k9BzHB$DoT zH0rd7Ef`}U9(X8}QpOm@_>cW??=~u^Reo78gy1F$wJZV*42sgDw)o+Hb;G0SPza$; zhmtG9=&&dXMF`8qWfC_S9U_D%r7GYt#t=e(Z>43mu1JTHl@wT{!5FI`3`x3&WDCo( zRJfviUWx&?;`=_Vt#Z!)KJ$jEQ`IetTIDk;P7QKTmSr7wALOOm?Y5%E-;3iofZ?<# z3deEUg%Fl77-N=YwF@DXUBP-aaBKi{MX199)}iA#aKt+rCe7!*SIdke!b z_l)Io8*DjkB@7$mQ%K!`Dx>3_p! z@Je*p@At2EMInT3+igeay6)ANDruS$LLd#QqeeW>3&XG}r*X~)g8^(Yt!iRuG#XvO zib;~Zyu85fL={3^*WcdWeBZzD&a@~B-}hf%U%|T}3a7q2&zsF=zVDX9d zo56Y@ydS1%`d=b>I`@3GRd%YeZL?*?NMHq(R zZnxXt)M}bGolZ{`K53ffc^*Yk$(c1XUP+RyR;zuDVp$d;q~Gt~4q-X?^z-vmt#@@@ zpUq}6X&0q*xm;Fr28{7=IPCZPjgsER2!#+q5Nx;G8csJ1V>+E)2a-}++H*}#_w@AS zy6%Nhw*f-Vc@PA<-R_cn1tByZkDJ<67>4Wh`VxXc2oXXEA!l)3iZBer&1TcI2QwH9 zo}ZsDQ6{ByyWIvs(2VO48V-kqkQ%!^k1)^k@9*z2JY3h0ux)!V7}&O5J@0ZzF9?D- zj<4>0bi3WjWO6EKok5tU>2kRQnN2FUQjP<6I-M-b$_Zka#08JVmG_WAj# zXix@RN}{TQL^W|`wOZW^yfVmteSK9ojA~M0MT1=GB+v6|9L6=Arfy0`of@kH|8=#6 zqUQnXELamj@e~ # Initialize chosen selects $('select.chosen').chosen() + # Initialize tooltips + $('.has_tooltip').tooltip() + # Disable form buttons while a form is submitting $('body').on 'ajax:complete, ajax:beforeSend, submit', 'form', (e) -> buttons = $('[type="submit"]', @) diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 17df600c..f39796e9 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -115,3 +115,34 @@ margin: -3px; } } + +/** + * Event filter + * + */ +.event_filter { + position: absolute; + width: 40px; + + .filter_icon { + float: left; + border-left: 3px solid #4bc; + padding: 7px; + background: #f9f9f9; + margin-bottom: 10px; + img { + width:20px; + } + + &.inactive { + border-left: 3px solid #EEE; + opacity: 0.5; + } + } +} + +.activities { + .content_list { + margin-left:50px; + } +} diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index af23f970..012d8676 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,12 +1,17 @@ class DashboardController < ApplicationController respond_to :html + before_filter :event_filter, only: :index + def index @groups = Group.where(id: current_user.projects.pluck(:group_id)) @projects = current_user.projects_with_events @projects = @projects.page(params[:page]).per(30) - @events = Event.in_projects(current_user.project_ids).limit(20).offset(params[:offset] || 0) + @events = Event.in_projects(current_user.project_ids) + @events = @event_filter.apply_filter(@events) + @events = @events.limit(20).offset(params[:offset] || 0) + @last_push = current_user.recent_push respond_to do |format| @@ -34,4 +39,8 @@ class DashboardController < ApplicationController format.atom { render layout: false } end end + + def event_filter + @event_filter ||= EventFilter.new(params[:event_filter]) + end end diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 0eb87caa..a2548a23 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -33,4 +33,22 @@ module EventsHelper image_tag event_image_path end end + + def event_filter_link key, tooltip + key = key.to_s + + filter = @event_filter.options key + + inactive = if @event_filter.active? key + nil + else + 'inactive' + end + + content_tag :div, class: "filter_icon #{inactive}" do + link_to dashboard_path(event_filter: filter), class: 'has_tooltip', 'data-original-title' => tooltip do + image_tag "event_filter_#{key}.png" + end + end + end end diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 6c4ff96b..023d3213 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -3,6 +3,13 @@ .activities.span8 = render "events/event_last_push", event: @last_push = render 'shared/no_ssh' + + .event_filter + = event_filter_link EventFilter.push, 'Push events' + = event_filter_link EventFilter.merged, 'Merge events' + = event_filter_link EventFilter.comments, 'Comments' + = event_filter_link EventFilter.team, 'Team' + - if @events.any? .content_list= render @events - else diff --git a/lib/event_filter.rb b/lib/event_filter.rb new file mode 100644 index 00000000..14ab0193 --- /dev/null +++ b/lib/event_filter.rb @@ -0,0 +1,68 @@ +class EventFilter + attr_accessor :params + + class << self + def default_filter + %w{ push issues merge_requests team} + end + + def push + 'push' + end + + def merged + 'merged' + end + + def comments + 'comments' + end + + def team + 'team' + end + end + + def initialize params + @params = if params + params.dup + else + []#EventFilter.default_filter + end + end + + def apply_filter events + return events unless params.present? + + filter = params.dup + + actions = [] + actions << Event::Pushed if filter.include? 'push' + actions << Event::Merged if filter.include? 'merged' + + if filter.include? 'team' + actions << Event::Joined + actions << Event::Left + end + + actions << Event::Commented if filter.include? 'comments' + + events = events.where(action: actions) + end + + def options key + filter = params.dup + + if filter.include? key + filter.delete key + else + filter << key + end + + filter + end + + def active? key + params.include? key + end +end From 949233aa1f205d81283e21c6804975ee2481bd54 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 6 Nov 2012 13:47:43 +0200 Subject: [PATCH 098/122] Changed default icon for gravatar. Moved filter out of layout --- app/assets/stylesheets/sections/events.scss | 7 +------ app/helpers/application_helper.rb | 2 +- app/views/dashboard/index.html.haml | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index f39796e9..99523639 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -123,6 +123,7 @@ .event_filter { position: absolute; width: 40px; + margin-left: -50px; .filter_icon { float: left; @@ -140,9 +141,3 @@ } } } - -.activities { - .content_list { - margin-left:50px; - } -} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a4d36c9b..cba34c96 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -36,7 +36,7 @@ module ApplicationHelper else gravatar_prefix = request.ssl? ? "https://secure" : "http://www" user_email.strip! - "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=identicon" + "#{gravatar_prefix}.gravatar.com/avatar/#{Digest::MD5.hexdigest(user_email.downcase)}?s=#{size}&d=mm" end end diff --git a/app/views/dashboard/index.html.haml b/app/views/dashboard/index.html.haml index 023d3213..d0882c6d 100644 --- a/app/views/dashboard/index.html.haml +++ b/app/views/dashboard/index.html.haml @@ -13,7 +13,7 @@ - if @events.any? .content_list= render @events - else - %h4.nothing_here_message Projects activity will be displayed here + %p.nothing_here_message Projects activity will be displayed here .loading.hide .side - if @groups.present? From 378ae951c628574625efafd2f92074e1fca9489d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 6 Nov 2012 17:51:40 +0200 Subject: [PATCH 099/122] version to 3.1.0pre --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 75a22a26..1c452795 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.0.3 +3.1.0pre From 96b2959fe394835c53c248938a76011234f1d49d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 6 Nov 2012 19:31:01 +0200 Subject: [PATCH 100/122] Styled chosen css. Lighter box shadow for blocks --- app/assets/stylesheets/main.scss | 21 +++++-- app/assets/stylesheets/ref_select.scss | 78 +++++++++++++++++--------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index c821c3c1..259a57e5 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -3,10 +3,11 @@ @import 'font-awesome'; /** GitLab colors **/ -$link_color:#3A89A3; -$blue_link: #2fa0bb; -$style_color: #474d57; +$link_color: #3A89A3; +$blue_link: #2FA0BB; +$style_color: #474D57; $hover: #D9EDF7; +$hover_border: #ADF; /** GitLab Fonts **/ @font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); } @@ -19,9 +20,9 @@ $hover: #D9EDF7; } @mixin solid_shade { - -moz-box-shadow: 0 0 0 3px #eee; - -webkit-box-shadow: 0 0 0 3px #eee; - box-shadow: 0 0 0 3px #eee; + -moz-box-shadow: 0 0 0 3px #f1f1f1; + -webkit-box-shadow: 0 0 0 3px #f1f1f1; + box-shadow: 0 0 0 3px #f1f1f1; } @mixin border-radius($radius) { @@ -64,6 +65,14 @@ $hover: #D9EDF7; background-image: -o-linear-gradient($from, $to); } +@mixin bg-light-gray-gradient { + background:#f1f1f1; + background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #f5f5f5), to(#e1e1e1)); + background-image: -webkit-linear-gradient(#f5f5f5 6.6%, #e1e1e1); + background-image: -moz-linear-gradient(#f5f5f5 6.6%, #e1e1e1); + background-image: -o-linear-gradient(#f5f5f5 6.6%, #e1e1e1); +} + @mixin bg-gray-gradient { background:#eee; background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); diff --git a/app/assets/stylesheets/ref_select.scss b/app/assets/stylesheets/ref_select.scss index ed6760f1..377d0086 100644 --- a/app/assets/stylesheets/ref_select.scss +++ b/app/assets/stylesheets/ref_select.scss @@ -19,41 +19,14 @@ margin-right: 10px; .chzn-drop { - margin:7px 0; min-width: 400px; - border: 2px solid $blue_link; - @include border-radius(4px); - .chzn-results { max-height:300px; - - .group-result { - color: $blue_link; - } - .active-result { - &.highlighted { - background: $blue_link; - } - } } - .chzn-search input { min-width:365px; } } - - .chzn-single { - @include bg-gray-gradient; - - div { - background:transparent; - border-left:none; - } - - span { - font-weight: normal; - } - } } /** Fix for Search Dropdown Border **/ @@ -65,4 +38,55 @@ box-shadow: none; } } + + .chzn-drop { + margin:7px 0; + min-width: 200px; + border: 1px solid #bbb; + border-radius:0; + + .chzn-results { + margin-top: 5px; + max-height:300px; + + .group-result { + color: $style_color; + border-bottom: 1px solid #EEE; + padding: 8px; + } + .active-result { + border-radius: 0; + + &.highlighted { + background: $hover; + color: $style_color; + } + &.result-selected { + background: #EEE; + border-left: 4px solid #CCC; + } + } + } + + .chzn-search { + @include bg-gray-gradient; + input { + min-width:165px; + border-color: #CCC; + } + } + } + + .chzn-single { + @include bg-light-gray-gradient; + + div { + background:transparent; + border-left:none; + } + + span { + font-weight: normal; + } + } } From be4138af75b2a80ceb7d444c573fc35c644d9c63 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Tue, 6 Nov 2012 21:15:25 +0100 Subject: [PATCH 101/122] Log caught exceptions --- app/controllers/application_controller.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b597795a..ef6fc81a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,19 +9,28 @@ class ApplicationController < ActionController::Base helper_method :abilities, :can? rescue_from Gitlab::Gitolite::AccessDenied do |exception| + log_exception(exception) render "errors/gitolite", layout: "errors", status: 500 end rescue_from Encoding::CompatibilityError do |exception| + log_exception(exception) render "errors/encoding", layout: "errors", status: 500 end rescue_from ActiveRecord::RecordNotFound do |exception| + log_exception(exception) render "errors/not_found", layout: "errors", status: 404 end protected + def log_exception(exception) + application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace + application_trace.map!{ |t| " #{t}\n" } + logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}" + end + def reject_blocked! if current_user && current_user.blocked sign_out current_user From 0d4568db783f0b5c9e4049fb37056e4acbba36ed Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Wed, 7 Nov 2012 00:47:33 +0200 Subject: [PATCH 102/122] gitolite custom config --- config/gitlab.yml.example | 1 + config/initializers/1_settings.rb | 4 ++++ lib/gitlab/backend/gitolite_config.rb | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 28323484..35683489 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -74,6 +74,7 @@ git_host: upload_pack: true receive_pack: true # host: localhost + # config_file: gitolite.conf # port: 22 # Git settings diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index fb809636..32af3d07 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -104,6 +104,10 @@ class Settings < Settingslogic git_host['admin_uri'] || 'git@localhost:gitolite-admin' end + def gitolite_config_file + git_host['config_file'] || 'gitolite.conf' + end + def gitolite_admin_key git_host['gitolite_admin_key'] || 'gitlab' end diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb index d988164d..1bef19a2 100644 --- a/lib/gitlab/backend/gitolite_config.rb +++ b/lib/gitlab/backend/gitolite_config.rb @@ -14,7 +14,10 @@ module Gitlab end def ga_repo - @ga_repo ||= ::Gitolite::GitoliteAdmin.new(File.join(config_tmp_dir,'gitolite')) + @ga_repo ||= ::Gitolite::GitoliteAdmin.new( + File.join(config_tmp_dir,'gitolite'), + conf: Gitlab.config.gitolite_config_file + ) end def apply From 10d881c9cad92169a3105cff0f02601dad4448cf Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 7 Nov 2012 13:31:26 +0200 Subject: [PATCH 103/122] Line anchors for file view --- app/assets/stylesheets/gitlab_bootstrap/files.scss | 13 +++++++++---- app/views/tree/blob/_text.html.haml | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/gitlab_bootstrap/files.scss index cbc58d22..580b7423 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/files.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/files.scss @@ -157,10 +157,15 @@ font-size:12px !important; } - table.highlighttable .linenodiv pre { - text-align: right; - padding-right: 4px; - color:#666; + table.highlighttable .linenodiv { + a { + color: #666; + } + pre { + text-align: right; + padding-right: 4px; + color:#666; + } } } } diff --git a/app/views/tree/blob/_text.html.haml b/app/views/tree/blob/_text.html.haml index c506a39f..3b7f293a 100644 --- a/app/views/tree/blob/_text.html.haml +++ b/app/views/tree/blob/_text.html.haml @@ -10,6 +10,6 @@ - unless blob.empty? %div{class: current_user.dark_scheme ? "black" : "white"} = preserve do - = raw blob.colorize(options: { linenos: 'True'}) + = raw blob.colorize(options: { linenos: true, lineanchors: :line, anchorlinenos: true }) - else %h4.nothing_here_message Empty file From 22d0569dbbbaa12f3589717f25c340f8b67df1c7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 7 Nov 2012 13:56:48 +0200 Subject: [PATCH 104/122] Dashboard steps: 1.9 syntax & use of create instead of Factory --- features/steps/dashboard/dashboard.rb | 40 +++++++++---------- features/steps/dashboard/dashboard_issues.rb | 4 +- .../dashboard/dashboard_merge_requests.rb | 8 ++-- features/steps/dashboard/dashboard_search.rb | 15 ++++--- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index b22b2465..008c1451 100644 --- a/features/steps/dashboard/dashboard.rb +++ b/features/steps/dashboard/dashboard.rb @@ -32,7 +32,7 @@ class Dashboard < Spinach::FeatureSteps end Given 'user with name "John Doe" joined project "Shop"' do - user = Factory.create(:user, {name: "John Doe"}) + user = create :user, {name: "John Doe"} project = Project.find_by_name "Shop" Event.create( project: project, @@ -60,14 +60,14 @@ class Dashboard < Spinach::FeatureSteps end And 'I own project "Shop"' do - @project = Factory :project, :name => 'Shop' + @project = create :project, name: 'Shop' @project.add_access(@user, :admin) end And 'I have group with projects' do - @group = Factory :group - @project = Factory :project, group: @group - @event = Factory :closed_issue_event, project: @project + @group = create :group + @project = create :project, group: @group + @event = create :closed_issue_event, project: @project @project.add_access current_user, :admin end @@ -76,25 +76,25 @@ class Dashboard < Spinach::FeatureSteps @project = Project.find_by_name("Shop") data = { - :before => "0000000000000000000000000000000000000000", - :after => "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", - :ref => "refs/heads/new_design", - :user_id => @user.id, - :user_name => @user.name, - :repository => { - :name => @project.name, - :url => "localhost/rubinius", - :description => "", - :homepage => "localhost/rubinius", - :private => true + before: "0000000000000000000000000000000000000000", + after: "0220c11b9a3e6c69dc8fd35321254ca9a7b98f7e", + ref: "refs/heads/new_design", + user_id: @user.id, + user_name: @user.name, + repository: { + name: @project.name, + url: "localhost/rubinius", + description: "", + homepage: "localhost/rubinius", + private: true } } @event = Event.create( - :project => @project, - :action => Event::Pushed, - :data => data, - :author_id => @user.id + project: @project, + action: Event::Pushed, + data: data, + author_id: @user.id ) end diff --git a/features/steps/dashboard/dashboard_issues.rb b/features/steps/dashboard/dashboard_issues.rb index 9368782b..e5caf905 100644 --- a/features/steps/dashboard/dashboard_issues.rb +++ b/features/steps/dashboard/dashboard_issues.rb @@ -11,9 +11,9 @@ class DashboardIssues < Spinach::FeatureSteps end And 'I have assigned issues' do - project = Factory :project + project = create :project project.add_access(@user, :read, :write) - 2.times { Factory :issue, :author => @user, :assignee => @user, :project => project } + 2.times { create :issue, author: @user, assignee: @user, project: project } end end diff --git a/features/steps/dashboard/dashboard_merge_requests.rb b/features/steps/dashboard/dashboard_merge_requests.rb index fc339e75..485a4ccc 100644 --- a/features/steps/dashboard/dashboard_merge_requests.rb +++ b/features/steps/dashboard/dashboard_merge_requests.rb @@ -11,13 +11,13 @@ class DashboardMergeRequests < Spinach::FeatureSteps end And 'I have authored merge requests' do - project1 = Factory :project - project2 = Factory :project + project1 = create :project + project2 = create :project project1.add_access(@user, :read, :write) project2.add_access(@user, :read, :write) - merge_request1 = Factory :merge_request, :author => @user, :project => project1 - merge_request2 = Factory :merge_request, :author => @user, :project => project2 + merge_request1 = create :merge_request, author: @user, project: project1 + merge_request2 = create :merge_request, author: @user, project: project2 end end diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb index e902e404..53d74bf3 100644 --- a/features/steps/dashboard/dashboard_search.rb +++ b/features/steps/dashboard/dashboard_search.rb @@ -3,7 +3,7 @@ class DashboardSearch < Spinach::FeatureSteps include SharedPaths Given 'I search for "Sho"' do - fill_in "dashboard_search", :with => "Sho" + fill_in "dashboard_search", with: "Sho" click_button "Search" end @@ -12,24 +12,23 @@ class DashboardSearch < Spinach::FeatureSteps end And 'I own project "Shop"' do - @project = Factory :project, :name => "Shop" + @project = create :project, name: "Shop" @project.add_access(@user, :admin) end Given 'I search for "Contibuting"' do - fill_in "dashboard_search", :with => "Contibuting" + fill_in "dashboard_search", with: "Contibuting" click_button "Search" end And 'Project "Shop" has wiki page "Contibuting guide"' do - @wiki_page = Factory :wiki, :project => @project, - :title => "Contibuting guide", - :slug => "contributing" + @wiki_page = create :wiki, + project: @project, + title: "Contibuting guide", + slug: "contributing" end Then 'I should see "Contibuting guide" wiki link' do page.should have_link "Contibuting guide" end - - end From d52f06f38013540a9798686aa37c4dad120c3d74 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 7 Nov 2012 14:01:23 +0200 Subject: [PATCH 105/122] Remove gitlab-cli and Proc.prod. Use foreman for development and unicorn for production. --- Procfile.production | 2 -- doc/development.md | 4 +-- gitlab | 75 --------------------------------------------- 3 files changed, 2 insertions(+), 79 deletions(-) delete mode 100644 Procfile.production delete mode 100755 gitlab diff --git a/Procfile.production b/Procfile.production deleted file mode 100644 index f1126486..00000000 --- a/Procfile.production +++ /dev/null @@ -1,2 +0,0 @@ -web: bundle exec rails s -p $PORT -e production -worker: bundle exec rake environment resque:work RAILS_ENV=production QUEUE=* diff --git a/doc/development.md b/doc/development.md index ef6a9b02..179c708d 100644 --- a/doc/development.md +++ b/doc/development.md @@ -8,9 +8,9 @@ Install the Gitlab development in a virtual machine with the [Gitlab Vagrant vir ### Start application in development mode -#### 1. Via gitlab cli +#### 1. Via foreman - ./gitlab start + bundle exec foreman start -p 3000 #### 2. Manually diff --git a/gitlab b/gitlab deleted file mode 100755 index acafb3f1..00000000 --- a/gitlab +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env ruby - -class GitlabCli - def initialize - @path = File.dirname(__FILE__) - @command = ARGV.shift - @mode = ARGV.shift - end - - def execute - case @command - when 'start' then start - when 'stop' then stop - else - puts "-- Usage gitlab start production or gitlab stop development" - end - end - - private - - def start - case @mode - when 'production'; - system(unicorn_start_cmd) - system(resque_start_cmd) - else - system(rails_start_cmd) - system(resque_dev_start_cmd) - end - end - - def stop - case @mode - when 'production'; - system(unicorn_stop_cmd) - else - system(rails_stop_cmd) - end - system(resque_stop_cmd) - end - - def rails_start_cmd - "bundle exec rails s -d" - end - - def rails_stop_cmd - pid = File.join(@path, "tmp/pids/server.pid") - "kill -QUIT `cat #{pid}`" - end - - def unicorn_start_cmd - unicorn_conf = File.join(@path, "config/unicorn.rb") - "bundle exec unicorn_rails -c #{unicorn_conf} -E production -D" - end - - def unicorn_stop_cmd - pid = File.join(@path, "/tmp/pids/unicorn.pid") - "kill -QUIT `cat #{pid}`" - end - - def resque_dev_start_cmd - "./resque_dev.sh > /dev/null 2>&1" - end - - def resque_start_cmd - "./resque.sh > /dev/null 2>&1" - end - - def resque_stop_cmd - pid = File.join(@path, "tmp/pids/resque_worker.pid") - "kill -QUIT `cat #{pid}`" - end -end - -GitlabCli.new.execute From b7445bb006ad3fa1ae60cc406dbda5203207fa65 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 7 Nov 2012 17:15:41 +0200 Subject: [PATCH 106/122] Fix github issue #1946 --- app/views/admin/projects/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml index c742fb33..78df8f2d 100644 --- a/app/views/admin/projects/show.html.haml +++ b/app/views/admin/projects/show.html.haml @@ -43,7 +43,7 @@ %b Owner: %td - = @admin_project.owner.name + = @admin_project.owner_name || '(deleted)' %tr %td %b From 313595e171c9931b4d61b1b4b19c50347bc4f87b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 7 Nov 2012 17:32:39 +0200 Subject: [PATCH 107/122] Annotated --- spec/models/merge_request_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index be40c561..0faca766 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -16,6 +16,7 @@ # st_diffs :text(4294967295 # merged :boolean default(FALSE), not null # state :integer default(1), not null +# milestone_id :integer # require 'spec_helper' From 784cb886cf63ba956d6ae93a92d538fd200b5463 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 7 Nov 2012 17:49:52 +0200 Subject: [PATCH 108/122] Sign in screen: removed hr, added clearfix --- app/views/devise/sessions/new.html.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 07ecf70b..38192d71 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -14,8 +14,9 @@ = f.submit "Sign in", :class => "primary btn wide" .right = render :partial => "devise/shared/links" - - if devise_mapping.omniauthable? - %hr/ - - resource_class.omniauth_providers.each do |provider| - %span - = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) + .clearfix + - if devise_mapping.omniauthable? && resource_class.omniauth_providers.present? + %div + - resource_class.omniauth_providers.each do |provider| + %span + = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider) From 993d6338b8efab89488900ed8ed9837f8000d20c Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 8 Nov 2012 15:43:01 +0100 Subject: [PATCH 109/122] Add pointer about alternative platforms --- doc/install/requirements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/install/requirements.md b/doc/install/requirements.md index 955f99a5..75b02d64 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -17,8 +17,8 @@ It should work on: You might have some luck using these, but no guarantees: - - MacOS X - - FreeBSD +- FreeBSD will likely work, see https://github.com/gitlabhq/gitlabhq/issues/796 +- MacOS X will likely work, see https://groups.google.com/forum/#!topic/gitlabhq/5IXHbPkjKLA GitLab does **not** run on Windows and we have no plans of making GitLab compatible. From 96211b01a86c0f147dda88f336e9443c94f46ea4 Mon Sep 17 00:00:00 2001 From: Saito Date: Thu, 8 Nov 2012 22:47:12 +0800 Subject: [PATCH 110/122] add grit_ext to gemfile --- Gemfile | 4 +--- Gemfile.lock | 11 +++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index ff16abad..cff7d661 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,7 @@ gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e' gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd' gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8' +gem 'grit_ext', git: "https://github.com/SaitoWu/grit_ext.git" # Gitolite client (for work with gitolite-admin repo) gem "gitolite", '1.1.0' @@ -83,9 +84,6 @@ gem 'resque_mailer' # HTTP requests gem "httparty" -# Handle encodings -gem "charlock_holmes" - # Colored output to console gem "colored" diff --git a/Gemfile.lock b/Gemfile.lock index 7b21a629..a8e4095d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,10 @@ +GIT + remote: https://github.com/SaitoWu/grit_ext.git + revision: 8558b3282696c50813eaba4100ab6f5fec0ebc16 + specs: + grit_ext (0.5.0) + charlock_holmes (~> 0.6.9) + GIT remote: https://github.com/ctran/annotate_models.git revision: 18cd39ad01829deba5aa34634b8540d6675ab978 @@ -92,7 +99,7 @@ GEM carrierwave (0.6.2) activemodel (>= 3.2.0) activesupport (>= 3.2.0) - charlock_holmes (0.6.8) + charlock_holmes (0.6.9) childprocess (0.3.2) ffi (~> 1.0.6) chosen-rails (0.9.8.3) @@ -415,7 +422,6 @@ DEPENDENCIES capybara capybara-webkit carrierwave - charlock_holmes chosen-rails coffee-rails (= 3.2.2) colored @@ -436,6 +442,7 @@ DEPENDENCIES grack! grape (~> 0.2.1) grit! + grit_ext! growl guard-rspec guard-spinach From f1ac2a616bedc2941bc7f67e2ac25e915da2ddb2 Mon Sep 17 00:00:00 2001 From: Saito Date: Fri, 9 Nov 2012 01:41:07 +0800 Subject: [PATCH 111/122] remove encode lib, clean all encoded area. --- app/controllers/blob_controller.rb | 1 - app/controllers/refs_controller.rb | 1 - app/models/commit.rb | 7 +++-- app/models/tree.rb | 2 +- app/views/blame/show.html.haml | 4 +-- app/views/tree/_blob.html.haml | 2 +- app/views/tree/edit.html.haml | 2 +- config/initializers/3_grit_ext.rb | 19 -------------- lib/gitlab/encode.rb | 41 ------------------------------ lib/gitlab/graph/commit.rb | 4 +-- 10 files changed, 10 insertions(+), 73 deletions(-) delete mode 100644 lib/gitlab/encode.rb diff --git a/app/controllers/blob_controller.rb b/app/controllers/blob_controller.rb index 30069d19..d68754d0 100644 --- a/app/controllers/blob_controller.rb +++ b/app/controllers/blob_controller.rb @@ -1,7 +1,6 @@ # Controller for viewing a file's blame class BlobController < ProjectResourceController include ExtractsPath - include Gitlab::Encode # Authorize before_filter :authorize_read_project! diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb index 977ccea7..b48d5ec7 100644 --- a/app/controllers/refs_controller.rb +++ b/app/controllers/refs_controller.rb @@ -1,5 +1,4 @@ class RefsController < ProjectResourceController - include Gitlab::Encode # Authorize before_filter :authorize_read_project! diff --git a/app/models/commit.rb b/app/models/commit.rb index e6a87dd9..5efb20ce 100644 --- a/app/models/commit.rb +++ b/app/models/commit.rb @@ -1,6 +1,5 @@ class Commit include ActiveModel::Conversion - include Gitlab::Encode include StaticModel extend ActiveModel::Naming @@ -112,7 +111,7 @@ class Commit end def safe_message - @safe_message ||= utf8 message + @safe_message ||= message end def created_at @@ -124,7 +123,7 @@ class Commit end def author_name - utf8 author.name + author.name end # Was this commit committed by a different person than the original author? @@ -133,7 +132,7 @@ class Commit end def committer_name - utf8 committer.name + committer.name end def committer_email diff --git a/app/models/tree.rb b/app/models/tree.rb index e4297a71..c3dfd4c7 100644 --- a/app/models/tree.rb +++ b/app/models/tree.rb @@ -8,7 +8,7 @@ class Tree def initialize(raw_tree, project, ref = nil, path = nil) @project, @ref, @path = project, ref, path @tree = if path.present? - raw_tree / path.dup.force_encoding('ascii-8bit') + raw_tree / path else raw_tree end diff --git a/app/views/blame/show.html.haml b/app/views/blame/show.html.haml index 29fac7a4..c5192c53 100644 --- a/app/views/blame/show.html.haml +++ b/app/views/blame/show.html.haml @@ -15,7 +15,7 @@ .file_title %i.icon-file %span.file_name - = @tree.name.force_encoding('utf-8') + = @tree.name %small= number_to_human_size @tree.size %span.options= render "tree/blob_actions" .file_content.blame @@ -32,4 +32,4 @@ %td.lines = preserve do %pre - = Gitlab::Encode.utf8 lines.join("\n") + = lines.join("\n") diff --git a/app/views/tree/_blob.html.haml b/app/views/tree/_blob.html.haml index 9ede3f8e..ebf1ee2c 100644 --- a/app/views/tree/_blob.html.haml +++ b/app/views/tree/_blob.html.haml @@ -2,7 +2,7 @@ .file_title %i.icon-file %span.file_name - = blob.name.force_encoding('utf-8') + = blob.name %small= number_to_human_size blob.size %span.options= render "tree/blob_actions" - if blob.text? diff --git a/app/views/tree/edit.html.haml b/app/views/tree/edit.html.haml index fdd334a3..a14a15b0 100644 --- a/app/views/tree/edit.html.haml +++ b/app/views/tree/edit.html.haml @@ -4,7 +4,7 @@ .file_title %i.icon-file %span.file_name - = "#{@tree.path.force_encoding('utf-8')} (#{@ref})" + = "#{@tree.path} (#{@ref})" .file_content.code #editor= @tree.data diff --git a/config/initializers/3_grit_ext.rb b/config/initializers/3_grit_ext.rb index fd7e288a..d114ea6c 100644 --- a/config/initializers/3_grit_ext.rb +++ b/config/initializers/3_grit_ext.rb @@ -6,23 +6,4 @@ Grit::Git.git_max_size = Gitlab.config.git_max_size Grit::Blob.class_eval do include Linguist::BlobHelper - - def data - @data ||= @repo.git.cat_file({:p => true}, id) - Gitlab::Encode.utf8 @data - end -end - -Grit::Diff.class_eval do - def old_path - Gitlab::Encode.utf8 @a_path - end - - def new_path - Gitlab::Encode.utf8 @b_path - end - - def diff - Gitlab::Encode.utf8 @diff - end end diff --git a/lib/gitlab/encode.rb b/lib/gitlab/encode.rb deleted file mode 100644 index 7e37442e..00000000 --- a/lib/gitlab/encode.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Patch Strings to enable detect_encoding! on views -require 'charlock_holmes/string' -module Gitlab - module Encode - extend self - - def utf8 message - # return nil if message is nil - return nil unless message - - message.force_encoding("utf-8") - # return message if message type is binary - detect = CharlockHolmes::EncodingDetector.detect(message) - return message if detect[:type] == :binary - - # if message is utf-8 encoding, just return it - return message if message.valid_encoding? - - # if message is not utf-8 encoding, convert it - if detect[:encoding] - message.force_encoding(detect[:encoding]) - message.encode!("utf-8", detect[:encoding], undef: :replace, replace: "", invalid: :replace) - end - - # ensure message encoding is utf8 - message.valid_encoding? ? message : raise - - # Prevent app from crash cause of encoding errors - rescue - encoding = detect ? detect[:encoding] : "unknown" - "--broken encoding: #{encoding}" - end - - def detect_encoding message - return nil unless message - - hash = CharlockHolmes::EncodingDetector.detect(message) rescue {} - return hash[:encoding] ? hash[:encoding] : nil - end - end -end diff --git a/lib/gitlab/graph/commit.rb b/lib/gitlab/graph/commit.rb index e26dd4a6..af8d7828 100644 --- a/lib/gitlab/graph/commit.rb +++ b/lib/gitlab/graph/commit.rb @@ -22,13 +22,13 @@ module Gitlab h[:parents] = self.parents.collect do |p| [p.id,0,0] end - h[:author] = Gitlab::Encode.utf8(author.name) + h[:author] = author.name h[:time] = time h[:space] = space h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? h[:id] = sha h[:date] = date - h[:message] = escape_once(Gitlab::Encode.utf8(message)) + h[:message] = escape_once(message) h[:login] = author.email h end From 8fbac65d036b142a75df5220eafc24ac3775a52c Mon Sep 17 00:00:00 2001 From: Saito Date: Fri, 9 Nov 2012 01:59:14 +0800 Subject: [PATCH 112/122] bump grit_ext version to 0.6.0 --- Gemfile | 2 +- Gemfile.lock | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index cff7d661..526a7e9e 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e' gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd' gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8' -gem 'grit_ext', git: "https://github.com/SaitoWu/grit_ext.git" +gem 'grit_ext', git: "https://github.com/SaitoWu/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10' # Gitolite client (for work with gitolite-admin repo) gem "gitolite", '1.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index a8e4095d..7a379c40 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,9 @@ GIT remote: https://github.com/SaitoWu/grit_ext.git - revision: 8558b3282696c50813eaba4100ab6f5fec0ebc16 + revision: 212fd40bea61f3c6a167223768e7295dc32bbc10 + ref: 212fd40bea61f3c6a167223768e7295dc32bbc10 specs: - grit_ext (0.5.0) + grit_ext (0.6.0) charlock_holmes (~> 0.6.9) GIT From 13dde2e4a4ee7346dc7a5674417cf5a3eb7257fb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 9 Nov 2012 15:17:50 +0200 Subject: [PATCH 113/122] Use grit_ext fork of gitlabhq --- Gemfile | 2 +- Gemfile.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 526a7e9e..84b557ba 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: gem "omniauth-ldap", git: "https://github.com/gitlabhq/omniauth-ldap.git", ref: 'f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e' gem 'yaml_db', git: "https://github.com/gitlabhq/yaml_db.git", ref: '98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd' gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8' -gem 'grit_ext', git: "https://github.com/SaitoWu/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10' +gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '212fd40bea61f3c6a167223768e7295dc32bbc10' # Gitolite client (for work with gitolite-admin repo) gem "gitolite", '1.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 7a379c40..617c302b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/SaitoWu/grit_ext.git - revision: 212fd40bea61f3c6a167223768e7295dc32bbc10 - ref: 212fd40bea61f3c6a167223768e7295dc32bbc10 - specs: - grit_ext (0.6.0) - charlock_holmes (~> 0.6.9) - GIT remote: https://github.com/ctran/annotate_models.git revision: 18cd39ad01829deba5aa34634b8540d6675ab978 @@ -30,6 +22,14 @@ GIT mime-types (~> 1.15) posix-spawn (~> 0.3.6) +GIT + remote: https://github.com/gitlabhq/grit_ext.git + revision: 212fd40bea61f3c6a167223768e7295dc32bbc10 + ref: 212fd40bea61f3c6a167223768e7295dc32bbc10 + specs: + grit_ext (0.6.0) + charlock_holmes (~> 0.6.9) + GIT remote: https://github.com/gitlabhq/omniauth-ldap.git revision: f038dd852d7bd473a557e385d5d7c2fd5dc1dc2e From f0712f39fbb75f4a1911a977ba63f9856331eea5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 9 Nov 2012 15:24:28 +0200 Subject: [PATCH 114/122] charlock_holmes up to 0.6.9 for travis and setup docs --- .travis.yml | 2 +- doc/install/installation.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index df3974fe..fe602a59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ env: before_install: - sudo apt-get install libicu-dev -y - sudo apt-get install libqt4-dev libqtwebkit-dev -y - - gem install charlock_holmes -v="0.6.8" + - gem install charlock_holmes -v="0.6.9" branches: only: - 'master' diff --git a/doc/install/installation.md b/doc/install/installation.md index 03c35c76..04a22a43 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -176,7 +176,7 @@ and ensure you have followed all of the above steps carefully. cd /home/gitlab/gitlab - sudo gem install charlock_holmes --version '0.6.8' + sudo gem install charlock_holmes --version '0.6.9' sudo gem install bundler sudo -u gitlab -H bundle install --without development test sqlite postgres --deployment From 12c0408ef5e09244a1716dd4e13986c9c5224b76 Mon Sep 17 00:00:00 2001 From: jdamick Date: Fri, 9 Nov 2012 11:03:42 -0500 Subject: [PATCH 115/122] Update app/views/notify/project_access_granted_email.html.haml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit changing wording to sound more better.   --- app/views/notify/project_access_granted_email.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/notify/project_access_granted_email.html.haml b/app/views/notify/project_access_granted_email.html.haml index 154c2aaa..72b3f065 100644 --- a/app/views/notify/project_access_granted_email.html.haml +++ b/app/views/notify/project_access_granted_email.html.haml @@ -4,7 +4,7 @@ %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %td{align: "left", style: "padding: 20px 0 0;"} %h2{style: "color:#646464; font-weight: bold; margin: 0; padding: 0; line-height: 26px; font-size: 18px; font-family: Helvetica, Arial, sans-serif; "} - = "You got granted #{@users_project.project_access_human} access to project" + = "You have been granted #{@users_project.project_access_human} access to project" %td{style: "font-size: 1px; line-height: 1px;", width: "21"} %tr %td{style: "font-size: 1px; line-height: 1px;", width: "21"} From b664b784f16f5f0fca295af538483bb83c20f98f Mon Sep 17 00:00:00 2001 From: Saito Date: Sat, 10 Nov 2012 01:06:20 +0800 Subject: [PATCH 116/122] linguist and web browser will take care of mimetype and encoding problem. --- app/controllers/blob_controller.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/controllers/blob_controller.rb b/app/controllers/blob_controller.rb index d68754d0..d4a45d95 100644 --- a/app/controllers/blob_controller.rb +++ b/app/controllers/blob_controller.rb @@ -11,16 +11,9 @@ class BlobController < ProjectResourceController def show if @tree.is_blob? - if @tree.text? - encoding = detect_encoding(@tree.data) - mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain" - else - mime_type = @tree.mime_type - end - send_data( @tree.data, - type: mime_type, + type: @tree.mime_type, disposition: 'inline', filename: @tree.name ) From 6cec9ed3283a611a40b6df981ed00ccaa1bd0e73 Mon Sep 17 00:00:00 2001 From: Saito Date: Sat, 10 Nov 2012 01:36:55 +0800 Subject: [PATCH 117/122] linguist will take care of this --- lib/api/projects.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 8f094e0c..ac20bbec 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -147,7 +147,7 @@ module Gitlab @hooks = paginate user_project.hooks present @hooks, with: Entities::Hook end - + # Get a project hook # # Parameters: @@ -159,7 +159,7 @@ module Gitlab @hook = user_project.hooks.find(params[:hook_id]) present @hook, with: Entities::Hook end - + # Add hook to project # @@ -177,7 +177,7 @@ module Gitlab error!({'message' => '404 Not found'}, 404) end end - + # Update an existing project hook # # Parameters: @@ -382,13 +382,7 @@ module Gitlab tree = Tree.new commit.tree, user_project, ref, params[:filepath] not_found! "File" 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 - + content_type tree.mime_type present tree.data end From ca54d43f9900666ff86fb4c647f9f9441eec781a Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 10 Nov 2012 00:55:56 +0100 Subject: [PATCH 118/122] Fix 500s because of "missing" lexer --- lib/redcarpet/render/gitlab_html.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/redcarpet/render/gitlab_html.rb b/lib/redcarpet/render/gitlab_html.rb index 30a80714..48b4da9d 100644 --- a/lib/redcarpet/render/gitlab_html.rb +++ b/lib/redcarpet/render/gitlab_html.rb @@ -10,10 +10,12 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML end def block_code(code, language) + options = { options: {encoding: 'utf-8'} } + if Pygments::Lexer.find(language) - Pygments.highlight(code, lexer: language, options: {encoding: 'utf-8'}) + Pygments.highlight(code, options.merge(lexer: language.downcase)) else - Pygments.highlight(code, options: {encoding: 'utf-8'}) + Pygments.highlight(code, options) end end From 1c5b2a5153abee3a140ce1f2926d746675addcf5 Mon Sep 17 00:00:00 2001 From: randx Date: Sat, 10 Nov 2012 23:08:47 +0200 Subject: [PATCH 119/122] Stats page --- app/assets/javascripts/application.js | 2 + .../stylesheets/gitlab_bootstrap/lists.scss | 8 ++ app/controllers/repositories_controller.rb | 7 +- app/views/commits/_head.html.haml | 5 ++ app/views/repositories/stats.html.haml | 39 ++++++++++ config/routes.rb | 1 + db/schema.rb | 28 +++---- lib/gitlab/git_stats.rb | 76 +++++++++++++++++++ vendor/assets/javascripts/g.bar-min.js | 7 ++ vendor/assets/javascripts/g.raphael-min.js | 28 +++++++ 10 files changed, 186 insertions(+), 15 deletions(-) create mode 100644 app/views/repositories/stats.html.haml create mode 100644 lib/gitlab/git_stats.rb create mode 100644 vendor/assets/javascripts/g.bar-min.js create mode 100644 vendor/assets/javascripts/g.raphael-min.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index d88f2a66..c4e9a1b0 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -17,6 +17,8 @@ //= require modernizr //= require chosen-jquery //= require raphael +//= require g.raphael-min +//= require g.bar-min //= require branch-graph //= require ace-src-noconflict/ace //= require_tree . diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss index a5d6bd0a..96bdfc91 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss @@ -31,3 +31,11 @@ ul { } } } + +ol, ul { + &.styled { + li { + padding:2px; + } + } +} diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 18b240e4..7678fbff 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -16,9 +16,14 @@ class RepositoriesController < ProjectResourceController @tags = @project.tags end + def stats + @stats = Gitlab::GitStats.new(@project.repo, @project.root_ref) + @graph = @stats.graph + end + def archive unless can?(current_user, :download_code, @project) - render_404 and return + render_404 and return end diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml index c001c2f7..2ec1d24b 100644 --- a/app/views/commits/_head.html.haml +++ b/app/views/commits/_head.html.haml @@ -16,6 +16,11 @@ Tags %span.badge= @project.tags.length + = nav_link(controller: :repositories, action: :stats) do + = link_to stats_project_repository_path(@project) do + Stats + + - if current_controller?(:commits) && current_user.private_token %li.right %span.rss-icon diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml new file mode 100644 index 00000000..bf68dc28 --- /dev/null +++ b/app/views/repositories/stats.html.haml @@ -0,0 +1,39 @@ += render "commits/head" +.row + .span5 + %h4 + Stats for #{@project.root_ref}: + %p + %b Total commits: + %span= @stats.commits_count + %p + %b Total files: + %span= @stats.files_count + %p + %b Authors: + %span= @stats.authors_count + + %br + %div#activity-chart + .span7 + %h4 Top 100 Committers: + %ol.styled + - @stats.authors[0...100].each do |author| + %li + = image_tag gravatar_icon(author.email, 16), class: 'avatar s16' + = author.name + %small.light= author.email + .right + = author.commits + + +:javascript + $(function(){ + var labels = [#{@graph.labels.to_json}]; + var r = Raphael('activity-chart'); + r.text(160, 10, "Commit activity for last #{@graph.weeks} weeks").attr({ font: "13px sans-serif" }); + r.barchart( + 10, 10, 400, 160, + [[#{@graph.commits.join(', ')}]] + ).label(labels, true); + }) diff --git a/config/routes.rb b/config/routes.rb index e597c61e..bf762865 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -128,6 +128,7 @@ Gitlab::Application.routes.draw do member do get "branches" get "tags" + get "stats" get "archive" end end diff --git a/db/schema.rb b/db/schema.rb index 51ab2072..e7eb5696 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -156,30 +156,30 @@ ActiveRecord::Schema.define(:version => 20121026114600) do end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + t.integer "sign_in_count", :default => 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "name" - t.boolean "admin", :default => false, :null => false - t.integer "projects_limit", :default => 10 - t.string "skype", :default => "", :null => false - t.string "linkedin", :default => "", :null => false - t.string "twitter", :default => "", :null => false + t.boolean "admin", :default => false, :null => false + t.integer "projects_limit", :default => 10 + t.string "skype", :default => "", :null => false + t.string "linkedin", :default => "", :null => false + t.string "twitter", :default => "", :null => false t.string "authentication_token" - t.boolean "dark_scheme", :default => false, :null => false - t.integer "theme_id", :default => 1, :null => false + t.boolean "dark_scheme", :default => false, :null => false + t.integer "theme_id", :default => 1, :null => false t.string "bio" - t.boolean "blocked", :default => false, :null => false - t.integer "failed_attempts", :default => 0 + t.boolean "blocked", :default => false, :null => false + t.integer "failed_attempts", :default => 0 t.datetime "locked_at" t.string "extern_uid" t.string "provider" diff --git a/lib/gitlab/git_stats.rb b/lib/gitlab/git_stats.rb new file mode 100644 index 00000000..a83c10ff --- /dev/null +++ b/lib/gitlab/git_stats.rb @@ -0,0 +1,76 @@ +module Gitlab + class GitStats + attr_accessor :repo, :ref + + def initialize repo, ref + @repo, @ref = repo, ref + end + + def authors + @authors ||= collect_authors + end + + def commits_count + @commits_count ||= repo.commit_count(ref) + end + + def files_count + repo.git.sh("git ls-tree -r --name-only #{ref} | wc -l").first.to_i + end + + def authors_count + authors.size + end + + def graph + @graph ||= build_graph + end + + protected + + def collect_authors + shortlog = repo.git.shortlog({:e => true, :s => true }, ref) + + authors = [] + + lines = shortlog.split("\n") + + lines.each do |line| + data = line.split("\t") + commits = data.first + author = Grit::Actor.from_string(data.last) + + authors << OpenStruct.new( + name: author.name, + email: author.email, + commits: commits.to_i + ) + end + + authors.sort_by(&:commits).reverse + end + + def build_graph n = 4 + from, to = (Date.today - n.weeks), Date.today + + format = "--pretty=format:'%h|%at|%ai|%aE'" + commits_strings = repo.git.sh("git rev-list --since #{from.to_s(:date)} #{format} #{ref} | grep -v commit")[0].split("\n") + + commits_dates = commits_strings.map do |string| + data = string.split("|") + date = data[2] + Time.parse(date).to_date.to_s(:date) + end + + commits_per_day = from.upto(to).map do |day| + commits_dates.count(day.to_date.to_s(:date)) + end + + OpenStruct.new( + labels: from.upto(to).map { |day| day.stamp('Aug 23') }, + commits: commits_per_day, + weeks: n + ) + end + end +end diff --git a/vendor/assets/javascripts/g.bar-min.js b/vendor/assets/javascripts/g.bar-min.js new file mode 100644 index 00000000..42f452af --- /dev/null +++ b/vendor/assets/javascripts/g.bar-min.js @@ -0,0 +1,7 @@ +/*! + * g.Raphael 0.5 - Charting library, based on Raphaël + * + * Copyright (c) 2009 Dmitry Baranovskiy (http://g.raphaeljs.com) + * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license. + */ +(function(){var f=Math.min,a=Math.max;function e(o,m,h,p,j,k,l,i){var s,n={round:"round",sharp:"sharp",soft:"soft",square:"square"};if((j&&!p)||(!j&&!h)){return l?"":i.path()}k=n[k]||"square";p=Math.round(p);h=Math.round(h);o=Math.round(o);m=Math.round(m);switch(k){case"round":if(!j){var g=~~(p/2);if(h=2*a?e.attr({path:["M",b,f+a,"a",a,a,0,1,1,0,2*-a,a,a,0,1,1,0,2*a,"m",0,2*-a-3,"a",a+3,a+3,0,1,0,0,2*(a+3),"L",b+a+3,f+c.height/2+3,"l",c.width+6,0, +0,-c.height-6,-c.width-6,0,"L",b,f-a-3].join()}):(g=Math.sqrt(Math.pow(a+3,2)-Math.pow(c.height/2+3,2)),e.attr({path:["M",b,f+a,"c",-i,0,-a,i-a,-a,-a,0,-i,a-i,-a,a,-a,i,0,a,a-i,a,a,0,i,i-a,a,-a,a,"M",b+g,f-c.height/2-3,"a",a+3,a+3,0,1,0,0,c.height+6,"l",a+3-g+c.width+6,0,0,-c.height-6,"L",b+g,f-c.height/2-3].join()}));d=360-d;e.rotate(d,b,f);this.attrs?(this.attr(this.attrs.x?"x":"cx",b+a+3+(!h?"text"==this.type?c.width:0:c.width/2)).attr("y",h?f:f-c.height/2),this.rotate(d,b,f),90d&&this.attr(this.attrs.x? +"x":"cx",b-a-3-(!h?c.width:c.width/2)).rotate(180,b,f)):90d?(this.translate(b-c.x-c.width-a-3,f-c.y-c.height/2),this.rotate(d-180,c.x+c.width+a+3,c.y+c.height/2)):(this.translate(b-c.x+a+3,f-c.y-c.height/2),this.rotate(d,c.x-a-3,c.y+c.height/2));return e.insertBefore(this.node?this:this[0])}}; +Raphael.el.drop=function(d,a,b){var f=this.getBBox(),e=this.paper||this[0].paper,c,g;if(e){switch(this.type){case "text":case "circle":case "ellipse":c=!0;break;default:c=!1}d=d||0;a="number"==typeof a?a:c?f.x+f.width/2:f.x;b="number"==typeof b?b:c?f.y+f.height/2:f.y;g=Math.max(f.width,f.height)+Math.min(f.width,f.height);e=e.path(["M",a,b,"l",g,0,"A",0.4*g,0.4*g,0,1,0,a+0.7*g,b-0.7*g,"z"]).attr({fill:"#000",stroke:"none"}).rotate(22.5-d,a,b);d=(d+90)*Math.PI/180;a=a+g*Math.sin(d)-(c?0:f.width/2); +d=b+g*Math.cos(d)-(c?0:f.height/2);this.attrs?this.attr(this.attrs.x?"x":"cx",a).attr(this.attrs.y?"y":"cy",d):this.translate(a-f.x,d-f.y);return e.insertBefore(this.node?this:this[0])}}; +Raphael.el.flag=function(d,a,b){var f=this.paper||this[0].paper;if(f){var f=f.path().attr({fill:"#000",stroke:"#000"}),e=this.getBBox(),c=e.height/2,g;switch(this.type){case "text":case "circle":case "ellipse":g=!0;break;default:g=!1}d=d||0;a="number"==typeof a?a:g?e.x+e.width/2:e.x;b="number"==typeof b?b:g?e.y+e.height/2:e.y;f.attr({path:["M",a,b,"l",c+3,-c-3,e.width+6,0,0,e.height+6,-e.width-6,0,"z"].join()});d=360-d;f.rotate(d,a,b);this.attrs?(this.attr(this.attrs.x?"x":"cx",a+c+3+(!g?"text"== +this.type?e.width:0:e.width/2)).attr("y",g?b:b-e.height/2),this.rotate(d,a,b),90d&&this.attr(this.attrs.x?"x":"cx",a-c-3-(!g?e.width:e.width/2)).rotate(180,a,b)):90d?(this.translate(a-e.x-e.width-c-3,b-e.y-e.height/2),this.rotate(d-180,e.x+e.width+c+3,e.y+e.height/2)):(this.translate(a-e.x+c+3,b-e.y-e.height/2),this.rotate(d,e.x-c-3,e.y+e.height/2));return f.insertBefore(this.node?this:this[0])}}; +Raphael.el.label=function(){var d=this.getBBox(),a=this.paper||this[0].paper,b=Math.min(20,d.width+10,d.height+10)/2;if(a)return a.rect(d.x-b/2,d.y-b/2,d.width+b,d.height+b,b).attr({stroke:"none",fill:"#000"}).insertBefore(this.node?this:this[0])}; +Raphael.el.blob=function(d,a,b){var f=this.getBBox(),e=Math.PI/180,c=this.paper||this[0].paper,g,i;if(c){switch(this.type){case "text":case "circle":case "ellipse":g=!0;break;default:g=!1}c=c.path().attr({fill:"#000",stroke:"none"});d=(+d+1?d:45)+90;i=Math.min(f.height,f.width);var a="number"==typeof a?a:g?f.x+f.width/2:f.x,b="number"==typeof b?b:g?f.y+f.height/2:f.y,h=Math.max(f.width+i,25*i/12),j=Math.max(f.height+i,25*i/12);g=a+i*Math.sin((d-22.5)*e);var o=b+i*Math.cos((d-22.5)*e),l=a+i*Math.sin((d+ +22.5)*e),d=b+i*Math.cos((d+22.5)*e),e=(l-g)/2;i=(d-o)/2;var h=h/2,j=j/2,n=-Math.sqrt(Math.abs(h*h*j*j-h*h*i*i-j*j*e*e)/(h*h*i*i+j*j*e*e));i=n*h*i/j+(l+g)/2;e=n*-j*e/h+(d+o)/2;c.attr({x:i,y:e,path:["M",a,b,"L",l,d,"A",h,j,0,1,1,g,o,"z"].join()});this.translate(i-f.x-f.width/2,e-f.y-f.height/2);return c.insertBefore(this.node?this:this[0])}};Raphael.fn.label=function(d,a,b){var f=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return f.push(b.label(),b)}; +Raphael.fn.popup=function(d,a,b,f,e){var c=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return c.push(b.popup(f,e),b)};Raphael.fn.tag=function(d,a,b,f,e){var c=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return c.push(b.tag(f,e),b)};Raphael.fn.flag=function(d,a,b,f){var e=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return e.push(b.flag(f),b)};Raphael.fn.drop=function(d,a,b,f){var e=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return e.push(b.drop(f),b)}; +Raphael.fn.blob=function(d,a,b,f){var e=this.set(),b=this.text(d,a,b).attr(Raphael.g.txtattr);return e.push(b.blob(f),b)};Raphael.el.lighter=function(d){var d=d||2,a=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[a[0],a[1]];a[0]=Raphael.rgb2hsb(Raphael.getRGB(a[0]).hex);a[1]=Raphael.rgb2hsb(Raphael.getRGB(a[1]).hex);a[0].b=Math.min(a[0].b*d,1);a[0].s/=d;a[1].b=Math.min(a[1].b*d,1);a[1].s/=d;this.attr({fill:"hsb("+[a[0].h,a[0].s,a[0].b]+")",stroke:"hsb("+[a[1].h,a[1].s,a[1].b]+")"});return this}; +Raphael.el.darker=function(d){var d=d||2,a=[this.attrs.fill,this.attrs.stroke];this.fs=this.fs||[a[0],a[1]];a[0]=Raphael.rgb2hsb(Raphael.getRGB(a[0]).hex);a[1]=Raphael.rgb2hsb(Raphael.getRGB(a[1]).hex);a[0].s=Math.min(a[0].s*d,1);a[0].b/=d;a[1].s=Math.min(a[1].s*d,1);a[1].b/=d;this.attr({fill:"hsb("+[a[0].h,a[0].s,a[0].b]+")",stroke:"hsb("+[a[1].h,a[1].s,a[1].b]+")"});return this};Raphael.el.resetBrightness=function(){this.fs&&(this.attr({fill:this.fs[0],stroke:this.fs[1]}),delete this.fs);return this}; +(function(){var d=["lighter","darker","resetBrightness"],a="popup tag flag label drop blob".split(" "),b;for(b in a)(function(a){Raphael.st[a]=function(){return Raphael.el[a].apply(this,arguments)}})(a[b]);for(b in d)(function(a){Raphael.st[a]=function(){for(var b=0;bb;b++)bMath.abs(a-0.5)?~~a+0.5:Math.round(a)}var e=d,c=a;if(e==c)return{from:e,to:c,power:0};var e=(c-e)/b,g=c=~~e,b=0;if(c){for(;g;)b--,g=~~(e*Math.pow(10,b))/Math.pow(10,b); +b++}else{if(0==e||!isFinite(e))b=1;else for(;!c;)b=b||1,c=~~(e*Math.pow(10,b))/Math.pow(10,b),b++;b&&b--}c=f(a*Math.pow(10,b))/Math.pow(10,b);c=a-b;)"-"!=h&&" "!=h&&(l=l.concat(["M",d-("+"==h||"|"==h?j:2*!(g-1)*j),m+0.5,"l",2*j+1,0])),n.push(o.text(d+p,m,i&&i[u++]||(Math.round(k)==k?k:+k.toFixed(r))).attr(v).attr({"text-anchor":g-1?"start":"end"})),k+=t,m-=s;Math.round(m+s-(a-b))&&("-"!=h&&" "!=h&&(l=l.concat(["M",d-("+"==h||"|"==h?j:2*!(g-1)*j),a-b+0.5,"l",2*j+1,0])),n.push(o.text(d+ +p,a-b,i&&i[u]||(Math.round(k)==k?k:+k.toFixed(r))).attr(v).attr({"text-anchor":g-1?"start":"end"})))}else{for(var k=p,r=(0=q.x-5?n.pop(n.length-1).remove():w=q.x+q.width,k+=t,m+=s;Math.round(m-s-d-b)&&("-"!=h&&" "!=h&&(l=l.concat(["M",d+b+0.5,a-("+"==h?j:2*!!g*j),"l",0,2*j+1])),n.push(o.text(d+ +b,a+p,i&&i[u]||(Math.round(k)==k?k:+k.toFixed(r))).attr(v)))}l=o.path(l);l.text=n;l.all=o.set([l,n]);l.remove=function(){this.text.remove();this.constructor.prototype.remove.call(this)};return l},labelise:function(d,a,b){return d?(d+"").replace(/(##+(?:\.#+)?)|(%%+(?:\.%+)?)/g,function(d,e,c){if(e)return(+a).toFixed(e.replace(/^#+\.?/g,"").length);if(c)return(100*a/b).toFixed(c.replace(/^%+\.?/g,"").length)+"%"}):(+a).toFixed(0)}}; \ No newline at end of file From 3e0467333471576735d225baec289c1e67e1a09c Mon Sep 17 00:00:00 2001 From: randx Date: Sat, 10 Nov 2012 23:33:10 +0200 Subject: [PATCH 120/122] Added feature test for stats --- app/views/repositories/stats.html.haml | 4 ++-- features/project/commits/commits.feature | 4 ++++ features/steps/project/project_browse_commits.rb | 6 ++++++ features/steps/shared/paths.rb | 4 ++++ lib/gitlab/git_stats.rb | 2 +- 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml index bf68dc28..a0a9377d 100644 --- a/app/views/repositories/stats.html.haml +++ b/app/views/repositories/stats.html.haml @@ -16,9 +16,9 @@ %br %div#activity-chart .span7 - %h4 Top 100 Committers: + %h4 Top 50 Committers: %ol.styled - - @stats.authors[0...100].each do |author| + - @stats.authors[0...50].each do |author| %li = image_tag gravatar_icon(author.email, 16), class: 'avatar s16' = author.name diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature index f5a11048..56069cdc 100644 --- a/features/project/commits/commits.feature +++ b/features/project/commits/commits.feature @@ -23,3 +23,7 @@ Feature: Project Browse commits Scenario: I browse commits for a specific path Given I visit my project's commits page for a specific path Then I see breadcrumb links + + Scenario: I browse commits stats + Given I visit my project's commits stats page + Then I see commits stats diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb index 036b6297..428c14a8 100644 --- a/features/steps/project/project_browse_commits.rb +++ b/features/steps/project/project_browse_commits.rb @@ -51,4 +51,10 @@ class ProjectBrowseCommits < Spinach::FeatureSteps find('ul.breadcrumb li:first a')['href'].should match(/#{@project.path}\/commits\/master\z/) find('ul.breadcrumb li:last a')['href'].should match(%r{master/app/models/project\.rb\z}) end + + Then 'I see commits stats' do + page.should have_content 'Stats for master' + page.should have_content 'Committers' + page.should have_content 'Total commits' + end end diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb index e2455554..33a94027 100644 --- a/features/steps/shared/paths.rb +++ b/features/steps/shared/paths.rb @@ -125,6 +125,10 @@ module SharedPaths visit project_commits_path(@project, @project.root_ref + "/app/models/project.rb", {limit: 5}) end + Given 'I visit my project\'s commits stats page' do + visit stats_project_repository_path(@project) + end + Given "I visit my project's network page" do # Stub Graph::JsonBuilder max_size to speed up test (10 commits vs. 650) Gitlab::Graph::JsonBuilder.stub(max_count: 10) diff --git a/lib/gitlab/git_stats.rb b/lib/gitlab/git_stats.rb index a83c10ff..94374869 100644 --- a/lib/gitlab/git_stats.rb +++ b/lib/gitlab/git_stats.rb @@ -29,7 +29,7 @@ module Gitlab protected def collect_authors - shortlog = repo.git.shortlog({:e => true, :s => true }, ref) + shortlog = repo.git.shortlog({e: true, s: true }, ref) authors = [] From 283a9c7b7d5818c18f100e50c66420441c090fee Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sat, 10 Nov 2012 23:45:13 +0200 Subject: [PATCH 121/122] Fix margin-right for some avatars --- app/assets/stylesheets/gitlab_bootstrap/common.scss | 8 ++++---- app/assets/stylesheets/sections/issues.scss | 2 +- app/assets/stylesheets/sections/merge_requests.scss | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss index aa9c421f..25c355e9 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss @@ -68,10 +68,10 @@ .alert-message.error { @extend .alert-error; } /** AVATARS **/ -img.avatar { float:left; margin-right:15px; width:40px; border:1px solid #ddd; padding:1px; } -img.avatar.s16 { width:16px; height:16px; } -img.avatar.s24 { width:24px; height:24px; } -img.avatar.s32 { width:32px; height:32px; } +img.avatar { float:left; margin-right:12px; width:40px; border:1px solid #ddd; padding:1px; } +img.avatar.s16 { width:16px; height:16px; margin-right:6px; } +img.avatar.s24 { width:24px; height:24px; margin-right:8px; } +img.avatar.s32 { width:32px; height:32px; margin-right:10px; } img.lil_av { padding-left: 4px; padding-right:3px; } /** HELPERS **/ diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss index 3ad9d6f7..93622d61 100644 --- a/app/assets/stylesheets/sections/issues.scss +++ b/app/assets/stylesheets/sections/issues.scss @@ -44,7 +44,7 @@ img.avatar { width:32px; - margin-top:4px; + margin-top:1px; } } } diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index fc9ad472..78e3fa39 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -71,7 +71,7 @@ li.merge_request { padding:7px 10px; img.avatar { width: 32px; - margin-top: 4px; + margin-top: 1px; } p { padding: 0px; From 3c7806c3f29e0c2cdbb0c973a9180296267815cb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Sun, 11 Nov 2012 00:08:42 +0200 Subject: [PATCH 122/122] Improve lists. Remove unneccessary padding --- app/assets/stylesheets/gitlab_bootstrap/lists.scss | 2 +- app/assets/stylesheets/sections/events.scss | 1 + app/views/commits/_commit.html.haml | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/lists.scss b/app/assets/stylesheets/gitlab_bootstrap/lists.scss index 96bdfc91..4fe45ecc 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/lists.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/lists.scss @@ -21,7 +21,7 @@ ul { .author { color: #999; } p { - padding-top:5px; + padding-top: 1px; margin:0; color:#222; img { diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss index 99523639..369ebc81 100644 --- a/app/assets/stylesheets/sections/events.scss +++ b/app/assets/stylesheets/sections/events.scss @@ -43,6 +43,7 @@ .event-body { p { color:#555; + padding-top: 5px; } .event-info { color:#666; diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml index 8e96d16a..156ff1e9 100644 --- a/app/views/commits/_commit.html.haml +++ b/app/views/commits/_commit.html.haml @@ -4,8 +4,8 @@ %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right" %p = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" - %strong= commit.author_link avatar: true, size: 24 - %span.dash – + = commit.author_link avatar: true, size: 24 +   = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title" %span.committed_ago