From e6524a919ee4c92d82518c2520d5c0cabc32eb47 Mon Sep 17 00:00:00 2001 From: Ilya Baryshev Date: Tue, 16 Oct 2012 23:05:11 +0400 Subject: [PATCH 001/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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/187] 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 6f25967c476be198853940a85f2d5d410b7bd7b1 Mon Sep 17 00:00:00 2001 From: David Barri Date: Thu, 8 Nov 2012 10:47:11 +1100 Subject: [PATCH 109/187] Fixed issue with git commit silently failing. Also updated status task and installation instuctions. --- doc/installation.md | 8 ++++++++ lib/gitlab/backend/gitolite_config.rb | 4 ++-- lib/tasks/gitlab/status.rake | 20 ++++++++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/doc/installation.md b/doc/installation.md index b04a324d..b1b954f1 100644 --- a/doc/installation.md +++ b/doc/installation.md @@ -244,6 +244,14 @@ and ensure you have followed all of the above steps carefully. # or sqlite sudo -u gitlab -H bundle install --without development test mysql postgres --deployment +#### Configure git client + +Gitlab needs to be able to commit and push changes to gitolite. +Git requires a username and email in order to be able to do that. + + sudo -u gitlab -H git config --global user.email "gitlab@localhost" + sudo -u gitlab -H git config --global user.name "Gitlab" + #### Setup database sudo -u gitlab bundle exec rake gitlab:app:setup RAILS_ENV=production diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb index d988164d..a54608eb 100644 --- a/lib/gitlab/backend/gitolite_config.rb +++ b/lib/gitlab/backend/gitolite_config.rb @@ -191,8 +191,8 @@ module Gitlab def push tmp_dir Dir.chdir(File.join(tmp_dir, "gitolite")) - system('git add -A') - system('git commit -am "GitLab"') + raise "Git add failed." unless system('git add -A') + raise "Git commit failed." unless system('git commit -am "GitLab"') if system('git push') Dir.chdir(Rails.root) else diff --git a/lib/tasks/gitlab/status.rake b/lib/tasks/gitlab/status.rake index 302f417c..ab2f41af 100644 --- a/lib/tasks/gitlab/status.rake +++ b/lib/tasks/gitlab/status.rake @@ -37,9 +37,10 @@ namespace :gitlab do return end + FileUtils.rm_rf("/tmp/gitolite_gitlab_test") begin - `git clone #{Gitlab.config.gitolite_admin_uri} /tmp/gitolite_gitlab_test` - FileUtils.rm_rf("/tmp/gitolite_gitlab_test") + `git clone -q #{Gitlab.config.gitolite_admin_uri} /tmp/gitolite_gitlab_test` + raise unless $?.success? print "Can clone gitolite-admin?............" puts "YES".green rescue @@ -48,6 +49,21 @@ namespace :gitlab do return end + begin + Dir.chdir("/tmp/gitolite_gitlab_test") do + `touch blah && git add blah && git commit -qm blah -- blah` + raise unless $?.success? + end + print "Can git commit?............" + puts "YES".green + rescue + print "Can git commit?............" + puts "NO".red + return + ensure + FileUtils.rm_rf("/tmp/gitolite_gitlab_test") + end + print "UMASK for .gitolite.rc is 0007? ............" if open("#{git_base_path}/../.gitolite.rc").grep(/UMASK([ \t]*)=([ \t>]*)0007/).any? puts "YES".green From 993d6338b8efab89488900ed8ed9837f8000d20c Mon Sep 17 00:00:00 2001 From: Sytse Sijbrandij Date: Thu, 8 Nov 2012 15:43:01 +0100 Subject: [PATCH 110/187] 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 111/187] 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 112/187] 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 113/187] 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 944d3823c32c0b5d336efb8a7a44eb73bfae4f38 Mon Sep 17 00:00:00 2001 From: David Barri Date: Fri, 9 Nov 2012 08:32:00 +1100 Subject: [PATCH 114/187] Fix for git commit when nothing to commit. Turns out git commit returns with 128 when user.name config not present. --- lib/gitlab/backend/gitolite_config.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb index a54608eb..cb931861 100644 --- a/lib/gitlab/backend/gitolite_config.rb +++ b/lib/gitlab/backend/gitolite_config.rb @@ -192,7 +192,9 @@ module Gitlab def push tmp_dir Dir.chdir(File.join(tmp_dir, "gitolite")) raise "Git add failed." unless system('git add -A') - raise "Git commit failed." unless system('git commit -am "GitLab"') + system('git commit -m "GitLab"') # git commit returns 0 on success, and 1 if there is nothing to commit + raise "Git commit failed." unless [0,1].include? $?.exitstatus + if system('git push') Dir.chdir(Rails.root) else From 13dde2e4a4ee7346dc7a5674417cf5a3eb7257fb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 9 Nov 2012 15:17:50 +0200 Subject: [PATCH 115/187] 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 116/187] 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 117/187] 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 118/187] 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 119/187] 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 45dcb1b5c4e765fa048492865d2664f52e0a11a9 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Tue, 6 Nov 2012 22:56:53 +0100 Subject: [PATCH 120/187] Add jQuery.ScrollTo --- app/assets/javascripts/application.js | 1 + vendor/assets/javascripts/jquery.scrollto.js | 225 +++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 vendor/assets/javascripts/jquery.scrollto.js diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index d88f2a66..ae2c925c 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -13,6 +13,7 @@ //= require jquery.history //= require jquery.waitforimages //= require jquery.atwho +//= require jquery.scrollto //= require bootstrap //= require modernizr //= require chosen-jquery diff --git a/vendor/assets/javascripts/jquery.scrollto.js b/vendor/assets/javascripts/jquery.scrollto.js new file mode 100644 index 00000000..7f10b7f1 --- /dev/null +++ b/vendor/assets/javascripts/jquery.scrollto.js @@ -0,0 +1,225 @@ +/** + * @depends jquery + * @name jquery.scrollto + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} + */ + +/** + * jQuery Aliaser + */ +(function(window,undefined){ + // Prepare + var jQuery, $, ScrollTo; + jQuery = $ = window.jQuery; + + /** + * jQuery ScrollTo (balupton edition) + * @version 1.2.0 + * @date July 9, 2012 + * @since 0.1.0, August 27, 2010 + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} + * @author Benjamin "balupton" Lupton {@link http://balupton.com} + * @copyright (c) 2010 Benjamin Arthur Lupton {@link http://balupton.com} + * @license MIT License {@link http://creativecommons.org/licenses/MIT/} + */ + ScrollTo = $.ScrollTo = $.ScrollTo || { + /** + * The Default Configuration + */ + config: { + duration: 400, + easing: 'swing', + callback: undefined, + durationMode: 'each', + offsetTop: 0, + offsetLeft: 0 + }, + + /** + * Configure ScrollTo + */ + configure: function(options){ + // Apply Options to Config + $.extend(ScrollTo.config, options||{}); + + // Chain + return this; + }, + + /** + * Perform the Scroll Animation for the Collections + * We use $inline here, so we can determine the actual offset start for each overflow:scroll item + * Each collection is for each overflow:scroll item + */ + scroll: function(collections, config){ + // Prepare + var collection, $container, container, $target, $inline, position, + containerScrollTop, containerScrollLeft, + containerScrollTopEnd, containerScrollLeftEnd, + startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted, + startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted, + scrollOptions, + callback; + + // Determine the Scroll + collection = collections.pop(); + $container = collection.$container; + container = $container.get(0); + $target = collection.$target; + + // Prepare the Inline Element of the Container + $inline = $('').css({ + 'position': 'absolute', + 'top': '0px', + 'left': '0px' + }); + position = $container.css('position'); + + // Insert the Inline Element of the Container + $container.css('position','relative'); + $inline.appendTo($container); + + // Determine the top offset + startOffsetTop = $inline.offset().top; + targetOffsetTop = $target.offset().top; + targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10); + + // Determine the left offset + startOffsetLeft = $inline.offset().left; + targetOffsetLeft = $target.offset().left; + targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10); + + // Determine current scroll positions + containerScrollTop = container.scrollTop; + containerScrollLeft = container.scrollLeft; + + // Reset the Inline Element of the Container + $inline.remove(); + $container.css('position',position); + + // Prepare the scroll options + scrollOptions = {}; + + // Prepare the callback + callback = function(event){ + // Check + if ( collections.length === 0 ) { + // Callback + if ( typeof config.callback === 'function' ) { + config.callback.apply(this,[event]); + } + } + else { + // Recurse + ScrollTo.scroll(collections,config); + } + // Return true + return true; + }; + + // Handle if we only want to scroll if we are outside the viewport + if ( config.onlyIfOutside ) { + // Determine current scroll positions + containerScrollTopEnd = containerScrollTop + $container.height(); + containerScrollLeftEnd = containerScrollLeft + $container.width(); + + // Check if we are in the range of the visible area of the container + if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) { + targetOffsetTopAdjusted = containerScrollTop; + } + if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) { + targetOffsetLeftAdjusted = containerScrollLeft; + } + } + + // Determine the scroll options + if ( targetOffsetTopAdjusted !== containerScrollTop ) { + scrollOptions.scrollTop = targetOffsetTopAdjusted; + } + if ( targetOffsetLeftAdjusted !== containerScrollLeft ) { + scrollOptions.scrollLeft = targetOffsetLeftAdjusted; + } + + // Perform the scroll + if ( $.browser.safari && container === document.body ) { + window.scrollTo(scrollOptions.scrollLeft, scrollOptions.scrollTop); + callback(); + } + else if ( scrollOptions.scrollTop || scrollOptions.scrollLeft ) { + $container.animate(scrollOptions, config.duration, config.easing, callback); + } + else { + callback(); + } + + // Return true + return true; + }, + + /** + * ScrollTo the Element using the Options + */ + fn: function(options){ + // Prepare + var collections, config, $container, container; + collections = []; + + // Prepare + var $target = $(this); + if ( $target.length === 0 ) { + // Chain + return this; + } + + // Handle Options + config = $.extend({},ScrollTo.config,options); + + // Fetch + $container = $target.parent(); + container = $container.get(0); + + // Cycle through the containers + while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) { + // Check Container for scroll differences + var scrollTop, scrollLeft; + scrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight; + scrollLeft = $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth; + if ( scrollTop || scrollLeft ) { + // Push the Collection + collections.push({ + '$container': $container, + '$target': $target + }); + // Update the Target + $target = $container; + } + // Update the Container + $container = $container.parent(); + container = $container.get(0); + } + + // Add the final collection + collections.push({ + '$container': $( + ($.browser.msie || $.browser.mozilla) ? 'html' : 'body' + ), + '$target': $target + }); + + // Adjust the Config + if ( config.durationMode === 'all' ) { + config.duration /= collections.length; + } + + // Handle + ScrollTo.scroll(collections,config); + + // Chain + return this; + } + }; + + // Apply our jQuery Prototype Function + $.fn.ScrollTo = $.ScrollTo.fn; + +})(window); From c42ada9bee6e95b6fd3ebdc55d4b269f7e18d9f6 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 10 Nov 2012 00:03:46 +0100 Subject: [PATCH 121/187] Allow linking to file lines Supported formats: "L12" for single lines and "L12-34" for multiple lines --- app/assets/javascripts/tree.js.coffee | 19 ++ .../stylesheets/gitlab_bootstrap/files.scss | 90 +++++--- app/assets/stylesheets/highlight/dark.scss | 61 +++--- app/assets/stylesheets/highlight/white.scss | 196 ++++++------------ app/views/tree/blob/_text.html.haml | 2 +- 5 files changed, 174 insertions(+), 194 deletions(-) diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee index 37adef70..8ef41e16 100644 --- a/app/assets/javascripts/tree.js.coffee +++ b/app/assets/javascripts/tree.js.coffee @@ -35,3 +35,22 @@ $ -> state = History.getState() window.ajaxGet(state.url) )(window) + + # See if there are lines selected + # "#L12" and "#L34-56" supported + highlightBlobLines = -> + if window.location.hash isnt "" + matches = window.location.hash.match /\#L(\d+)(\-(\d+))?/ + first_line = parseInt matches[1] + last_line = parseInt matches[3] + + unless isNaN first_line + last_line = first_line if isNaN last_line + $("#tree-content-holder .highlight .line").removeClass("hll") + $("#LC#{line}").addClass("hll") for line in [first_line..last_line] + $("#L#{first_line}").ScrollTo() + + # Highlight the correct lines on load + highlightBlobLines() + # Highlight the correct lines when the hash part of the URL changes + $(window).on 'hashchange', highlightBlobLines diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/gitlab_bootstrap/files.scss index 580b7423..4887d1c9 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/files.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/files.scss @@ -132,39 +132,73 @@ * Code file */ &.code { - padding:0; - td.code { - width: 100%; - .highlight { - margin-left: 55px; - overflow:auto; - overflow-y:hidden; - } - } - .highlight pre { - white-space: pre; - word-wrap:normal; - } + padding: 0; - table.highlighttable { + table.lines { border: none; - } - body.project-page table.highlighttable td { border: none } - table.highlighttable tr:hover { background:none;} + box-shadow: none; + margin: 0px; + padding: 0px; + table-layout: fixed; - table.highlighttable pre{ - line-height:16px !important; - font-size:12px !important; - } - - table.highlighttable .linenodiv { - a { - color: #666; - } pre { + background: none; + border: none; + font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + font-size: 12px !important; + line-height: 16px !important; + margin: 0; + padding: 10px 0; + } + td { + border: none; + margin: 0; + padding: 0; + vertical-align: top; + + &:first-child { + background: #eee; + width: 50px; + } + &:last-child { + } + } + tr:hover { + background: none; + } + + pre.line_numbers { + color: #666; + padding: 10px 6px 10px 0; text-align: right; - padding-right: 4px; - color:#666; + + a { + color: #666; + + i { + display: none; + font-size: 14px; + line-height: 14px; + } + &:hover i { + display: inherit; + } + } + } + + .highlight { + border-left: 1px solid #DEE2E3; + overflow: auto; + overflow-y: hidden; + + pre { + white-space: pre; + word-wrap: normal; + + .line { + padding: 0 10px; + } + } } } } diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index 97c57835..0996cc77 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -1,9 +1,8 @@ -.black .highlighttable { - td.linenos { border:none; } - pre { color: #eee } - .highlight { background: #333; border-left:1px solid #555; } +.black .lines .highlight { + background: #333; + pre { color: #eee; } - .hll { background-color: #ffffff } + .hll { display: block; background-color: darken($hover, 65%) } .c { color: #888888; font-style: italic } /* Comment */ .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .k { color: #CDA869; font-weight: bold } /* Keyword */ @@ -22,43 +21,43 @@ .gs { font-weight: bold } /* Generic.Strong */ .gu { color: #606060 } /* Generic.Subheading */ .gt { color: #aa0000 } /* Generic.Traceback */ - .highlight .kc{font-weight:bold;} /* Keyword.Constant */ - .highlight .kd{font-weight:bold;} /* Keyword.Declaration */ - .highlight .kn{font-weight:bold;} /* Keyword.Namespace */ - .highlight .kp{font-weight:bold;} /* Keyword.Pseudo */ - .highlight .kr{font-weight:bold;} /* Keyword.Reserved */ - .highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ + .kc{font-weight:bold;} /* Keyword.Constant */ + .kd{font-weight:bold;} /* Keyword.Declaration */ + .kn{font-weight:bold;} /* Keyword.Namespace */ + .kp{font-weight:bold;} /* Keyword.Pseudo */ + .kr{font-weight:bold;} /* Keyword.Reserved */ + .kt{color:#458;font-weight:bold;} /* Keyword.Type */ .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .p { color: #eee; } .s { color: #0AD; background-color: transparent } /* Literal.String */ - .highlight .na{color:#008080;} /* Name.Attribute */ - .highlight .nb{color:#0086B3;} /* Name.Builtin */ - .highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */ - .highlight .no{color:turquoise;} /* Name.Constant */ - .highlight .ni{color:#800080;} - .highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */ - .highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */ - .highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */ - .highlight .nt{color:#fc5;} /* Name.Tag */ - .highlight .nv{color:#FA4;} /* Name.Variable */ + .na{color:#008080;} /* Name.Attribute */ + .nb{color:#0086B3;} /* Name.Builtin */ + .nc{color:#ccc;font-weight:bold;} /* Name.Class */ + .no{color:turquoise;} /* Name.Constant */ + .ni{color:#800080;} + .ne{color:#900;font-weight:bold;} /* Name.Exception */ + .nf{color:#ccc;font-weight:bold;} /* Name.Function */ + .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */ + .nt{color:#fc5;} /* Name.Tag */ + .nv{color:#FA4;} /* Name.Variable */ .py { color: #336699; font-weight: bold } /* Name.Property */ .ow { color: #008800 } /* Operator.Word */ .w { color: #bbbbbb } /* Text.Whitespace */ .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */ .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */ - .highlight .mi {color:#099;} /* Literal.Number.Integer */ + .mi {color:#099;} /* Literal.Number.Integer */ .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */ - .highlight .sc{color:#d14;} /* Literal.String.Char */ + .sc{color:#d14;} /* Literal.String.Char */ .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */ - .highlight .s2{color:orange;} /* Literal.String.Double */ - .highlight .se{color:orange;} /* Literal.String.Escape */ - .highlight .sh{color:orange;} /* Literal.String.Heredoc */ - .highlight .si{color:orange;} /* Literal.String.Interpol */ - .highlight .sx{color:orange;} /* Literal.String.Other */ - .highlight .sr{color:orange;} /* Literal.String.Regex */ - .highlight .s1{color:orange;} /* Literal.String.Single */ - .highlight .ss{color:orange;} /* Literal.String.Symbol */ + .s2{color:orange;} /* Literal.String.Double */ + .se{color:orange;} /* Literal.String.Escape */ + .sh{color:orange;} /* Literal.String.Heredoc */ + .si{color:orange;} /* Literal.String.Interpol */ + .sx{color:orange;} /* Literal.String.Other */ + .sr{color:orange;} /* Literal.String.Regex */ + .s1{color:orange;} /* Literal.String.Single */ + .ss{color:orange;} /* Literal.String.Symbol */ .bp { color: #D58 } /* Name.Builtin.Pseudo */ .vc { color: #336699 } /* Name.Variable.Class */ .vg { color: #dd7700 } /* Name.Variable.Global */ diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 9b003b8a..d6792b37 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -1,141 +1,69 @@ -table.highlighttable { - margin:0px; - padding:0px; - font-size:12px; - table-layout:fixed; - background: #EEE; - box-shadow: none; - border: none; - td.linenos { - background:#eee; - border-left:none; - } - td.code { - border-right:none; - } -} - - -td.code, -td.linenos{ - padding:0; - margin:0; - border-top:0; - vertical-align:top; -} - -.highlighttable .highlight{ - background:none; - padding:10px 0px 0px 10px; - margin-left:0px; - border-left: 1px solid #DEE2E3; +.white .lines .highlight { background: white; + pre { color: #333; } + + .hll { display: block; background-color: $hover } + .c { color: #888888; font-style: italic } /* Comment */ + .err { color: #a61717; background-color: #e3d2d2 } /* Error */ + .k { color: #000000; font-weight: bold } /* Keyword */ + .cm { color: #888888 } /* Comment.Multiline */ + .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ + .c1 { color: #888888 } /* Comment.Single */ + .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ + .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ + .ge { font-style: italic } /* Generic.Emph */ + .gr { color: #aa0000 } /* Generic.Error */ + .gh { color: #303030 } /* Generic.Heading */ + .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ + .go { color: #888888 } /* Generic.Output */ + .gp { color: #555555 } /* Generic.Prompt */ + .gs { font-weight: bold } /* Generic.Strong */ + .gu { color: #606060 } /* Generic.Subheading */ + .gt { color: #aa0000 } /* Generic.Traceback */ + .kc{font-weight:bold;} /* Keyword.Constant */ + .kd{font-weight:bold;} /* Keyword.Declaration */ + .kn{font-weight:bold;} /* Keyword.Namespace */ + .kp{font-weight:bold;} /* Keyword.Pseudo */ + .kr{font-weight:bold;} /* Keyword.Reserved */ + .kt{color:#458;font-weight:bold;} /* Keyword.Type */ + .m { color: #0000DD; font-weight: bold } /* Literal.Number */ + .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ + .na{color:#008080;} /* Name.Attribute */ + .nb{color:#0086B3;} /* Name.Builtin */ + .nc{color:#458;font-weight:bold;} /* Name.Class */ + .no{color:#008080;} /* Name.Constant */ + .ni{color:#800080;} + .ne{color:#900;font-weight:bold;} /* Name.Exception */ + .nf{color:#900;font-weight:bold;} /* Name.Function */ + .nn{color:#005;font-weight:bold;} /* Name.Namespace */ + .nt{color:#000080;} /* Name.Tag */ + .nv{color:#008080;} /* Name.Variable */ + .py { color: #336699; font-weight: bold } /* Name.Property */ + .ow { color: #008800 } /* Operator.Word */ + .w { color: #bbbbbb } /* Text.Whitespace */ + .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ + .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ + .mi {color:#099;} /* Literal.Number.Integer */ + .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ + .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ + .sc{color:#d14;} /* Literal.String.Char */ + .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ + .s2{color:#d14;} /* Literal.String.Double */ + .se{color:#d14;} /* Literal.String.Escape */ + .sh{color:#d14;} /* Literal.String.Heredoc */ + .si{color:#d14;} /* Literal.String.Interpol */ + .sx{color:#d14;} /* Literal.String.Other */ + .sr{color:#d14;} /* Literal.String.Regex */ + .s1{color:#d14;} /* Literal.String.Single */ + .ss{color:#d14;} /* Literal.String.Symbol */ + .bp { color: #003388 } /* Name.Builtin.Pseudo */ + .vc { color: #336699 } /* Name.Variable.Class */ + .vg { color: #dd7700 } /* Name.Variable.Global */ + .vi { color: #3333bb } } -.linenodiv pre, -.highlighttable .highlight pre{ - margin:0; - padding:0; - background:none; - border:none; -} - -.linenodiv pre { - white-space:pre-line; -} - -td.linenos { - /*background:#F7F7F7;*/ - color:#666; - padding:10px 0px 0px 10px; - float:left; - width:45px; - border-right: 1px solid #ccc; - -} - -td.code .highlight { - overflow: auto; -} -table.highlighttable pre{ - padding:0; - margin:0; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; - color: #333; - text-align:left; -} - -.git-empty .highlight { - pre{ - padding:15px; - line-height:2.0; - margin:0; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; - color: #333; - text-align:left;} - } - -.shadow{ +.shadow { -webkit-box-shadow:0 5px 15px #000; -moz-box-shadow:0 5px 15px #000; box-shadow:0 5px 15px #000; } - -.hll { background-color: #ffffff } -.c { color: #888888; font-style: italic } /* Comment */ -.err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.k { color: #000000; font-weight: bold } /* Keyword */ -.cm { color: #888888 } /* Comment.Multiline */ -.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ -.c1 { color: #888888 } /* Comment.Single */ -.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ -.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.ge { font-style: italic } /* Generic.Emph */ -.gr { color: #aa0000 } /* Generic.Error */ -.gh { color: #303030 } /* Generic.Heading */ -.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.go { color: #888888 } /* Generic.Output */ -.gp { color: #555555 } /* Generic.Prompt */ -.gs { font-weight: bold } /* Generic.Strong */ -.gu { color: #606060 } /* Generic.Subheading */ -.gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc{font-weight:bold;} /* Keyword.Constant */ -.highlight .kd{font-weight:bold;} /* Keyword.Declaration */ -.highlight .kn{font-weight:bold;} /* Keyword.Namespace */ -.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */ -.highlight .kr{font-weight:bold;} /* Keyword.Reserved */ -.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ -.m { color: #0000DD; font-weight: bold } /* Literal.Number */ -.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ -.highlight .na{color:#008080;} /* Name.Attribute */ -.highlight .nb{color:#0086B3;} /* Name.Builtin */ -.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */ -.highlight .no{color:#008080;} /* Name.Constant */ -.highlight .ni{color:#800080;} -.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */ -.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */ -.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */ -.highlight .nt{color:#000080;} /* Name.Tag */ -.highlight .nv{color:#008080;} /* Name.Variable */ -.py { color: #336699; font-weight: bold } /* Name.Property */ -.ow { color: #008800 } /* Operator.Word */ -.w { color: #bbbbbb } /* Text.Whitespace */ -.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ -.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ -.highlight .mi {color:#099;} /* Literal.Number.Integer */ -.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ -.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ -.highlight .sc{color:#d14;} /* Literal.String.Char */ -.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ -.highlight .s2{color:#d14;} /* Literal.String.Double */ -.highlight .se{color:#d14;} /* Literal.String.Escape */ -.highlight .sh{color:#d14;} /* Literal.String.Heredoc */ -.highlight .si{color:#d14;} /* Literal.String.Interpol */ -.highlight .sx{color:#d14;} /* Literal.String.Other */ -.highlight .sr{color:#d14;} /* Literal.String.Regex */ -.highlight .s1{color:#d14;} /* Literal.String.Single */ -.highlight .ss{color:#d14;} /* Literal.String.Symbol */ -.bp { color: #003388 } /* Name.Builtin.Pseudo */ -.vc { color: #336699 } /* Name.Variable.Class */ -.vg { color: #dd7700 } /* Name.Variable.Global */ -.vi { color: #3333bb } diff --git a/app/views/tree/blob/_text.html.haml b/app/views/tree/blob/_text.html.haml index 3b7f293a..9e0f4bc4 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, lineanchors: :line, anchorlinenos: true }) + = raw blob.colorize(formatter: :gitlab) - else %h4.nothing_here_message Empty file From ca54d43f9900666ff86fb4c647f9f9441eec781a Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 10 Nov 2012 00:55:56 +0100 Subject: [PATCH 122/187] 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 245544a9d9807c6875eb7b3d63ab6d76468464d6 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 10 Nov 2012 10:47:30 +0100 Subject: [PATCH 123/187] Use pygments.rb fork with a custom formatter --- Gemfile | 2 +- Gemfile.lock | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 84b557ba..2a5b95b3 100644 --- a/Gemfile +++ b/Gemfile @@ -33,7 +33,7 @@ gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref gem "gitolite", '1.1.0' # Syntax highlighter -gem "pygments.rb", "0.3.1" +gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4' # Language detection gem "github-linguist", "~> 2.3.4" , require: "linguist" diff --git a/Gemfile.lock b/Gemfile.lock index 617c302b..a78e7379 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -41,6 +41,15 @@ GIT pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.1.1) +GIT + remote: https://github.com/gitlabhq/pygments.rb.git + revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4 + ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4 + specs: + pygments.rb (0.3.2) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) + GIT remote: https://github.com/gitlabhq/yaml_db.git revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd @@ -266,9 +275,6 @@ GEM coderay (~> 1.0.5) method_source (~> 0.7.1) slop (>= 2.4.4, < 3) - pygments.rb (0.3.1) - 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) @@ -465,7 +471,7 @@ DEPENDENCIES omniauth-twitter pg pry - pygments.rb (= 0.3.1) + pygments.rb! quiet_assets (= 1.0.1) rack-mini-profiler rails (= 3.2.8) From 4abf5d06f1104469500c3565890f70f81fbee8bc Mon Sep 17 00:00:00 2001 From: shtirlic Date: Sat, 10 Nov 2012 20:30:22 +0400 Subject: [PATCH 124/187] Update thin closes #1765 and maybe #1051 --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 84b557ba..475b6e8e 100644 --- a/Gemfile +++ b/Gemfile @@ -68,7 +68,7 @@ gem "redcarpet", "~> 2.1.1" gem "github-markup", "~> 0.7.4", require: 'github/markup' # Servers -gem "thin" +gem "thin", '~> 1.5.0' gem "unicorn" # Issue tags diff --git a/Gemfile.lock b/Gemfile.lock index 617c302b..b67f5856 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -117,7 +117,7 @@ GEM colored (1.2) colorize (0.5.8) crack (0.3.1) - daemons (1.1.8) + daemons (1.1.9) database_cleaner (0.8.0) devise (2.1.2) bcrypt-ruby (~> 3.0) @@ -133,7 +133,7 @@ GEM rspec (~> 2.0) erubis (2.7.0) escape_utils (0.2.4) - eventmachine (0.12.10) + eventmachine (1.0.0) execjs (1.4.0) multi_json (~> 1.0) factory_girl (4.0.0) @@ -384,7 +384,7 @@ GEM test_after_commit (0.0.1) therubyracer (0.10.1) libv8 (~> 3.3.10) - thin (1.3.1) + thin (1.5.0) daemons (>= 1.0.9) eventmachine (>= 0.12.6) rack (>= 1.0.0) @@ -489,7 +489,7 @@ DEPENDENCIES stamp test_after_commit therubyracer - thin + thin (~> 1.5.0) uglifier (= 1.0.3) unicorn webmock From 1c5b2a5153abee3a140ce1f2926d746675addcf5 Mon Sep 17 00:00:00 2001 From: randx Date: Sat, 10 Nov 2012 23:08:47 +0200 Subject: [PATCH 125/187] 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 126/187] 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 127/187] 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 128/187] 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 From 9d499b86f8fdb41d2e1cd202989abe67ab88ace7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 13 Nov 2012 12:36:41 +0200 Subject: [PATCH 129/187] Fix loader hiding when create new project --- app/views/projects/create.js.haml | 4 ++-- app/views/projects/update.js.haml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml index 2f6264a1..e8684565 100644 --- a/app/views/projects/create.js.haml +++ b/app/views/projects/create.js.haml @@ -4,8 +4,8 @@ - else - if @project.git_error? location.href = "#{errors_githost_path}"; - -else + -else :plain $('.project_new_holder').show(); $("#new_project").replaceWith("#{escape_javascript(render('new_form'))}"); - $('.ajax_loader').hide(); + $('.save-project-loader').hide(); diff --git a/app/views/projects/update.js.haml b/app/views/projects/update.js.haml index a961dc39..8aaa0e49 100644 --- a/app/views/projects/update.js.haml +++ b/app/views/projects/update.js.haml @@ -5,4 +5,4 @@ :plain $('.project_edit_holder').show(); $(".edit_project").replaceWith("#{escape_javascript(render('form'))}"); - $('.ajax_loader').hide(); + $('.save-project-loader').hide(); From 80fb38de7abdfacbf5ad2e0150b934c1392721f0 Mon Sep 17 00:00:00 2001 From: Vincent Bonmalais Date: Tue, 6 Nov 2012 14:31:55 +1100 Subject: [PATCH 130/187] Remove backward compatibility of factories. --- features/steps/dashboard/dashboard.rb | 8 ++-- features/steps/dashboard/dashboard_search.rb | 2 +- features/steps/group/group.rb | 6 +-- features/steps/profile/profile.rb | 2 +- features/steps/profile/profile_ssh_keys.rb | 2 +- features/steps/project/project_hooks.rb | 2 +- features/steps/project/project_issues.rb | 26 ++++++------ features/steps/project/project_labels.rb | 2 +- .../steps/project/project_merge_requests.rb | 18 ++++----- features/steps/project/project_milestones.rb | 4 +- .../steps/project/project_team_management.rb | 6 +-- features/steps/shared/project.rb | 2 +- spec/factories.rb | 18 --------- spec/mailers/notify_spec.rb | 40 +++++++++---------- spec/models/event_spec.rb | 2 +- spec/models/issue_spec.rb | 8 ++-- spec/models/key_spec.rb | 4 +- spec/models/merge_request_spec.rb | 14 +++---- spec/models/milestone_spec.rb | 4 +- spec/models/note_spec.rb | 36 ++++++++--------- spec/models/project_hooks_spec.rb | 16 ++++---- spec/models/project_security_spec.rb | 6 +-- spec/models/project_spec.rb | 22 +++++----- spec/models/system_hook_spec.rb | 18 ++++----- spec/models/user_spec.rb | 2 +- spec/models/web_hook_spec.rb | 4 +- spec/observers/activity_observer_spec.rb | 18 ++++----- spec/observers/issue_observer_spec.rb | 4 +- spec/observers/merge_request_observer_spec.rb | 4 +- spec/observers/note_observer_spec.rb | 2 +- spec/observers/user_observer_spec.rb | 2 +- spec/observers/users_project_observer_spec.rb | 14 +++---- spec/requests/admin/admin_hooks_spec.rb | 8 ++-- spec/requests/admin/admin_projects_spec.rb | 8 ++-- spec/requests/admin/admin_users_spec.rb | 10 ++--- spec/requests/api/issues_spec.rb | 6 +-- spec/requests/api/merge_requests_spec.rb | 16 ++++---- spec/requests/api/milestones_spec.rb | 6 +-- spec/requests/api/projects_spec.rb | 18 ++++----- spec/requests/api/session_spec.rb | 2 +- spec/requests/api/users_spec.rb | 12 +++--- spec/requests/atom/dashboard_issues_spec.rb | 10 ++--- spec/requests/atom/dashboard_spec.rb | 2 +- spec/requests/atom/issues_spec.rb | 6 +-- .../requests/gitlab_flavored_markdown_spec.rb | 38 +++++++++--------- spec/requests/issues_spec.rb | 34 ++++++++-------- spec/requests/projects_deploy_keys_spec.rb | 6 +-- spec/requests/projects_spec.rb | 10 ++--- spec/requests/search_spec.rb | 4 +- spec/requests/security/profile_access_spec.rb | 2 +- spec/requests/snippets_spec.rb | 14 +++---- spec/support/login_helpers.rb | 2 +- spec/support/matchers.rb | 4 +- spec/workers/post_receive_spec.rb | 4 +- 54 files changed, 261 insertions(+), 279 deletions(-) diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb index 008c1451..99c48738 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 = create :user, {name: "John Doe"} + user = create(:user, {name: "John Doe"}) project = Project.find_by_name "Shop" Event.create( project: project, @@ -65,9 +65,9 @@ class Dashboard < Spinach::FeatureSteps end And 'I have group with projects' do - @group = create :group - @project = create :project, group: @group - @event = create :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 diff --git a/features/steps/dashboard/dashboard_search.rb b/features/steps/dashboard/dashboard_search.rb index 53d74bf3..a34c14d0 100644 --- a/features/steps/dashboard/dashboard_search.rb +++ b/features/steps/dashboard/dashboard_search.rb @@ -12,7 +12,7 @@ class DashboardSearch < Spinach::FeatureSteps end And 'I own project "Shop"' do - @project = create :project, name: "Shop" + @project = create(:project, :name => "Shop") @project.add_access(@user, :admin) end diff --git a/features/steps/group/group.rb b/features/steps/group/group.rb index 51581a1e..4de260ec 100644 --- a/features/steps/group/group.rb +++ b/features/steps/group/group.rb @@ -9,9 +9,9 @@ class Groups < Spinach::FeatureSteps 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 diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index efab1010..151182f6 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -53,7 +53,7 @@ class Profile < Spinach::FeatureSteps end Given 'I have activity' do - Factory :closed_issue_event, author: current_user + create(:closed_issue_event, author: current_user) end Then 'I should see my activity' do diff --git a/features/steps/profile/profile_ssh_keys.rb b/features/steps/profile/profile_ssh_keys.rb index 535c3862..8ae1fa91 100644 --- a/features/steps/profile/profile_ssh_keys.rb +++ b/features/steps/profile/profile_ssh_keys.rb @@ -43,6 +43,6 @@ class ProfileSshKeys < Spinach::FeatureSteps end And 'I have ssh key "ssh-rsa Work"' do - Factory :key, :user => @user, :title => "ssh-rsa Work", :key => "jfKLJDFKSFJSHFJssh-rsa Work" + create(:key, :user => @user, :title => "ssh-rsa Work", :key => "jfKLJDFKSFJSHFJssh-rsa Work") end end diff --git a/features/steps/project/project_hooks.rb b/features/steps/project/project_hooks.rb index 1786fe5b..36555fb8 100644 --- a/features/steps/project/project_hooks.rb +++ b/features/steps/project/project_hooks.rb @@ -6,7 +6,7 @@ class ProjectHooks < Spinach::FeatureSteps include RSpec::Mocks::ExampleMethods Given 'project has hook' do - @hook = Factory :project_hook, project: current_project + @hook = create(:project_hook, project: current_project) end Then 'I should see project hook' do diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb index 64af2449..a9a33650 100644 --- a/features/steps/project/project_issues.rb +++ b/features/steps/project/project_issues.rb @@ -79,16 +79,16 @@ class ProjectIssues < Spinach::FeatureSteps Given 'project "Shop" has milestone "v2.2"' do project = Project.find_by_name("Shop") - milestone = Factory :milestone, :title => "v2.2", :project => project + milestone = create(:milestone, :title => "v2.2", :project => project) - 3.times { Factory :issue, :project => project, :milestone => milestone } + 3.times { create(:issue, :project => project, :milestone => milestone) } end And 'project "Shop" has milestone "v3.0"' do project = Project.find_by_name("Shop") - milestone = Factory :milestone, :title => "v3.0", :project => project + milestone = create(:milestone, :title => "v3.0", :project => project) - 3.times { Factory :issue, :project => project, :milestone => milestone } + 3.times { create(:issue, :project => project, :milestone => milestone) } end When 'I select milestone "v3.0"' do @@ -117,18 +117,18 @@ class ProjectIssues < Spinach::FeatureSteps And 'project "Shop" have "Release 0.4" open issue' do project = Project.find_by_name("Shop") - Factory.create(:issue, - :title => "Release 0.4", - :project => project, - :author => project.users.first) + create(:issue, + :title => "Release 0.4", + :project => project, + :author => project.users.first) end And 'project "Shop" have "Release 0.3" closed issue' do project = Project.find_by_name("Shop") - Factory.create(:issue, - :title => "Release 0.3", - :project => project, - :author => project.users.first, - :closed => true) + create(:issue, + :title => "Release 0.3", + :project => project, + :author => project.users.first, + :closed => true) end end diff --git a/features/steps/project/project_labels.rb b/features/steps/project/project_labels.rb index 1a347bf3..915190f3 100644 --- a/features/steps/project/project_labels.rb +++ b/features/steps/project/project_labels.rb @@ -18,7 +18,7 @@ class ProjectLabels < Spinach::FeatureSteps And 'project "Shop" have issues tags: "bug", "feature"' do project = Project.find_by_name("Shop") ['bug', 'feature'].each do |label| - Factory :issue, project: project, label_list: label + create(:issue, project: project, label_list: label) end end end diff --git a/features/steps/project/project_merge_requests.rb b/features/steps/project/project_merge_requests.rb index 80e83906..d153ad28 100644 --- a/features/steps/project/project_merge_requests.rb +++ b/features/steps/project/project_merge_requests.rb @@ -63,18 +63,18 @@ class ProjectMergeRequests < Spinach::FeatureSteps And 'project "Shop" have "Bug NS-04" open merge request' do project = Project.find_by_name("Shop") - Factory.create(:merge_request, - :title => "Bug NS-04", - :project => project, - :author => project.users.first) + create(:merge_request, + :title => "Bug NS-04", + :project => project, + :author => project.users.first) end And 'project "Shop" have "Feature NS-03" closed merge request' do project = Project.find_by_name("Shop") - Factory.create(:merge_request, - :title => "Feature NS-03", - :project => project, - :author => project.users.first, - :closed => true) + create(:merge_request, + :title => "Feature NS-03", + :project => project, + :author => project.users.first, + :closed => true) end end diff --git a/features/steps/project/project_milestones.rb b/features/steps/project/project_milestones.rb index 4d689c95..1c9ad6da 100644 --- a/features/steps/project/project_milestones.rb +++ b/features/steps/project/project_milestones.rb @@ -32,9 +32,9 @@ class ProjectMilestones < Spinach::FeatureSteps And 'project "Shop" has milestone "v2.2"' do project = Project.find_by_name("Shop") - milestone = Factory :milestone, :title => "v2.2", :project => project + milestone = create(:milestone, :title => "v2.2", :project => project) - 3.times { Factory :issue, :project => project, :milestone => milestone } + 3.times { create(:issue, :project => project, :milestone => milestone) } end Given 'the milestone has open and closed issues' do diff --git a/features/steps/project/project_team_management.rb b/features/steps/project/project_team_management.rb index 5c3a9b31..6bde0b64 100644 --- a/features/steps/project/project_team_management.rb +++ b/features/steps/project/project_team_management.rb @@ -74,11 +74,11 @@ class ProjectTeamManagement < Spinach::FeatureSteps end And 'gitlab user "Mike"' do - Factory :user, :name => "Mike" + create(:user, :name => "Mike") end And 'gitlab user "Sam"' do - Factory :user, :name => "Sam" + create(:user, :name => "Sam") end And '"Sam" is "Shop" developer' do @@ -88,7 +88,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps end Given 'I own project "Website"' do - @project = Factory :project, :name => "Website" + @project = create(:project, :name => "Website") @project.add_access(@user, :admin) end diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb index ae871d63..dfc8ce9d 100644 --- a/features/steps/shared/project.rb +++ b/features/steps/shared/project.rb @@ -9,7 +9,7 @@ module SharedProject # Create a specific project called "Shop" And 'I own project "Shop"' do - @project = Factory :project, :name => "Shop" + @project = create(:project, :name => "Shop") @project.add_access(@user, :admin) end diff --git a/spec/factories.rb b/spec/factories.rb index 0258f892..7b2a2efa 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,21 +1,3 @@ -# Backwards compatibility with the old method -def Factory(type, *args) - FactoryGirl.create(type, *args) -end - -module Factory - def self.create(type, *args) - FactoryGirl.create(type, *args) - end - - def self.new(type, *args) - FactoryGirl.build(type, *args) - end - def self.attributes(type, *args) - FactoryGirl.attributes_for(type, *args) - end -end - FactoryGirl.define do sequence :sentence, aliases: [:title, :content] do Faker::Lorem.sentence diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 874864a3..b6b1769f 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -4,8 +4,8 @@ describe Notify do include EmailSpec::Helpers include EmailSpec::Matchers - let(:recipient) { Factory.create(:user, email: 'recipient@example.com') } - let(:project) { Factory.create(:project) } + let(:recipient) { create(:user, email: 'recipient@example.com') } + let(:project) { create(:project) } shared_examples 'a multiple recipients email' do it 'is sent to the given recipient' do @@ -15,7 +15,7 @@ describe Notify do describe 'for new users, the email' do let(:example_site_path) { root_path } - let(:new_user) { Factory.create(:user, email: 'newguy@example.com') } + let(:new_user) { create(:user, email: 'newguy@example.com') } subject { Notify.new_user_email(new_user.id, new_user.password) } @@ -42,8 +42,8 @@ describe Notify do context 'for a project' do describe 'items that are assignable, the email' do - let(:assignee) { Factory.create(:user, email: 'assignee@example.com') } - let(:previous_assignee) { Factory.create(:user, name: 'Previous Assignee') } + let(:assignee) { create(:user, email: 'assignee@example.com') } + let(:previous_assignee) { create(:user, name: 'Previous Assignee') } shared_examples 'an assignee email' do it 'is sent to the assignee' do @@ -52,7 +52,7 @@ describe Notify do end context 'for issues' do - let(:issue) { Factory.create(:issue, assignee: assignee, project: project ) } + let(:issue) { create(:issue, assignee: assignee, project: project ) } describe 'that are new' do subject { Notify.new_issue_email(issue.id) } @@ -93,10 +93,10 @@ describe Notify do end describe 'status changed' do - let(:current_user) { Factory.create :user, email: "current@email.com" } + let(:current_user) { create(:user, email: "current@email.com") } let(:status) { 'closed' } subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) } - + it 'has the correct subject' do should have_subject /changed issue ##{issue.id} \| #{issue.title}/i end @@ -117,7 +117,7 @@ describe Notify do end context 'for merge requests' do - let(:merge_request) { Factory.create(:merge_request, assignee: assignee, project: project) } + let(:merge_request) { create(:merge_request, assignee: assignee, project: project) } describe 'that are new' do subject { Notify.new_merge_request_email(merge_request.id) } @@ -169,13 +169,13 @@ describe Notify do end describe 'project access changed' do - let(:project) { Factory.create(:project, - path: "Fuu", - code: "Fuu") } - let(:user) { Factory.create :user } - let(:users_project) { Factory.create(:users_project, - project: project, - user: user) } + let(:project) { create(:project, + path: "Fuu", + code: "Fuu") } + let(:user) { create(:user) } + let(:users_project) { create(:users_project, + project: project, + user: user) } subject { Notify.project_access_granted_email(users_project.id) } it 'has the correct subject' do should have_subject /access to project was granted/ @@ -189,8 +189,8 @@ describe Notify do end context 'items that are noteable, the email for a note' do - let(:note_author) { Factory.create(:user, name: 'author_name') } - let(:note) { Factory.create(:note, project: project, author: note_author) } + let(:note_author) { create(:user, name: 'author_name') } + let(:note) { create(:note, project: project, author: note_author) } before :each do Note.stub(:find).with(note.id).and_return(note) @@ -251,7 +251,7 @@ describe Notify do end describe 'on a merge request' do - let(:merge_request) { Factory.create(:merge_request, project: project) } + let(:merge_request) { create(:merge_request, project: project) } let(:note_on_merge_request_path) { project_merge_request_path(project, merge_request, anchor: "note_#{note.id}") } before(:each) { note.stub(:noteable).and_return(merge_request) } @@ -269,7 +269,7 @@ describe Notify do end describe 'on an issue' do - let(:issue) { Factory.create(:issue, project: project) } + let(:issue) { create(:issue, project: project) } let(:note_on_issue_path) { project_issue_path(project, issue, anchor: "note_#{note.id}") } before(:each) { note.stub(:noteable).and_return(issue) } diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 77b49246..d68ebb86 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -32,7 +32,7 @@ describe Event do describe "Push event" do before do - project = Factory :project + project = create(:project) @user = project.owner data = { diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 7c98b9ea..4e999aad 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -38,11 +38,11 @@ describe Issue do it { should include_module(Votes) } end - subject { Factory.create(:issue) } + subject { create(:issue) } describe '#is_being_reassigned?' do it 'returns true if the issue assignee has changed' do - subject.assignee = Factory(:user) + subject.assignee = create(:user) subject.is_being_reassigned?.should be_true end it 'returns false if the issue assignee has not changed' do @@ -56,7 +56,7 @@ describe Issue do subject.is_being_closed?.should be_true end it 'returns false if the closed attribute has changed and is now false' do - issue = Factory.create(:closed_issue) + issue = create(:closed_issue) issue.closed = false issue.is_being_closed?.should be_false end @@ -68,7 +68,7 @@ describe Issue do describe '#is_being_reopened?' do it 'returns true if the closed attribute has changed and is now false' do - issue = Factory.create(:closed_issue) + issue = create(:closed_issue) issue.closed = false issue.is_being_reopened?.should be_true end diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index d3231af8..80dfff08 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -53,7 +53,7 @@ describe Key do end context "as a personal key" do - let(:user) { Factory.create(:user) } + let(:user) { create(:user) } it "accepts the key once" do build(:key, user: user).should be_valid @@ -67,7 +67,7 @@ describe Key do end context "validate it is a fingerprintable key" do - let(:user) { Factory.create(:user) } + let(:user) { create(:user) } it "accepts the fingerprintable key" do build(:key, user: user).should be_valid diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index be40c561..3267f6f6 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -37,12 +37,12 @@ describe MergeRequest do end describe "#mr_and_commit_notes" do - let!(:merge_request) { Factory.create(:merge_request) } + let!(:merge_request) { create(:merge_request) } before do merge_request.stub(:commits) { [merge_request.project.commit] } - Factory.create(:note, noteable: merge_request.commits.first) - Factory.create(:note, noteable: merge_request) + create(:note, noteable: merge_request.commits.first) + create(:note, noteable: merge_request) end it "should include notes for commits" do @@ -51,11 +51,11 @@ describe MergeRequest do end end - subject { Factory.create(:merge_request) } + subject { create(:merge_request) } describe '#is_being_reassigned?' do it 'returns true if the merge_request assignee has changed' do - subject.assignee = Factory(:user) + subject.assignee = create(:user) subject.is_being_reassigned?.should be_true end it 'returns false if the merge request assignee has not changed' do @@ -69,7 +69,7 @@ describe MergeRequest do subject.is_being_closed?.should be_true end it 'returns false if the closed attribute has changed and is now false' do - merge_request = Factory.create(:closed_merge_request) + merge_request = create(:closed_merge_request) merge_request.closed = false merge_request.is_being_closed?.should be_false end @@ -81,7 +81,7 @@ describe MergeRequest do describe '#is_being_reopened?' do it 'returns true if the closed attribute has changed and is now false' do - merge_request = Factory.create(:closed_merge_request) + merge_request = create(:closed_merge_request) merge_request.closed = false merge_request.is_being_reopened?.should be_true end diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 1aba20c6..0e5cf7dd 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -30,8 +30,8 @@ describe Milestone do it { should ensure_inclusion_of(:closed).in_array([true, false]) } end - let(:milestone) { Factory :milestone } - let(:issue) { Factory :issue } + let(:milestone) { create(:milestone) } + let(:issue) { create(:issue) } describe "#percent_complete" do it "should not count open issues" do diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index 514b6202..d7390537 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -40,10 +40,10 @@ describe Note do end describe "Voting score" do - let(:project) { Factory(:project) } + let(:project) { create(:project) } it "recognizes a neutral note" do - note = Factory(:note, note: "This is not a +1 note") + note = create(:note, note: "This is not a +1 note") note.should_not be_upvote note.should_not be_downvote end @@ -55,7 +55,7 @@ describe Note do end it "recognizes a +1 note" do - note = Factory(:note, note: "+1 for this") + note = create(:note, note: "+1 for this") note.should be_upvote end @@ -65,7 +65,7 @@ describe Note do end it "recognizes a -1 note" do - note = Factory(:note, note: "-1 for this") + note = create(:note, note: "-1 for this") note.should be_downvote end @@ -80,9 +80,9 @@ describe Note do describe "Commit notes" do before do - @note = Factory :note, - noteable_id: commit.id, - noteable_type: "Commit" + @note = create(:note, + noteable_id: commit.id, + noteable_type: "Commit") end it "should be accessible through #noteable" do @@ -103,10 +103,10 @@ describe Note do describe "Pre-line commit notes" do before do - @note = Factory :note, - noteable_id: commit.id, - noteable_type: "Commit", - line_code: "0_16_1" + @note = create(:note, + noteable_id: commit.id, + noteable_type: "Commit", + line_code: "0_16_1") end it "should save a valid note" do @@ -120,9 +120,9 @@ describe Note do end describe '#create_status_change_note' do - let(:project) { Factory.create(:project) } - let(:thing) { Factory.create(:issue, project: project) } - let(:author) { Factory(:user) } + let(:project) { create(:project) } + let(:thing) { create(:issue, project: project) } + let(:author) { create(:user) } let(:status) { 'new_status' } subject { Note.create_status_change_note(thing, author, status) } @@ -141,10 +141,10 @@ describe Note do describe :authorization do before do @p1 = create(:project) - @p2 = Factory :project - @u1 = Factory :user - @u2 = Factory :user - @u3 = Factory :user + @p2 = create(:project) + @u1 = create(:user) + @u2 = create(:user) + @u3 = create(:user) @abilities = Six.new @abilities << Ability end diff --git a/spec/models/project_hooks_spec.rb b/spec/models/project_hooks_spec.rb index 129e3d61..ee441ec4 100644 --- a/spec/models/project_hooks_spec.rb +++ b/spec/models/project_hooks_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' describe Project, "Hooks" do - let(:project) { Factory :project } - before do - @key = Factory :key, user: project.owner + let(:project) { create(:project) } + before do + @key = create(:key, user: project.owner) @user = @key.user @key_id = @key.identifier end - describe "Post Receive Event" do - it "should create push event" do + describe "Post Receive Event" do + it "should create push event" do oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master' project.observe_push(oldrev, newrev, ref, @user) event = Event.last @@ -32,8 +32,8 @@ describe Project, "Hooks" do context "with web hooks" do before do - @project_hook = Factory(:project_hook) - @project_hook_2 = Factory(:project_hook) + @project_hook = create(:project_hook) + @project_hook_2 = create(:project_hook) project.hooks << [@project_hook, @project_hook_2] end @@ -47,7 +47,7 @@ describe Project, "Hooks" do context "does not execute web hooks" do before do - @project_hook = Factory(:project_hook) + @project_hook = create(:project_hook) project.hooks << [@project_hook] end diff --git a/spec/models/project_security_spec.rb b/spec/models/project_security_spec.rb index baf6d4b6..60f8d45c 100644 --- a/spec/models/project_security_spec.rb +++ b/spec/models/project_security_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Project do describe :authorization do before do - @p1 = Factory :project - @u1 = Factory :user - @u2 = Factory :user + @p1 = create(:project) + @u1 = create(:user) + @u2 = create(:user) @abilities = Six.new @abilities << Ability end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 6fe46446..1cf4f586 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -157,7 +157,7 @@ describe Project do describe :valid_repo? do it "should be valid repo" do - project = Factory :project + project = create(:project) project.valid_repo?.should be_true end @@ -168,7 +168,7 @@ describe Project do end describe "last_activity methods" do - let(:project) { Factory :project } + let(:project) { create(:project) } let(:last_event) { double(created_at: Time.now) } describe "last_activity" do @@ -191,7 +191,7 @@ describe Project do end describe "fresh commits" do - let(:project) { Factory :project } + let(:project) { create(:project) } it { project.fresh_commits(3).count.should == 3 } it { project.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" } @@ -199,7 +199,7 @@ describe Project do end describe "commits_between" do - let(:project) { Factory :project } + let(:project) { create(:project) } subject do commits = project.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff", @@ -213,7 +213,7 @@ describe Project do end describe "Git methods" do - let(:project) { Factory :project } + let(:project) { create(:project) } describe :repo do it "should return valid repo" do @@ -270,14 +270,14 @@ describe Project do end describe :update_merge_requests do - let(:project) { Factory :project } + let(:project) { create(:project) } before do - @merge_request = Factory :merge_request, - project: project, - merged: false, - closed: false - @key = Factory :key, user_id: project.owner.id + @merge_request = create(:merge_request, + project: project, + merged: false, + closed: false) + @key = create(:key, user_id: project.owner.id) end it "should close merge request if last commit from source branch was pushed to target branch" do diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb index b5d338a8..5f923911 100644 --- a/spec/models/system_hook_spec.rb +++ b/spec/models/system_hook_spec.rb @@ -17,19 +17,19 @@ describe SystemHook do before(:each) { ActiveRecord::Base.observers.enable(:all) } before(:each) do - @system_hook = Factory :system_hook + @system_hook = create(:system_hook) WebMock.stub_request(:post, @system_hook.url) end it "project_create hook" do with_resque do - project = Factory :project + project = create(:project) end WebMock.should have_requested(:post, @system_hook.url).with(body: /project_create/).once end it "project_destroy hook" do - project = Factory :project + project = create(:project) with_resque do project.destroy end @@ -38,13 +38,13 @@ describe SystemHook do it "user_create hook" do with_resque do - Factory :user + create(:user) end WebMock.should have_requested(:post, @system_hook.url).with(body: /user_create/).once end it "user_destroy hook" do - user = Factory :user + user = create(:user) with_resque do user.destroy end @@ -52,8 +52,8 @@ describe SystemHook do end it "project_create hook" do - user = Factory :user - project = Factory :project + user = create(:user) + project = create(:project) with_resque do project.users << user end @@ -61,8 +61,8 @@ describe SystemHook do end it "project_destroy hook" do - user = Factory :user - project = Factory :project + user = create(:user) + project = create(:project) project.users << user with_resque do project.users_projects.clear diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 5f41fb05..b9654d70 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -108,7 +108,7 @@ describe User do describe 'authentication token' do it "should have authentication token" do - user = Factory(:user) + user = create(:user) user.authentication_token.should_not be_blank end end diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index d71fec81..8f8decb8 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -39,8 +39,8 @@ describe ProjectHook do describe "execute" do before(:each) do - @project_hook = Factory :project_hook - @project = Factory :project + @project_hook = create(:project_hook) + @project = create(:project) @project.hooks << [@project_hook] @data = { before: 'oldrev', after: 'newrev', ref: 'ref'} diff --git a/spec/observers/activity_observer_spec.rb b/spec/observers/activity_observer_spec.rb index 0db4a998..0eec41f4 100644 --- a/spec/observers/activity_observer_spec.rb +++ b/spec/observers/activity_observer_spec.rb @@ -1,17 +1,17 @@ require 'spec_helper' describe ActivityObserver do - let(:project) { Factory :project } + let(:project) { create(:project) } def self.it_should_be_valid_event it { @event.should_not be_nil } it { @event.project.should == project } end - describe "Merge Request created" do + describe "Merge Request created" do before do MergeRequest.observers.enable :activity_observer do - @merge_request = Factory :merge_request, project: project + @merge_request = create(:merge_request, project: project) @event = Event.last end end @@ -21,10 +21,10 @@ describe ActivityObserver do it { @event.target.should == @merge_request } end - describe "Issue created" do + describe "Issue created" do before do Issue.observers.enable :activity_observer do - @issue = Factory :issue, project: project + @issue = create(:issue, project: project) @event = Event.last end end @@ -34,10 +34,10 @@ describe ActivityObserver do it { @event.target.should == @issue } end - #describe "Issue commented" do - #before do - #@issue = Factory :issue, project: project - #@note = Factory :note, noteable: @issue, project: project + #describe "Issue commented" do + #before do + #@issue = create(:issue, project: project) + #@note = create(:note, noteable: @issue, project: project) #@event = Event.last #end diff --git a/spec/observers/issue_observer_spec.rb b/spec/observers/issue_observer_spec.rb index b5943f2c..509c1d02 100644 --- a/spec/observers/issue_observer_spec.rb +++ b/spec/observers/issue_observer_spec.rb @@ -16,7 +16,7 @@ describe IssueObserver do subject.should_receive(:after_create) Issue.observers.enable :issue_observer do - Factory.create(:issue, project: Factory.create(:project)) + create(:issue, project: create(:project)) end end @@ -43,7 +43,7 @@ describe IssueObserver do end it 'is called when an issue is changed' do - changed = Factory.create(:issue, project: Factory.create(:project)) + changed = create(:issue, project: create(:project)) subject.should_receive(:after_update) Issue.observers.enable :issue_observer do diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb index a9ba7927..6b15be96 100644 --- a/spec/observers/merge_request_observer_spec.rb +++ b/spec/observers/merge_request_observer_spec.rb @@ -16,7 +16,7 @@ describe MergeRequestObserver do subject.should_receive(:after_create) MergeRequest.observers.enable :merge_request_observer do - Factory.create(:merge_request, project: Factory.create(:project)) + create(:merge_request, project: create(:project)) end end @@ -43,7 +43,7 @@ describe MergeRequestObserver do end it 'is called when a merge request is changed' do - changed = Factory.create(:merge_request, project: Factory.create(:project)) + changed = create(:merge_request, project: create(:project)) subject.should_receive(:after_update) MergeRequest.observers.enable :merge_request_observer do diff --git a/spec/observers/note_observer_spec.rb b/spec/observers/note_observer_spec.rb index 203a58a4..7dfa9f77 100644 --- a/spec/observers/note_observer_spec.rb +++ b/spec/observers/note_observer_spec.rb @@ -13,7 +13,7 @@ describe NoteObserver do subject.should_receive :after_create Note.observers.enable :note_observer do - Factory.create(:note) + create(:note) end end diff --git a/spec/observers/user_observer_spec.rb b/spec/observers/user_observer_spec.rb index 0420a250..08254f44 100644 --- a/spec/observers/user_observer_spec.rb +++ b/spec/observers/user_observer_spec.rb @@ -4,7 +4,7 @@ describe UserObserver do subject { UserObserver.instance } it 'calls #after_create when new users are created' do - new_user = Factory.new(:user) + new_user = build(:user) subject.should_receive(:after_create).with(new_user) User.observers.enable :user_observer do diff --git a/spec/observers/users_project_observer_spec.rb b/spec/observers/users_project_observer_spec.rb index a8e0834b..cbe42248 100644 --- a/spec/observers/users_project_observer_spec.rb +++ b/spec/observers/users_project_observer_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' describe UsersProjectObserver do - let(:user) { Factory.create :user } - let(:project) { Factory.create(:project, - code: "Fuu", - path: "Fuu" ) } - let(:users_project) { Factory.create(:users_project, - project: project, - user: user )} + let(:user) { create(:user) } + let(:project) { create(:project, + code: "Fuu", + path: "Fuu" ) } + let(:users_project) { create(:users_project, + project: project, + user: user )} subject { UsersProjectObserver.instance } describe "#after_commit" do diff --git a/spec/requests/admin/admin_hooks_spec.rb b/spec/requests/admin/admin_hooks_spec.rb index 2f026aab..3f35b2fd 100644 --- a/spec/requests/admin/admin_hooks_spec.rb +++ b/spec/requests/admin/admin_hooks_spec.rb @@ -2,12 +2,12 @@ require 'spec_helper' describe "Admin::Hooks" do before do - @project = Factory :project, - name: "LeGiT", - code: "LGT" + @project = create(:project, + name: "LeGiT", + code: "LGT") login_as :admin - @system_hook = Factory :system_hook + @system_hook = create(:system_hook) end diff --git a/spec/requests/admin/admin_projects_spec.rb b/spec/requests/admin/admin_projects_spec.rb index 61e66eec..43e39d7c 100644 --- a/spec/requests/admin/admin_projects_spec.rb +++ b/spec/requests/admin/admin_projects_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe "Admin::Projects" do before do - @project = Factory :project, - name: "LeGiT", - code: "LGT" + @project = create(:project, + name: "LeGiT", + code: "LGT") login_as :admin end @@ -104,7 +104,7 @@ describe "Admin::Projects" do describe "Add new team member" do before do - @new_user = Factory :user + @new_user = create(:user) visit admin_project_path(@project) end diff --git a/spec/requests/admin/admin_users_spec.rb b/spec/requests/admin/admin_users_spec.rb index 68358bf0..9f43f07a 100644 --- a/spec/requests/admin/admin_users_spec.rb +++ b/spec/requests/admin/admin_users_spec.rb @@ -76,7 +76,7 @@ describe "Admin::Users" do describe "GET /admin/users/:id/edit" do before do - @simple_user = Factory :user + @simple_user = create(:user) visit admin_users_path click_link "edit_user_#{@simple_user.id}" end @@ -107,13 +107,13 @@ describe "Admin::Users" do end end - describe "Add new project" do - before do - @new_project = Factory :project + describe "Add new project" do + before do + @new_project = create(:project) visit admin_user_path(@user) end - it "should create new user" do + it "should create new user" do select @new_project.name, from: "project_ids" expect { click_button "Add" }.to change { UsersProject.count }.by(1) page.should have_content @new_project.name diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 442e9c73..6ea7e9b5 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Gitlab::API do include ApiHelpers - let(:user) { Factory :user } - let!(:project) { Factory :project, owner: user } - let!(:issue) { Factory :issue, author: user, assignee: user, project: project } + let(:user) { create(:user) } + let!(:project) { create(:project, owner: user) } + let!(:issue) { create(:issue, author: user, assignee: user, project: project) } before { project.add_access(user, :read) } describe "GET /issues" do diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index e1c7949f..e83f2467 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -1,11 +1,11 @@ require "spec_helper" -describe Gitlab::API do +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" } + + let(:user) { create(:user ) } + let!(:project) { create(:project, owner: user) } + let!(:merge_request) { create(:merge_request, author: user, assignee: user, project: project, title: "Test") } before { project.add_access(user, :read) } describe "GET /projects/:id/merge_requests" do @@ -39,7 +39,7 @@ describe Gitlab::API do 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' + json_response['title'].should == 'Test merge_request' end end @@ -47,7 +47,7 @@ describe Gitlab::API do it "should return merge_request" do put api("/projects/#{project.code}/merge_request/#{merge_request.id}", user), title: "New title" response.status.should == 200 - json_response['title'].should == 'New title' + json_response['title'].should == 'New title' end end @@ -55,7 +55,7 @@ describe Gitlab::API do it "should return comment" do 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' + json_response['note'].should == 'My comment' end end diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb index cf5f65f0..860825ab 100644 --- a/spec/requests/api/milestones_spec.rb +++ b/spec/requests/api/milestones_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Gitlab::API do include ApiHelpers - let(:user) { Factory :user } - let!(:project) { Factory :project, owner: user } - let!(:milestone) { Factory :milestone, project: project } + let(:user) { create(:user) } + let!(:project) { create(:project, owner: user) } + let!(:milestone) { create(:milestone, project: project) } before { project.add_access(user, :read) } diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 5f9a587d..d24ce43d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -3,14 +3,14 @@ require 'spec_helper' describe Gitlab::API do include ApiHelpers - let(:user) { Factory :user } - let(:user2) { Factory.create(:user) } - let(:user3) { Factory.create(:user) } - let!(:hook) { Factory :project_hook, project: project, url: "http://example.com" } - let!(:project) { Factory :project, owner: user } - let!(:snippet) { Factory :snippet, author: user, project: project, title: 'example' } - let!(:users_project) { Factory :users_project, user: user, project: project, project_access: UsersProject::MASTER } - let!(:users_project2) { Factory :users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER } + let(:user) { create(:user) } + let(:user2) { create(:user) } + let(:user3) { create(:user) } + let!(:hook) { create(:project_hook, project: project, url: "http://example.com") } + let!(:project) { create(:project, owner: user ) } + let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') } + let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } + let!(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) } before { project.add_access(user, :read) } describe "GET /projects" do @@ -52,7 +52,7 @@ describe Gitlab::API do end it "should assign attributes to project" do - project = Factory.attributes(:project, { + project = attributes_for(:project, { path: 'path', code: 'code', description: Faker::Lorem.sentence, diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb index f251f392..afae8be8 100644 --- a/spec/requests/api/session_spec.rb +++ b/spec/requests/api/session_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Gitlab::API do include ApiHelpers - let(:user) { Factory :user } + let(:user) { create(:user) } describe "POST /session" do context "when valid password" do diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb index 4c2e6ada..4cfb4884 100644 --- a/spec/requests/api/users_spec.rb +++ b/spec/requests/api/users_spec.rb @@ -3,9 +3,9 @@ require 'spec_helper' describe Gitlab::API do include ApiHelpers - let(:user) { Factory :user } - let(:admin) { Factory :admin } - let(:key) { Factory :key, user: user } + let(:user) { create(:user) } + let(:admin) { create(:admin) } + let(:key) { create(:key, user: user) } describe "GET /users" do context "when unauthenticated" do @@ -43,12 +43,12 @@ describe Gitlab::API do it "should create user" do expect { - post api("/users", admin), Factory.attributes(:user, projects_limit: 3) + post api("/users", admin), attributes_for(:user, projects_limit: 3) }.to change { User.count }.by(1) end it "shouldn't available for non admin users" do - post api("/users", user), Factory.attributes(:user) + post api("/users", user), attributes_for(:user) response.status.should == 403 end end @@ -103,7 +103,7 @@ describe Gitlab::API do end it "should create ssh key" do - key_attrs = Factory.attributes :key + key_attrs = attributes_for :key expect { post api("/user/keys", user), key_attrs }.to change{ user.keys.count }.by(1) diff --git a/spec/requests/atom/dashboard_issues_spec.rb b/spec/requests/atom/dashboard_issues_spec.rb index 8d1111fc..8ce64cd4 100644 --- a/spec/requests/atom/dashboard_issues_spec.rb +++ b/spec/requests/atom/dashboard_issues_spec.rb @@ -2,11 +2,11 @@ require 'spec_helper' describe "Dashboard Issues Feed" do describe "GET /issues" do - let!(:user) { Factory :user } - let!(:project1) { Factory :project } - let!(:project2) { Factory :project } - let!(:issue1) { Factory :issue, author: user, assignee: user, project: project1 } - let!(:issue2) { Factory :issue, author: user, assignee: user, project: project2 } + let!(:user) { create(:user) } + let!(:project1) { create(:project) } + let!(:project2) { create(:project) } + let!(:issue1) { create(:issue, author: user, assignee: user, project: project1) } + let!(:issue2) { create(:issue, author: user, assignee: user, project: project2) } describe "atom feed" do it "should render atom feed via private token" do diff --git a/spec/requests/atom/dashboard_spec.rb b/spec/requests/atom/dashboard_spec.rb index c160d24a..6257ad5c 100644 --- a/spec/requests/atom/dashboard_spec.rb +++ b/spec/requests/atom/dashboard_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe "Dashboard Feed" do describe "GET /" do - let!(:user) { Factory :user } + let!(:user) { create(:user) } context "projects atom feed via private token" do it "should render projects atom feed" do diff --git a/spec/requests/atom/issues_spec.rb b/spec/requests/atom/issues_spec.rb index c8671979..29f88f3f 100644 --- a/spec/requests/atom/issues_spec.rb +++ b/spec/requests/atom/issues_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe "Issues Feed" do describe "GET /issues" do - let!(:user) { Factory :user } - let!(:project) { Factory :project, owner: user } - let!(:issue) { Factory :issue, author: user, project: project } + let!(:user) { create(:user) } + let!(:project) { create(:project, owner: user) } + let!(:issue) { create(:issue, author: user, project: project) } before { project.add_access(user, :read, :write) } diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb index 014f99eb..aedd435e 100644 --- a/spec/requests/gitlab_flavored_markdown_spec.rb +++ b/spec/requests/gitlab_flavored_markdown_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' describe "Gitlab Flavored Markdown" do - let(:project) { Factory :project } - let(:issue) { Factory :issue, project: project } - let(:merge_request) { Factory :merge_request, project: project } + let(:project) { create(:project) } + let(:issue) { create(:issue, project: project) } + let(:merge_request) { create(:merge_request, project: project) } let(:fred) do - u = Factory :user, name: "fred" + u = create(:user, name: "fred") project.users << u u end @@ -84,16 +84,16 @@ describe "Gitlab Flavored Markdown" do describe "for issues" do before do - @other_issue = Factory :issue, + @other_issue = create(:issue, + author: @user, + assignee: @user, + project: project) + @issue = create(:issue, author: @user, assignee: @user, - project: project - @issue = Factory :issue, - author: @user, - assignee: @user, - project: project, - title: "fix ##{@other_issue.id}", - description: "ask @#{fred.name} for details" + project: project, + title: "fix ##{@other_issue.id}", + description: "ask @#{fred.name} for details") end it "should render subject in issues#index" do @@ -118,9 +118,9 @@ describe "Gitlab Flavored Markdown" do describe "for merge requests" do before do - @merge_request = Factory :merge_request, - project: project, - title: "fix ##{issue.id}" + @merge_request = create(:merge_request, + project: project, + title: "fix ##{issue.id}") end it "should render title in merge_requests#index" do @@ -139,10 +139,10 @@ describe "Gitlab Flavored Markdown" do describe "for milestones" do before do - @milestone = Factory :milestone, - project: project, - title: "fix ##{issue.id}", - description: "ask @#{fred.name} for details" + @milestone = create(:milestone, + project: project, + title: "fix ##{issue.id}", + description: "ask @#{fred.name} for details") end it "should render title in milestones#index" do diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb index 15ee5d17..c95409d3 100644 --- a/spec/requests/issues_spec.rb +++ b/spec/requests/issues_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' describe "Issues" do - let(:project) { Factory :project } + let(:project) { create(:project) } before do login_as :user - @user2 = Factory :user + @user2 = create(:user) project.add_access(@user, :read, :write) project.add_access(@user2, :read, :write) @@ -13,10 +13,10 @@ describe "Issues" do describe "Edit issue", js: true do before do - @issue = Factory :issue, - author: @user, - assignee: @user, - project: project + @issue = create(:issue, + author: @user, + assignee: @user, + project: project) visit project_issues_path(project) click_link "Edit" end @@ -46,11 +46,11 @@ describe "Issues" do describe "Search issue", js: true do before do ['foobar', 'foobar2', 'gitlab'].each do |title| - @issue = Factory :issue, - author: @user, - assignee: @user, - project: project, - title: title + @issue = create(:issue, + author: @user, + assignee: @user, + project: project, + title: title) @issue.save end end @@ -93,15 +93,15 @@ describe "Issues" do describe "Filter issue" do before do ['foobar', 'barbaz', 'gitlab'].each do |title| - @issue = Factory :issue, - author: @user, - assignee: @user, - project: project, - title: title + @issue = create(:issue, + author: @user, + assignee: @user, + project: project, + title: title) end @issue = Issue.first - @issue.milestone = Factory(:milestone, project: project) + @issue.milestone = create(:milestone, project: project) @issue.assignee = nil @issue.save end diff --git a/spec/requests/projects_deploy_keys_spec.rb b/spec/requests/projects_deploy_keys_spec.rb index df1be79d..35323f55 100644 --- a/spec/requests/projects_deploy_keys_spec.rb +++ b/spec/requests/projects_deploy_keys_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe "Projects", "DeployKeys" do - let(:project) { Factory :project } + let(:project) { create(:project) } before do login_as :user @@ -10,7 +10,7 @@ describe "Projects", "DeployKeys" do describe "GET /keys" do before do - @key = Factory :key, project: project + @key = create(:key, project: project) visit project_deploy_keys_path(project) end @@ -57,7 +57,7 @@ describe "Projects", "DeployKeys" do describe "Show page" do before do - @key = Factory :key, project: project + @key = create(:key, project: project) visit project_deploy_key_path(project, @key) end diff --git a/spec/requests/projects_spec.rb b/spec/requests/projects_spec.rb index 92e89a16..c44bea89 100644 --- a/spec/requests/projects_spec.rb +++ b/spec/requests/projects_spec.rb @@ -6,7 +6,7 @@ describe "Projects" do describe 'GET /project/new' do it "should work autocomplete", :js => true do visit new_project_path - + fill_in 'project_name', with: 'Awesome' find("#project_path").value.should == 'awesome' find("#project_code").value.should == 'awesome' @@ -15,7 +15,7 @@ describe "Projects" do describe "GET /projects/show" do before do - @project = Factory :project, owner: @user + @project = create(:project, owner: @user) @project.add_access(@user, :read) visit project_path(@project) @@ -28,7 +28,7 @@ describe "Projects" do describe "GET /projects/:id/edit" do before do - @project = Factory :project + @project = create(:project) @project.add_access(@user, :admin, :read) visit edit_project_path(@project) @@ -47,7 +47,7 @@ describe "Projects" do describe "PUT /projects/:id" do before do - @project = Factory :project, owner: @user + @project = create(:project, owner: @user) @project.add_access(@user, :admin, :read) visit edit_project_path(@project) @@ -69,7 +69,7 @@ describe "Projects" do describe "DELETE /projects/:id" do before do - @project = Factory :project + @project = create(:project) @project.add_access(@user, :read, :admin) visit edit_project_path(@project) end diff --git a/spec/requests/search_spec.rb b/spec/requests/search_spec.rb index 537c4d0c..17cc0d39 100644 --- a/spec/requests/search_spec.rb +++ b/spec/requests/search_spec.rb @@ -3,14 +3,14 @@ require 'spec_helper' describe "Search" do before do login_as :user - @project = Factory :project + @project = create(:project) @project.add_access(@user, :read) visit search_path fill_in "search", with: @project.name[0..3] click_button "Search" end - it "should show project in search results" do + it "should show project in search results" do page.should have_content @project.name end end diff --git a/spec/requests/security/profile_access_spec.rb b/spec/requests/security/profile_access_spec.rb index 69c1c29c..8562b8e7 100644 --- a/spec/requests/security/profile_access_spec.rb +++ b/spec/requests/security/profile_access_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe "Users Security" do describe "Project" do before do - @u1 = Factory :user + @u1 = create(:user) end describe "GET /login" do diff --git a/spec/requests/snippets_spec.rb b/spec/requests/snippets_spec.rb index 6b993660..9ef217ba 100644 --- a/spec/requests/snippets_spec.rb +++ b/spec/requests/snippets_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe "Snippets" do - let(:project) { Factory :project } + let(:project) { create(:project) } before do login_as :user @@ -10,9 +10,9 @@ describe "Snippets" do describe "GET /snippets" do before do - @snippet = Factory :snippet, - author: @user, - project: project + @snippet = create(:snippet, + author: @user, + project: project) visit project_snippets_path(project) end @@ -68,9 +68,9 @@ describe "Snippets" do describe "Edit snippet" do before do - @snippet = Factory :snippet, - author: @user, - project: project + @snippet = create(:snippet, + author: @user, + project: project) visit project_snippet_path(project, @snippet) click_link "Edit" end diff --git a/spec/support/login_helpers.rb b/spec/support/login_helpers.rb index 769034e2..4579c971 100644 --- a/spec/support/login_helpers.rb +++ b/spec/support/login_helpers.rb @@ -3,7 +3,7 @@ module LoginHelpers # # role - User role (e.g., :admin, :user) def login_as(role) - @user = Factory(role) + @user = create(role) login_with(@user) end diff --git a/spec/support/matchers.rb b/spec/support/matchers.rb index 809453c4..29d16ecb 100644 --- a/spec/support/matchers.rb +++ b/spec/support/matchers.rb @@ -59,9 +59,9 @@ module UrlAccess def emulate_user(user) user = case user - when :user then Factory(:user) + when :user then create(:user) when :visitor then nil - when :admin then Factory(:admin) + when :admin then create(:admin) else user end login_with(user) if user diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 6f4bcca2..22e3e0d0 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -9,8 +9,8 @@ describe PostReceive do end context "web hook" do - let(:project) { Factory.create(:project) } - let(:key) { Factory.create(:key, user: project.owner) } + let(:project) { create(:project) } + let(:key) { create(:key, user: project.owner) } let(:key_id) { key.identifier } it "fetches the correct project" do From f0a6fbaae3b8d06c43eef6879afbcbbfdca52f1d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 13 Nov 2012 21:26:36 +0200 Subject: [PATCH 131/187] Improve Commits stats code --- app/views/repositories/stats.html.haml | 8 +++++--- lib/gitlab/git_stats.rb | 15 ++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml index a0a9377d..a93814a4 100644 --- a/app/views/repositories/stats.html.haml +++ b/app/views/repositories/stats.html.haml @@ -2,12 +2,12 @@ .row .span5 %h4 - Stats for #{@project.root_ref}: + Stats: %p %b Total commits: %span= @stats.commits_count %p - %b Total files: + %b Total files in #{@project.root_ref}: %span= @stats.files_count %p %b Authors: @@ -30,10 +30,12 @@ :javascript $(function(){ var labels = [#{@graph.labels.to_json}]; + var commits = [#{@graph.commits.join(', ')}]; 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(', ')}]] + [commits], + {colors:["#456"]} ).label(labels, true); }) diff --git a/lib/gitlab/git_stats.rb b/lib/gitlab/git_stats.rb index 94374869..855bffb5 100644 --- a/lib/gitlab/git_stats.rb +++ b/lib/gitlab/git_stats.rb @@ -15,7 +15,8 @@ module Gitlab end def files_count - repo.git.sh("git ls-tree -r --name-only #{ref} | wc -l").first.to_i + args = [ref, '-r', '--name-only' ] + repo.git.run(nil, 'ls-tree', nil, {}, args).split("\n").count end def authors_count @@ -52,15 +53,11 @@ module Gitlab def build_graph n = 4 from, to = (Date.today - n.weeks), Date.today + args = ['--all', "--since=#{from.to_s(:date)}", '--format=%ad' ] + rev_list = repo.git.run(nil, 'rev-list', nil, {}, args).split("\n") - 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_dates = rev_list.values_at(* rev_list.each_index.select {|i| i.odd?}) + commits_dates = commits_dates.map { |date_str| Time.parse(date_str).to_date.to_s(:date) } commits_per_day = from.upto(to).map do |day| commits_dates.count(day.to_date.to_s(:date)) From a85e11fa51497888684f247bc09450cbcc67a058 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 13 Nov 2012 22:11:56 +0200 Subject: [PATCH 132/187] Improved seeds for development env --- db/fixtures/development/002_project.rb | 6 +- db/fixtures/development/004_teams.rb | 6 ++ db/fixtures/development/006_wall.rb | 55 ++++++------------- db/fixtures/development/007_issues.rb | 37 +++++++------ db/fixtures/development/008_merge_requests.rb | 41 +++++++------- db/fixtures/development/009_source_code.rb | 27 +++++++++ lib/gitlab/seeder.rb | 10 ++++ 7 files changed, 105 insertions(+), 77 deletions(-) create mode 100644 db/fixtures/development/009_source_code.rb create mode 100644 lib/gitlab/seeder.rb diff --git a/db/fixtures/development/002_project.rb b/db/fixtures/development/002_project.rb index eea987ff..eb68b5fe 100644 --- a/db/fixtures/development/002_project.rb +++ b/db/fixtures/development/002_project.rb @@ -1,5 +1,5 @@ Project.seed(:id, [ - { :id => 1, :name => "Rubinius", :path => "rubinius", :code => "rubinius", :owner_id => 1 }, - { :id => 2, :name => "Diaspora", :path => "diaspora", :code => "diaspora", :owner_id => 1 }, - { :id => 3, :name => "Ruby on Rails", :path => "ruby_on_rails", :code => "ruby_on_rails", :owner_id => 1 } + { id: 1, name: "Underscore.js", path: "underscore", code: "underscore", owner_id: 1 }, + { id: 2, name: "Diaspora", path: "diaspora", code: "diaspora", owner_id: 1 }, + { id: 3, name: "Ruby on Rails", path: "rails", code: "rails", owner_id: 1 } ]) diff --git a/db/fixtures/development/004_teams.rb b/db/fixtures/development/004_teams.rb index 5af98b92..2752cb44 100644 --- a/db/fixtures/development/004_teams.rb +++ b/db/fixtures/development/004_teams.rb @@ -1,3 +1,5 @@ +UsersProject.skip_callback(:save, :after, :update_repository) + UsersProject.seed(:id, [ { :id => 1, :project_id => 1, :user_id => 1, :project_access => UsersProject::MASTER }, { :id => 2, :project_id => 1, :user_id => 2, :project_access => UsersProject::REPORTER}, @@ -18,4 +20,8 @@ UsersProject.seed(:id, [ { :id => 16, :project_id => 3, :user_id => 5, :project_access => UsersProject::MASTER} ]) +UsersProject.set_callback(:save, :after, :update_repository) +puts "\nRebuild gitolite\n".yellow +Project.all.each(&:update_repository) +puts "OK".green diff --git a/db/fixtures/development/006_wall.rb b/db/fixtures/development/006_wall.rb index 7c0d25d1..a9fb66dd 100644 --- a/db/fixtures/development/006_wall.rb +++ b/db/fixtures/development/006_wall.rb @@ -1,40 +1,19 @@ -Note.seed(:id, [ - { :id => 1, :project_id => 1, :author_id => 1, :note => Faker::Lorem.sentence(6) }, - { :id => 2, :project_id => 1, :author_id => 2, :note => Faker::Lorem.sentence(6) }, - { :id => 3, :project_id => 1, :author_id => 3, :note => Faker::Lorem.sentence(6) }, - { :id => 4, :project_id => 1, :author_id => 4, :note => Faker::Lorem.sentence(6) }, - { :id => 5, :project_id => 1, :author_id => 5, :note => Faker::Lorem.sentence(6) }, - - { :id => 6, :project_id => 2, :author_id => 1, :note => Faker::Lorem.sentence(6) }, - { :id => 7, :project_id => 2, :author_id => 2, :note => Faker::Lorem.sentence(6) }, - { :id => 8, :project_id => 2, :author_id => 3, :note => Faker::Lorem.sentence(6) }, - { :id => 9, :project_id => 2, :author_id => 4, :note => Faker::Lorem.sentence(6) }, - { :id => 11, :project_id => 2, :author_id => 5, :note => Faker::Lorem.sentence(6) }, - - { :id => 12, :project_id => 3, :author_id => 1, :note => Faker::Lorem.sentence(6)}, - { :id => 13, :project_id => 3, :author_id => 2, :note => Faker::Lorem.sentence(6)}, - { :id => 14, :project_id => 3, :author_id => 3, :note => Faker::Lorem.sentence(6)}, - { :id => 15, :project_id => 3, :author_id => 4, :note => Faker::Lorem.sentence(6)}, - { :id => 16, :project_id => 3, :author_id => 5, :note => Faker::Lorem.sentence(6)}, - - { :id => 21, :project_id => 1, :author_id => 1, :note => Faker::Lorem.sentence(6) }, - { :id => 22, :project_id => 1, :author_id => 2, :note => Faker::Lorem.sentence(6) }, - { :id => 23, :project_id => 1, :author_id => 3, :note => Faker::Lorem.sentence(6) }, - { :id => 24, :project_id => 1, :author_id => 4, :note => Faker::Lorem.sentence(6) }, - { :id => 25, :project_id => 1, :author_id => 5, :note => Faker::Lorem.sentence(6) }, - - { :id => 26, :project_id => 2, :author_id => 1, :note => Faker::Lorem.sentence(6) }, - { :id => 27, :project_id => 2, :author_id => 2, :note => Faker::Lorem.sentence(6) }, - { :id => 28, :project_id => 2, :author_id => 3, :note => Faker::Lorem.sentence(6) }, - { :id => 29, :project_id => 2, :author_id => 4, :note => Faker::Lorem.sentence(6) }, - { :id => 30, :project_id => 2, :author_id => 5, :note => Faker::Lorem.sentence(6) }, - - { :id => 32, :project_id => 3, :author_id => 1, :note => Faker::Lorem.sentence(6)}, - { :id => 33, :project_id => 3, :author_id => 2, :note => Faker::Lorem.sentence(6)}, - { :id => 34, :project_id => 3, :author_id => 3, :note => Faker::Lorem.sentence(6)}, - { :id => 35, :project_id => 3, :author_id => 4, :note => Faker::Lorem.sentence(6)}, - { :id => 36, :project_id => 3, :author_id => 5, :note => Faker::Lorem.sentence(6)} -]) - +Gitlab::Seeder.quiet do + (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 + Note.seed(:id, [{ + id: i, + project_id: project_id, + author_id: user_id, + note: Faker::Lorem.sentence(6) + }]) + print('.') + end +end diff --git a/db/fixtures/development/007_issues.rb b/db/fixtures/development/007_issues.rb index d60af71e..98e32fcc 100644 --- a/db/fixtures/development/007_issues.rb +++ b/db/fixtures/development/007_issues.rb @@ -1,20 +1,23 @@ -(1..300).each do |i| - # Random Project - project_id = rand(2) + 1 - project = Project.find(project_id) +Gitlab::Seeder.quiet do + (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 + # 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) - }]) + 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) + }]) + print('.') + end end diff --git a/db/fixtures/development/008_merge_requests.rb b/db/fixtures/development/008_merge_requests.rb index 8d20e628..698c55ad 100644 --- a/db/fixtures/development/008_merge_requests.rb +++ b/db/fixtures/development/008_merge_requests.rb @@ -1,22 +1,25 @@ -(1..300).each do |i| - # Random Project - project_id = rand(2) + 1 - project = Project.find(project_id) +Gitlab::Seeder.quiet do + (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 - MergeRequestObserver.current_user = user + # Random user + user = project.users.sample + user_id = user.id + MergeRequestObserver.current_user = user - 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) - }]) + 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) + }]) + print('.') + end end diff --git a/db/fixtures/development/009_source_code.rb b/db/fixtures/development/009_source_code.rb new file mode 100644 index 00000000..489bd02e --- /dev/null +++ b/db/fixtures/development/009_source_code.rb @@ -0,0 +1,27 @@ +root = Gitlab.config.git_base_path + +projects = [ + { path: 'underscore.git', git: 'https://github.com/documentcloud/underscore.git' }, + { path: 'diaspora.git', git: 'https://github.com/diaspora/diaspora.git' }, + { path: 'rails.git', git: 'https://github.com/rails/rails.git' }, +] + +projects.each do |project| + project_path = File.join(root, project[:path]) + + + next if File.exists?(project_path) + + cmds = [ + "cd #{root} && sudo -u git -H git clone --bare #{project[:git]}", + "sudo cp ./lib/hooks/post-receive #{project_path}/hooks/post-receive", + "sudo chown git:git #{project_path}/hooks/post-receive" + ] + + cmds.each do |cmd| + puts cmd.yellow + `#{cmd}` + end +end + +puts "OK".green diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb new file mode 100644 index 00000000..3aa3b2ba --- /dev/null +++ b/lib/gitlab/seeder.rb @@ -0,0 +1,10 @@ +module Gitlab + class Seeder + def self.quiet + SeedFu.quiet = true + yield + SeedFu.quiet = false + puts "\nOK".green + end + end +end From 578cf89812fc12e99e22a3da83aaca89e7c8d430 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 14 Nov 2012 01:20:37 +0100 Subject: [PATCH 133/187] Fix specs --- app/assets/javascripts/issues.js | 8 +-- app/models/milestone.rb | 1 + .../steps/project/project_browse_commits.rb | 3 +- spec/models/issue_spec.rb | 1 - spec/requests/issues_spec.rb | 61 ++++++++++--------- spec/roles/issue_commonality_spec.rb | 1 + 6 files changed, 39 insertions(+), 36 deletions(-) diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js index db3ad7f7..55db72c3 100644 --- a/app/assets/javascripts/issues.js +++ b/app/assets/javascripts/issues.js @@ -39,10 +39,10 @@ function backToIssues(){ } function initIssuesSearch() { - var href = $('.issue_search').parent().attr('action'); + var href = $('#issue_search_form').attr('action'); var last_terms = ''; - $('.issue_search').keyup(function() { + $('#issue_search').keyup(function() { var terms = $(this).val(); var milestone_id = $('#milestone_id').val(); var status = $('#status').val(); @@ -57,10 +57,6 @@ function initIssuesSearch() { } } }); - - $('.delete-issue').live('ajax:success', function() { - $(this).closest('tr').fadeOut(); updatePage(); - }); } /** diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 41412a13..1dcc93bf 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -7,6 +7,7 @@ class Milestone < ActiveRecord::Base validates :title, presence: true validates :project, presence: true + validates :closed, inclusion: { in: [true, false] } def self.active where("due_date > ? OR due_date IS NULL", Date.today) diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb index 428c14a8..6bf164e2 100644 --- a/features/steps/project/project_browse_commits.rb +++ b/features/steps/project/project_browse_commits.rb @@ -53,8 +53,9 @@ class ProjectBrowseCommits < Spinach::FeatureSteps end Then 'I see commits stats' do - page.should have_content 'Stats for master' + page.should have_content 'Stats' page.should have_content 'Committers' page.should have_content 'Total commits' + page.should have_content 'Authors' end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 4e999aad..9c69f868 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -30,7 +30,6 @@ describe Issue do describe "Validation" do it { should ensure_length_of(:description).is_within(0..2000) } - it { should ensure_inclusion_of(:closed).in_array([true, false]) } end describe 'modules' do diff --git a/spec/requests/issues_spec.rb b/spec/requests/issues_spec.rb index c95409d3..ff4d4c8b 100644 --- a/spec/requests/issues_spec.rb +++ b/spec/requests/issues_spec.rb @@ -5,24 +5,27 @@ describe "Issues" do before do login_as :user - @user2 = create(:user) + user2 = create(:user) project.add_access(@user, :read, :write) - project.add_access(@user2, :read, :write) + project.add_access(user2, :read, :write) end describe "Edit issue", js: true do + let!(:issue) do + create(:issue, + author: @user, + assignee: @user, + project: project) + end + before do - @issue = create(:issue, - author: @user, - assignee: @user, - project: project) visit project_issues_path(project) click_link "Edit" end it "should open new issue popup" do - page.should have_content("Issue ##{@issue.id}") + page.should have_content("Issue ##{issue.id}") end describe "fill in" do @@ -46,19 +49,18 @@ describe "Issues" do describe "Search issue", js: true do before do ['foobar', 'foobar2', 'gitlab'].each do |title| - @issue = create(:issue, - author: @user, - assignee: @user, - project: project, - title: title) - @issue.save + create(:issue, + author: @user, + assignee: @user, + project: project, + title: title) end end it "should be able to search on different statuses" do - @issue = Issue.first - @issue.closed = true - @issue.save + issue = Issue.first # with title 'foobar' + issue.closed = true + issue.save visit project_issues_path(project) click_link 'Closed' @@ -81,8 +83,9 @@ describe "Issues" do it "should return all results if term has been cleared" do visit project_issues_path(project) fill_in "issue_search", with: "foobar" - # Because fill_in, with: "" triggers nothing we need to trigger a keyup event - page.execute_script("$('.issue_search').val('').keyup();"); + # Reset the search field and trigger loading the issues + fill_in "issue_search", with: "" + page.execute_script("$('#issue_search').keyup();"); page.should have_content 'foobar' page.should have_content 'foobar2' @@ -93,19 +96,21 @@ describe "Issues" do describe "Filter issue" do before do ['foobar', 'barbaz', 'gitlab'].each do |title| - @issue = create(:issue, - author: @user, - assignee: @user, - project: project, - title: title) + create(:issue, + author: @user, + assignee: @user, + project: project, + title: title) end - @issue = Issue.first - @issue.milestone = create(:milestone, project: project) - @issue.assignee = nil - @issue.save + issue = Issue.first # with title 'foobar' + issue.milestone = create(:milestone, project: project) + issue.assignee = nil + issue.save end + let(:issue) { Issue.first } + it "should allow filtering by issues with no specified milestone" do visit project_issues_path(project, milestone_id: '0') @@ -115,7 +120,7 @@ describe "Issues" do end it "should allow filtering by a specified milestone" do - visit project_issues_path(project, milestone_id: @issue.milestone.id) + visit project_issues_path(project, milestone_id: issue.milestone.id) page.should have_content 'foobar' page.should_not have_content 'barbaz' diff --git a/spec/roles/issue_commonality_spec.rb b/spec/roles/issue_commonality_spec.rb index fc4114e3..11f278de 100644 --- a/spec/roles/issue_commonality_spec.rb +++ b/spec/roles/issue_commonality_spec.rb @@ -15,6 +15,7 @@ describe Issue, "IssueCommonality" do it { should validate_presence_of(:author) } it { should validate_presence_of(:title) } it { should ensure_length_of(:title).is_at_least(0).is_at_most(255) } + it { should ensure_inclusion_of(:closed).in_array([true, false]) } end describe "Scope" do From 433d2278e0a9228ba8142dfb6b69df900654158d Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 14 Nov 2012 13:14:46 +0200 Subject: [PATCH 134/187] Rails up to 3.2.9 --- Gemfile | 2 +- Gemfile.lock | 67 ++++++++++++++++++++++++++-------------------------- 2 files changed, 35 insertions(+), 34 deletions(-) diff --git a/Gemfile b/Gemfile index 475b6e8e..047555a0 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ def linux_only(require_as) RUBY_PLATFORM.include?('linux') && require_as end -gem "rails", "3.2.8" +gem "rails", "3.2.9" # Supported DBs gem "sqlite3", group: :sqlite diff --git a/Gemfile.lock b/Gemfile.lock index b67f5856..cc6a13be 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -51,31 +51,31 @@ GIT GEM remote: http://rubygems.org/ specs: - actionmailer (3.2.8) - actionpack (= 3.2.8) + actionmailer (3.2.9) + actionpack (= 3.2.9) mail (~> 2.4.4) - actionpack (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) + actionpack (3.2.9) + activemodel (= 3.2.9) + activesupport (= 3.2.9) builder (~> 3.0.0) erubis (~> 2.7.0) journey (~> 1.0.4) rack (~> 1.4.0) rack-cache (~> 1.2) rack-test (~> 0.6.1) - sprockets (~> 2.1.3) - activemodel (3.2.8) - activesupport (= 3.2.8) + sprockets (~> 2.2.1) + activemodel (3.2.9) + activesupport (= 3.2.9) builder (~> 3.0.0) - activerecord (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) + activerecord (3.2.9) + activemodel (= 3.2.9) + activesupport (= 3.2.9) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - activesupport (3.2.8) + activeresource (3.2.9) + activemodel (= 3.2.9) + activesupport (= 3.2.9) + activesupport (3.2.9) i18n (~> 0.6) multi_json (~> 1.0) acts-as-taggable-on (2.3.1) @@ -86,7 +86,7 @@ GEM bcrypt-ruby (3.0.1) blankslate (2.1.2.4) bootstrap-sass (2.0.4.0) - builder (3.0.2) + builder (3.0.4) capybara (1.1.2) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -227,7 +227,7 @@ GEM mime-types (1.19) modernizr (2.5.3) sprockets (~> 2.0) - multi_json (1.3.6) + multi_json (1.3.7) multi_xml (0.5.1) multipart-post (1.1.5) mysql2 (0.3.11) @@ -283,28 +283,28 @@ GEM rack rack-ssl (1.3.2) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - rails (3.2.8) - actionmailer (= 3.2.8) - actionpack (= 3.2.8) - activerecord (= 3.2.8) - activeresource (= 3.2.8) - activesupport (= 3.2.8) + rails (3.2.9) + actionmailer (= 3.2.9) + actionpack (= 3.2.9) + activerecord (= 3.2.9) + activeresource (= 3.2.9) + activesupport (= 3.2.9) bundler (~> 1.0) - railties (= 3.2.8) + railties (= 3.2.9) rails-dev-tweaks (0.6.1) actionpack (~> 3.1) railties (~> 3.1) - railties (3.2.8) - actionpack (= 3.2.8) - activesupport (= 3.2.8) + railties (3.2.9) + actionpack (= 3.2.9) + activesupport (= 3.2.9) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) raindrops (0.9.0) - rake (0.9.2.2) + rake (10.0.0) raphael-rails (1.5.2) rb-fsevent (0.9.1) rb-inotify (0.8.8) @@ -375,8 +375,9 @@ GEM capybara (~> 1) railties (>= 3) spinach (>= 0.4) - sprockets (2.1.3) + sprockets (2.2.1) hike (~> 1.2) + multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.6) @@ -390,10 +391,10 @@ GEM rack (>= 1.0.0) thor (0.16.0) tilt (1.3.3) - treetop (1.4.10) + treetop (1.4.12) polyglot polyglot (>= 0.3.1) - tzinfo (0.3.33) + tzinfo (0.3.35) uglifier (1.0.3) execjs (>= 0.3.0) multi_json (>= 1.0.2) @@ -468,7 +469,7 @@ DEPENDENCIES pygments.rb (= 0.3.1) quiet_assets (= 1.0.1) rack-mini-profiler - rails (= 3.2.8) + rails (= 3.2.9) rails-dev-tweaks raphael-rails (= 1.5.2) rb-fsevent From ece563296bcac93ce5918a050a70a95ceba0d7f9 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 14 Nov 2012 14:36:51 +0100 Subject: [PATCH 135/187] Fix Notes JS Also fixes #1983 --- app/assets/javascripts/main.js.coffee | 19 -------------- app/assets/javascripts/notes.js | 36 +++++++++++++++++++++------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index 04e6b2ef..b41651bf 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -58,25 +58,6 @@ $ -> $(@).next('table').show() $(@).remove() - # Note markdown preview - $(document).on 'click', '#preview-link', (e) -> - $('#preview-note').text 'Loading...' - - previewLinkText = if $(@).text() is 'Preview' then 'Edit' else 'Preview' - $(@).text previewLinkText - - note = $('#note_note').val() - - if note.trim().length is 0 - $('#preview-note').text 'Nothing to preview.' - else - $.post $(@).attr('href'), {note: note}, (data) -> - $('#preview-note').html(data) - - $('#preview-note, #note_note').toggle() - e.preventDefault() - false - (($) -> _chosen = $.fn.chosen $.fn.extend chosen: (options) -> diff --git a/app/assets/javascripts/notes.js b/app/assets/javascripts/notes.js index 558643d5..b6f65b7a 100644 --- a/app/assets/javascripts/notes.js +++ b/app/assets/javascripts/notes.js @@ -14,8 +14,8 @@ var NoteList = { this.notes_path = path + ".js"; this.target_id = tid; this.target_type = tt; - this.reversed = $("#notes-list").hasClass("reversed"); - this.target_params = "&target_type=" + this.target_type + "&target_id=" + this.target_id; + this.reversed = $("#notes-list").is(".reversed"); + this.target_params = "target_type=" + this.target_type + "&target_id=" + this.target_id; // get initial set of notes this.getContent(); @@ -33,6 +33,8 @@ var NoteList = { $(".note-form-holder").on("ajax:complete", function(){ $(".submit_note").enable(); + $('#preview-note').hide(); + $('#note_note').show(); }) disableButtonIfEmptyField(".note-text", ".submit_note"); @@ -52,6 +54,26 @@ var NoteList = { $('.note_advanced_opts').show(); }); } + + // Setup note preview + $(document).on('click', '#preview-link', function(e) { + $('#preview-note').text('Loading...'); + + $(this).text($(this).text() === "Edit" ? "Preview" : "Edit"); + + var note_text = $('#note_note').val(); + + if(note_text.trim().length === 0) { + $('#preview-note').text('Nothing to preview.'); + } else { + $.post($(this).attr('href'), {note: note_text}).success(function(data) { + $('#preview-note').html(data); + }); + } + + $('#preview-note, #note_note').toggle(); + e.preventDefault(); + }); }, @@ -69,7 +91,7 @@ var NoteList = { $.ajax({ type: "GET", url: this.notes_path, - data: "?" + this.target_params, + data: this.target_params, complete: function(){ $('.notes-status').removeClass("loading")}, beforeSend: function() { $('.notes-status').addClass("loading") }, dataType: "script"}); @@ -131,7 +153,7 @@ var NoteList = { $.ajax({ type: "GET", url: this.notes_path, - data: "loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id + this.target_params, + data: this.target_params + "&loading_more=1&" + (this.reversed ? "before_id" : "after_id") + "=" + this.bottom_id, complete: function(){ $('.notes-status').removeClass("loading")}, beforeSend: function() { $('.notes-status').addClass("loading") }, dataType: "script"}); @@ -192,7 +214,7 @@ var NoteList = { $.ajax({ type: "GET", url: this.notes_path, - data: "loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id) + this.target_params, + data: this.target_params + "&loading_new=1&after_id=" + (this.reversed ? this.top_id : this.bottom_id), dataType: "script"}); }, @@ -264,7 +286,7 @@ var PerLineNotes = { $(this).closest("tr").after(form); form.find("#note_line_code").val($(this).data("lineCode")); form.show(); - return false; + e.preventDefault(); }); disableButtonIfEmptyField(".line-note-text", ".submit_inline_note"); @@ -285,7 +307,7 @@ var PerLineNotes = { // elements must really be removed for this to work reliably var trLine = trNote.prev(); var trRpl = trNote.next(); - if (trLine.hasClass("line_holder") && trRpl.hasClass("reply")) { + if (trLine.is(".line_holder") && trRpl.is(".reply")) { trRpl.fadeOut(function() { $(this).remove(); }); } }); From 8a2b1369483e175f5ac8b4247852e6ab119db7ae Mon Sep 17 00:00:00 2001 From: Greg Barendt Date: Wed, 14 Nov 2012 13:33:22 -0500 Subject: [PATCH 136/187] Update doc/development.md Fixed a typo. --- doc/development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development.md b/doc/development.md index 179c708d..b7213adc 100644 --- a/doc/development.md +++ b/doc/development.md @@ -18,7 +18,7 @@ Install the Gitlab development in a virtual machine with the [Gitlab Vagrant vir bundle exec rake environment resque:work QUEUE=* VVERBOSE=1 -### Test DB seutup & seed +### Test DB setup & seed bundle exec rake db:setup RAILS_ENV=test bundle exec rake db:seed_fu RAILS_ENV=test From ba25b2dc84cc25e66d6fa1450fee39c9bac002c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 16 Nov 2012 12:27:39 +0200 Subject: [PATCH 137/187] Use poltergeist instaead of capybara-webkit --- Gemfile | 5 +++-- Gemfile.lock | 16 +++++++++------ features/steps/project/project_issues.rb | 3 +-- features/support/env.rb | 25 +++++++++++++++++++++--- spec/spec_helper.rb | 10 ++-------- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index 047555a0..aaf1f000 100644 --- a/Gemfile +++ b/Gemfile @@ -123,8 +123,6 @@ group :development, :test do gem 'spinach-rails' gem "rspec-rails" gem "capybara" - gem "capybara-webkit" - gem "headless" gem "pry" gem "awesome_print" gem "database_cleaner" @@ -139,6 +137,9 @@ group :development, :test do gem 'rb-fsevent', require: darwin_only('rb-fsevent') gem 'growl', require: darwin_only('growl') gem 'rb-inotify', require: linux_only('rb-inotify') + + # PhantomJS driver for Capybara + gem 'poltergeist' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index cc6a13be..76e92cd9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -94,9 +94,6 @@ GEM rack-test (>= 0.5.4) selenium-webdriver (~> 2.0) xpath (~> 0.1.4) - capybara-webkit (0.12.1) - capybara (>= 1.0.0, < 1.2) - json carrierwave (0.6.2) activemodel (>= 3.2.0) activesupport (>= 3.2.0) @@ -143,6 +140,8 @@ GEM railties (>= 3.0.0) faraday (0.8.4) multipart-post (~> 1.1) + faye-websocket (0.4.6) + eventmachine (>= 0.12.0) ffaker (1.14.0) ffi (1.0.11) font-awesome-sass-rails (2.0.0.0) @@ -189,8 +188,8 @@ GEM hashery (1.5.0) blankslate hashie (1.2.0) - headless (0.3.1) hike (1.2.1) + http_parser.rb (0.5.3) httparty (0.8.3) multi_json (~> 1.0) multi_xml @@ -260,6 +259,12 @@ GEM omniauth-oauth (~> 1.0) orm_adapter (0.3.0) pg (0.14.0) + poltergeist (1.0.2) + capybara (~> 1.1) + childprocess (~> 0.3) + faye-websocket (~> 0.4, >= 0.4.4) + http_parser.rb (~> 0.5.3) + multi_json (~> 1.0) polyglot (0.3.3) posix-spawn (0.3.6) pry (0.9.9.6) @@ -422,7 +427,6 @@ DEPENDENCIES awesome_print bootstrap-sass (= 2.0.4) capybara - capybara-webkit carrierwave chosen-rails coffee-rails (= 3.2.2) @@ -449,7 +453,6 @@ DEPENDENCIES guard-rspec guard-spinach haml-rails - headless httparty jquery-atwho-rails (= 0.1.6) jquery-rails (= 2.0.2) @@ -465,6 +468,7 @@ DEPENDENCIES omniauth-ldap! omniauth-twitter pg + poltergeist pry pygments.rb (= 0.3.1) quiet_assets (= 1.0.1) diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb index a9a33650..23142f5c 100644 --- a/features/steps/project/project_issues.rb +++ b/features/steps/project/project_issues.rb @@ -96,8 +96,7 @@ class ProjectIssues < Spinach::FeatureSteps end Then 'I should see selected milestone with title "v3.0"' do - issues_milestone_selector = "#issue_milestone_id_chzn/a" - wait_until { page.has_content?("Details") } + issues_milestone_selector = "#milestone_id_chzn > a" page.find(issues_milestone_selector).should have_content("v3.0") end diff --git a/features/support/env.rb b/features/support/env.rb index 6d49c25a..1a72d765 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -11,14 +11,33 @@ end Dir["#{Rails.root}/features/steps/shared/*.rb"].each {|file| require file} +# +# Stub gitolite +# include GitoliteStub WebMock.allow_net_connect! -Capybara.javascript_driver = :webkit + +# +# JS driver +# +require 'capybara/poltergeist' +Capybara.javascript_driver = :poltergeist +Spinach.hooks.on_tag("javascript") do + ::Capybara.current_driver = ::Capybara.javascript_driver + ::Capybara.default_wait_time = 5 +end + DatabaseCleaner.strategy = :truncation -Spinach.hooks.before_scenario { DatabaseCleaner.start } -Spinach.hooks.after_scenario { DatabaseCleaner.clean } + +Spinach.hooks.before_scenario do + DatabaseCleaner.start +end + +Spinach.hooks.after_scenario do + DatabaseCleaner.clean +end Spinach.hooks.before_run do RSpec::Mocks::setup self diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4700c3fe..ace5ca00 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,14 +11,13 @@ require 'capybara/rails' require 'capybara/rspec' require 'webmock/rspec' require 'email_spec' -require 'headless' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} -# Use capybara-webkit -Capybara.javascript_driver = :webkit +require 'capybara/poltergeist' +Capybara.javascript_driver = :poltergeist WebMock.disable_net_connect!(allow_localhost: true) @@ -35,11 +34,6 @@ RSpec.configure do |config| # instead of true. config.use_transactional_fixtures = false - config.before :all do - headless = Headless.new - headless.start - end - config.before do stub_gitolite! From 0e9794ca5d04b69d347c14ac6e5a273da6bea8b0 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 16 Nov 2012 12:47:09 +0200 Subject: [PATCH 138/187] new phantomjs for travis --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fe602a59..051c9811 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,9 @@ env: - DB=mysql before_install: - sudo apt-get install libicu-dev -y - - sudo apt-get install libqt4-dev libqtwebkit-dev -y + - wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2 + - tar -xf /tmp/phantomjs-1.7.0-linux-i686.tar.bz2 -C /tmp/ + - PATH=$PATH:/tmp/phantomjs-1.7.0-linux-i686/bin - gem install charlock_holmes -v="0.6.9" branches: only: From 5d9788b05cc72858c3bdcd4c9b3f0beae4e91e7b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 16 Nov 2012 12:54:35 +0200 Subject: [PATCH 139/187] Another try for phantom --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 051c9811..868a6c6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,8 @@ before_install: - sudo apt-get install libicu-dev -y - wget -P /tmp http://phantomjs.googlecode.com/files/phantomjs-1.7.0-linux-i686.tar.bz2 - tar -xf /tmp/phantomjs-1.7.0-linux-i686.tar.bz2 -C /tmp/ - - PATH=$PATH:/tmp/phantomjs-1.7.0-linux-i686/bin + - sudo rm -rf /usr/local/phantomjs + - sudo mv /tmp/phantomjs-1.7.0-linux-i686 /usr/local/phantomjs - gem install charlock_holmes -v="0.6.9" branches: only: From c7aeb5127e3e7e852ed76096ad90a68ebd1195fa Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Fri, 16 Nov 2012 13:03:07 +0200 Subject: [PATCH 140/187] Fix pre-selected assignee spinach --- features/steps/project/project_issues.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/steps/project/project_issues.rb b/features/steps/project/project_issues.rb index 23142f5c..88bfac63 100644 --- a/features/steps/project/project_issues.rb +++ b/features/steps/project/project_issues.rb @@ -107,8 +107,7 @@ class ProjectIssues < Spinach::FeatureSteps end Then 'I should see first assignee from "Shop" as selected assignee' do - issues_assignee_selector = "#issue_assignee_id_chzn/a" - wait_until { page.has_content?("Details") } + issues_assignee_selector = "#assignee_id_chzn > a" project = Project.find_by_name "Shop" assignee_name = project.users.first.name page.find(issues_assignee_selector).should have_content(assignee_name) From 19e8473eb7dd456b64315b1b9e62c780ace98fef Mon Sep 17 00:00:00 2001 From: Marin Jankovski Date: Fri, 2 Nov 2012 12:26:41 +0100 Subject: [PATCH 141/187] Cannot remove user that owns a project. Cannot remove user that owns a project. Make lines shorter, set alert, use path instead of url. --- app/controllers/admin/users_controller.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index c9586ad5..744b1912 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -98,6 +98,9 @@ class Admin::UsersController < AdminController def destroy @admin_user = User.find(params[:id]) + if @admin_user.my_own_projects.count > 0 + redirect_to admin_users_path, alert: "User is a project owner and can't be removed." and return + end @admin_user.destroy respond_to do |format| From 31bf0cd8763b01ec028f8cd5eeaee43c745ad7c6 Mon Sep 17 00:00:00 2001 From: Alexey Loktionov Date: Fri, 16 Nov 2012 22:31:17 +0400 Subject: [PATCH 142/187] fix projects sorting; fix Postgresql issue with LIMIT and DISTINCT; fix query performance --- app/controllers/dashboard_controller.rb | 2 +- app/controllers/groups_controller.rb | 2 +- app/roles/account.rb | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 012d8676..8d9329f2 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -5,7 +5,7 @@ class DashboardController < ApplicationController def index @groups = Group.where(id: current_user.projects.pluck(:group_id)) - @projects = current_user.projects_with_events + @projects = current_user.projects_sorted_by_activity @projects = @projects.page(params[:page]).per(30) @events = Event.in_projects(current_user.project_ids) diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 761238a9..63f70cd0 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -54,7 +54,7 @@ class GroupsController < ApplicationController end def projects - @projects ||= current_user.projects_with_events.where(group_id: @group.id) + @projects ||= current_user.projects_sorted_by_activity.where(group_id: @group.id) end def project_ids diff --git a/app/roles/account.rb b/app/roles/account.rb index 21545b91..b80fbba0 100644 --- a/app/roles/account.rb +++ b/app/roles/account.rb @@ -67,7 +67,7 @@ module Account events = events.recent.limit(1).first end - def projects_with_events - projects.includes(:events).order("events.created_at DESC") + def projects_sorted_by_activity + projects.order("(SELECT max(events.created_at) FROM events WHERE events.project_id = projects.id) DESC") end end From 6c1b44859d3ddddfbec619ef71f63a4084f5f6dd Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 17 Nov 2012 01:00:26 +0100 Subject: [PATCH 143/187] Fix Haml indenting file content --- app/assets/stylesheets/sections/editor.scss | 5 ++++- app/views/tree/edit.html.haml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/sections/editor.scss b/app/assets/stylesheets/sections/editor.scss index 84f221bd..e8ecab62 100644 --- a/app/assets/stylesheets/sections/editor.scss +++ b/app/assets/stylesheets/sections/editor.scss @@ -1,8 +1,11 @@ .file-editor { #editor{ + border: none; height: 500px; - width: 100%; + margin: 0; + padding: 0; position: relative; + width: 100%; } .editor-commit-comment { padding-top:20px; diff --git a/app/views/tree/edit.html.haml b/app/views/tree/edit.html.haml index a14a15b0..638958e0 100644 --- a/app/views/tree/edit.html.haml +++ b/app/views/tree/edit.html.haml @@ -6,7 +6,7 @@ %span.file_name = "#{@tree.path} (#{@ref})" .file_content.code - #editor= @tree.data + %pre#editor= @tree.data .editor-commit-comment = label_tag 'commit_message' do From 7caf4de2cf1095bce65386d4c1bc7df604a09ae6 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 17 Nov 2012 15:28:32 +0100 Subject: [PATCH 144/187] Fix setting Ace mode --- app/views/tree/edit.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/tree/edit.html.haml b/app/views/tree/edit.html.haml index 638958e0..d1d7bf8f 100644 --- a/app/views/tree/edit.html.haml +++ b/app/views/tree/edit.html.haml @@ -19,8 +19,11 @@ = link_to "Cancel", project_tree_path(@project, @id), class: "btn cancel-btn", confirm: "Are you sure?" :javascript + var ace_mode = "#{@tree.language.try(:ace_mode)}"; var editor = ace.edit("editor"); - editor.getSession().setMode("ace/mode/javascript"); + if (ace_mode) { + editor.getSession().setMode('ace/mode/' + ace_mode); + } $(".save-btn").click(function(){ $("#file_content").val(editor.getValue()); From 98e938bdb0049ee4e25b0aac41ce3c3489735052 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 17 Nov 2012 15:43:13 +0100 Subject: [PATCH 145/187] Fix editor form, styles and JS --- app/assets/stylesheets/sections/editor.scss | 39 ++++++++++++++++++--- app/views/tree/edit.html.haml | 33 +++++++++++------ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/app/assets/stylesheets/sections/editor.scss b/app/assets/stylesheets/sections/editor.scss index e8ecab62..711dc0d8 100644 --- a/app/assets/stylesheets/sections/editor.scss +++ b/app/assets/stylesheets/sections/editor.scss @@ -1,17 +1,48 @@ .file-editor { #editor{ border: none; + border-radius: 0; height: 500px; margin: 0; padding: 0; position: relative; width: 100%; } - .editor-commit-comment { - padding-top:20px; + + .cancel-btn { + color: #B94A48; + &:hover { + color: #B94A48; + } + } + .commit-button-annotation { + @extend .alert; + @extend .alert-info; + display: inline-block; + margin: 0; + padding: 2px; + + > * { + float: left; + } + + .commit-btn { + @extend .save-btn; + } + .message { + display: inline-block; + margin: 5px 8px 0 8px; + } + } + .commit_message-group { + margin-top: 20px; + + label { + font-size: 16px; + line-height: 20px; + } textarea { - width: 50%; - margin-left: 20px; + @extend .span8; } } } diff --git a/app/views/tree/edit.html.haml b/app/views/tree/edit.html.haml index d1d7bf8f..adee68a0 100644 --- a/app/views/tree/edit.html.haml +++ b/app/views/tree/edit.html.haml @@ -1,21 +1,32 @@ .file-editor - = form_tag(project_tree_path(@project, @id), :method => :put) do + = form_tag(project_tree_path(@project, @id), method: :put, class: "form-horizontal") do .file_holder .file_title %i.icon-file %span.file_name - = "#{@tree.path} (#{@ref})" + = @tree.path + %small + on + %strong= @ref + %span.options + .btn-group.tree-btn-group + = link_to "Cancel", project_tree_path(@project, @id), class: "btn very_small cancel-btn", confirm: "Are you sure?" .file_content.code %pre#editor= @tree.data - .editor-commit-comment - = label_tag 'commit_message' do - %p.slead Commit message - = text_area_tag 'commit_message', '', :required => true + .control-group.commit_message-group + = label_tag 'commit_message', class: "control-label" do + Commit message + .controls + = text_area_tag 'commit_message', '', placeholder: "Update #{@tree.name}", required: true, rows: 3 .form-actions = hidden_field_tag 'last_commit', @last_commit - = hidden_field_tag 'content', '', :id => :file_content - = button_tag "Commit", class: 'btn save-btn' + = hidden_field_tag 'content', '', id: :file_content + .commit-button-annotation + = button_tag "Commit", class: 'btn commit-btn js-commit-button' + .message + to branch + %strong= @ref = link_to "Cancel", project_tree_path(@project, @id), class: "btn cancel-btn", confirm: "Are you sure?" :javascript @@ -25,7 +36,9 @@ editor.getSession().setMode('ace/mode/' + ace_mode); } - $(".save-btn").click(function(){ + disableButtonIfEmptyField("#commit_message", ".js-commit-button"); + + $(".js-commit-button").click(function(){ $("#file_content").val(editor.getValue()); - $(".form_editor form").submit(); + $(".file-editor form").submit(); }); From 51f48392abb225eaed58a6368382cdc28a961d3b Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sat, 17 Nov 2012 22:25:48 +0100 Subject: [PATCH 146/187] Fix type error if there is a different location hash --- app/assets/javascripts/tree.js.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee index 8ef41e16..3f8ed6c2 100644 --- a/app/assets/javascripts/tree.js.coffee +++ b/app/assets/javascripts/tree.js.coffee @@ -40,12 +40,12 @@ $ -> # "#L12" and "#L34-56" supported highlightBlobLines = -> if window.location.hash isnt "" - matches = window.location.hash.match /\#L(\d+)(\-(\d+))?/ - first_line = parseInt matches[1] - last_line = parseInt matches[3] + matches = window.location.hash.match(/\#L(\d+)(\-(\d+))?/) + first_line = parseInt(matches?[1]) + last_line = parseInt(matches?[3]) unless isNaN first_line - last_line = first_line if isNaN last_line + last_line = first_line if isNaN(last_line) $("#tree-content-holder .highlight .line").removeClass("hll") $("#LC#{line}").addClass("hll") for line in [first_line..last_line] $("#L#{first_line}").ScrollTo() From 3ac1f9459a481fa77be2c0c1b68d4f1ccc5fe9f9 Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Sun, 18 Nov 2012 17:41:41 +0100 Subject: [PATCH 147/187] Optimized commit diff views, now showing file size and file mode changes Replaced commit status images (diff_file_*.png) with fontawesome icons --- app/assets/stylesheets/main.scss | 1 + app/assets/stylesheets/sections/commits.scss | 82 ++++++++++++++------ app/helpers/commits_helper.rb | 4 +- app/views/commits/_diff_head.html.haml | 26 +++---- app/views/commits/_diffs.html.haml | 38 ++++++--- 5 files changed, 102 insertions(+), 49 deletions(-) diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 259a57e5..698dd44a 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -11,6 +11,7 @@ $hover_border: #ADF; /** GitLab Fonts **/ @font-face { font-family: Korolev; src: font-url('korolev-medium-compressed.otf'); } +$monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono', 'lucida console', monospace; /** MIXINS **/ @mixin shade { diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index 4f9360ad..cd74ff33 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -74,16 +74,33 @@ margin-bottom:1em; .diff_file_header { - padding:7px 5px; - border-bottom:1px solid #CCC; + @extend .clearfix; + padding: 5px 5px 5px 10px; + color: #555; + border-bottom:1px solid #D8D8D8; background: #eee; background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -moz-linear-gradient(#eee 6.6%, #dfdfdf); background-image: -o-linear-gradient(#eee 6.6%, #dfdfdf); - span { - font-size:14px; + > span { + font-family: $monospace; + font-size:12px; + line-height: 30px; + } + + a.view-commit{ + font-weight: bold; + } + + .commit-short-id{ + font-family: $monospace; + font-size: smaller; + } + + .file-mode{ + font-family: $monospace; } } .diff_file_content { @@ -92,7 +109,7 @@ background:#fff; color:#333; font-size: 12px; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + font-family: $monospace; .old{ span.idiff{ background-color:#FAA; @@ -113,22 +130,31 @@ .diff_file_content_image { background:#eee; text-align:center; - img { + .image { + display: inline-block; margin:50px; padding:1px; max-width:400px; - &.diff_image_removed { - border: 1px solid #C00; + &.diff_removed { + img{ + border: 1px solid #C00; + } } - &.diff_image_added { - border: 1px solid #0C0;; + &.diff_added { + img{ + border: 1px solid #0C0; + } + } + + .image-info{ + margin: 5px 0 0 0; } } &.img_compared { - img { + .image { max-width:300px; } } @@ -225,7 +251,7 @@ float:left; @extend .lined; min-width:65px; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + font-family: $monospace; } .commit-author-name { @@ -237,17 +263,29 @@ } .diff_file_header a, -.file_stats a { - color:$style_color; +.file-stats a { + color: $style_color; } -.file_stats { - span { - img { - width:14px; - float:left; - margin-right:6px; - padding:2px 0; +.file-stats { + .new-file{ + i{ + color: #1BCF00; + } + } + .renamed-file{ + i{ + color: #FE9300; + } + } + .deleted-file{ + i{ + color: #FF0000; + } + } + .edit-file{ + i{ + color: #555; } } } @@ -259,5 +297,5 @@ font-size:13px; background: #474D57; color:#fff; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + font-family: $monospace; } diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 135d002f..2349888e 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -57,9 +57,9 @@ module CommitsHelper def image_diff_class(diff) if diff.deleted_file - "diff_image_removed" + "diff_removed" elsif diff.new_file - "diff_image_added" + "diff_added" else nil end diff --git a/app/views/commits/_diff_head.html.haml b/app/views/commits/_diff_head.html.haml index 710e8857..5aa54228 100644 --- a/app/views/commits/_diff_head.html.haml +++ b/app/views/commits/_diff_head.html.haml @@ -1,26 +1,26 @@ %ul.bordered-list - - diffs.each do |diff| + - diffs.each_with_index do |diff, i| %li - if diff.deleted_file - %span.removed_file - %a{href: "##{diff.old_path}"} + %span.deleted-file + %a{href: "#diff-#{i}"} + %i.icon-minus = diff.old_path - = image_tag "diff_file_delete.png" - elsif diff.renamed_file - %span.moved_file - %a{href: "##{diff.new_path}"} + %span.renamed-file + %a{href: "#diff-#{i}"} + %i.icon-minus = diff.old_path = "->" = diff.new_path - = image_tag "diff_file_notice.png" - elsif diff.new_file - %span.new_file - %a{href: "##{diff.new_path}"} + %span.new-file + %a{href: "#diff-#{i}"} + %i.icon-plus = diff.new_path - = image_tag "diff_file_add.png" - else - %span.edit_file - %a{href: "##{diff.new_path}"} + %span.edit-file + %a{href: "#diff-#{i}"} + %i.icon-adjust = diff.new_path - = image_tag "diff_file_info.png" diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml index 70fff53c..6ffc6d8b 100644 --- a/app/views/commits/_diffs.html.haml +++ b/app/views/commits/_diffs.html.haml @@ -9,7 +9,7 @@ %p.cgray Showing #{pluralize(diffs.count, "changed file")} -.file_stats +.file-stats = render "commits/diff_head", diffs: diffs - unless @suppress_diff @@ -18,30 +18,44 @@ - file = (@commit.tree / diff.new_path) - file = (@commit.prev_commit.tree / diff.old_path) unless file - next unless file - .diff_file + .diff_file{id: "diff-#{i}"} .diff_file_header - if diff.deleted_file - %i.icon-file - %span{id: "#{diff.old_path}"}= diff.old_path + %span= diff.old_path + + - if @commit.prev_commit + = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-commit'} do + View file @ + %span.commit-short-id= @commit.short_id(6) - else - = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)) do - %i.icon-file - %span{id: "#{diff.new_path}"}= diff.new_path + %span= diff.new_path + - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode + %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" + + = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn right view-commit'} do + View file @ + %span.commit-short-id= @commit.short_id(6) + %br/ .diff_file_content -# Skipp all non non-supported blobs - next unless file.respond_to?('text?') - - if file.text? = render "commits/text_file", diff: diff, index: i - elsif file.image? + - old_file = (@commit.prev_commit.tree / diff.old_path) - 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)}"} + .image{class: image_diff_class(diff)} + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + %div.image-info= "#{number_to_human_size file.size}" - 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)}"} - %img{class: "diff_image_added", src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + .image.diff_removed + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"} + %div.image-info= "#{number_to_human_size file.size}" + .image.diff_added + %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} + %div.image-info= "#{number_to_human_size file.size}" - else %p.nothing_here_message No preview for this file type From e226551e812faf2264b9747e3123c3ec0d1b9e58 Mon Sep 17 00:00:00 2001 From: Valeriy Sizov Date: Sun, 18 Nov 2012 19:53:30 +0200 Subject: [PATCH 148/187] Fix hooks for merge request which were accepted by web-interface --- app/workers/post_receive.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 5311ede7..10128660 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -6,11 +6,15 @@ class PostReceive return false if project.nil? # Ignore push from non-gitlab users - if /^[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) + user = if identifier.eql? Gitlab.config.gitolite_admin_key + email = project.commit(newrev).author.email + User.find_by_email(email) + elsif /^[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}$/.match(identifier) + User.find_by_email(identifier) else - return false unless user = Key.find_by_identifier(identifier).try(:user) + Key.find_by_identifier(identifier).try(:user) end + return false unless user project.trigger_post_receive(oldrev, newrev, ref, user) end From bb3fc1e04ed32b16a7ea5e7be11944e4eda4afaf Mon Sep 17 00:00:00 2001 From: Sergey Linnik Date: Sun, 18 Nov 2012 22:36:22 +0400 Subject: [PATCH 149/187] add order to projects admin page --- app/controllers/admin/projects_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/projects_controller.rb b/app/controllers/admin/projects_controller.rb index 24406525..d27b657d 100644 --- a/app/controllers/admin/projects_controller.rb +++ b/app/controllers/admin/projects_controller.rb @@ -4,7 +4,7 @@ class Admin::ProjectsController < AdminController 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) + @admin_projects = @admin_projects.order("name ASC").page(params[:page]).per(20) end def show From 527d223680864a40887674768cf83a4a8626ead9 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 14 Nov 2012 14:45:15 +0100 Subject: [PATCH 150/187] Update Rails config --- config/application.rb | 10 +++++++++- config/environments/development.rb | 22 ++++++++++++---------- config/environments/production.rb | 11 +++++++++-- config/environments/test.rb | 12 ++---------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/config/application.rb b/config/application.rb index 74ed330e..d6bb90a3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -4,7 +4,7 @@ require 'rails/all' if defined?(Bundler) # If you precompile assets before deploying to production, use this line - # Bundler.require *Rails.groups(:assets => %w(development test)) + # Bundler.require(*Rails.groups(:assets => %w(development test))) # If you want your assets lazily compiled in production, use this line Bundler.require(:default, :assets, Rails.env) end @@ -47,6 +47,14 @@ module Gitlab # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] + # Enable escaping HTML in JSON. + config.active_support.escape_html_entities_in_json = true + + # Use SQL instead of Active Record's schema dumper when creating the database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + # Enforce whitelist mode for mass assignment. # This will create an empty whitelist of attributes available for mass-assignment for all models # in your app. As such, your models will need to explicitly whitelist or blacklist accessible diff --git a/config/environments/development.rb b/config/environments/development.rb index 38400d17..6cba17f6 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -2,7 +2,7 @@ Gitlab::Application.configure do # Settings specified here will take precedence over those in config/application.rb # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false @@ -22,19 +22,21 @@ Gitlab::Application.configure do # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin - # Do not compress assets - config.assets.compress = false - - # Expands the lines which load the assets - config.assets.debug = true - - config.action_mailer.default_url_options = { :host => 'localhost:3000' } - config.action_mailer.delivery_method = :letter_opener - # Raise exception on mass assignment protection for Active Record models config.active_record.mass_assignment_sanitizer = :strict # Log the query plan for queries taking more than this (works # with SQLite, MySQL, and PostgreSQL) config.active_record.auto_explain_threshold_in_seconds = 0.5 + + # Do not compress assets + config.assets.compress = false + + # Expands the lines which load the assets + config.assets.debug = true + + # For having correct urls in mails + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + # Open sent mails in browser + config.action_mailer.delivery_method = :letter_opener end diff --git a/config/environments/production.rb b/config/environments/production.rb index fc8d4c11..52fb8877 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -20,7 +20,7 @@ Gitlab::Application.configure do # Generate digests for assets URLs config.assets.digest = true - # Defaults to Rails.root.join("public/assets") + # Defaults to nil and saved in location specified by config.assets.prefix # config.assets.manifest = YOUR_PATH # Specifies the header that your server uses for sending files @@ -33,8 +33,11 @@ Gitlab::Application.configure do # See everything in the log (default is :info) # config.log_level = :debug + # Prepend all log lines with the following tags + # config.log_tags = [ :subdomain, :uuid ] + # Use a different logger for distributed setups - # config.logger = SyslogLogger.new + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) # Use a different cache store in production config.cache_store = :memory_store @@ -58,6 +61,10 @@ Gitlab::Application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify + # Log the query plan for queries taking more than this (works + # with SQLite, MySQL, and PostgreSQL) + # config.active_record.auto_explain_threshold_in_seconds = 0.5 + config.action_mailer.delivery_method = :sendmail # Defaults to: # # config.action_mailer.sendmail_settings = { diff --git a/config/environments/test.rb b/config/environments/test.rb index f5816e42..b6269862 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -2,9 +2,9 @@ Gitlab::Application.configure do # Settings specified here will take precedence over those in config/application.rb # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that + # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! + # and recreated between test runs. Don't rely on the data there! config.cache_classes = true # Configure static asset server for tests with Cache-Control for performance @@ -29,17 +29,9 @@ Gitlab::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Use SQL instead of Active Record's schema dumper when creating the test database. - # This is necessary if your schema can't be completely dumped by the schema dumper, - # like if you have constraints or database-specific column types - # config.active_record.schema_format = :sql - # Raise exception on mass assignment protection for Active Record models # config.active_record.mass_assignment_sanitizer = :strict # Print deprecation notices to the stderr config.active_support.deprecation = :stderr - - # Allow pass debug_assets=true as a query parameter to load pages with unpackaged assets - config.assets.allow_debugging = true end From 20189f84eef7b242962242b4a5d929208d561ed2 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Sun, 18 Nov 2012 21:51:49 +0100 Subject: [PATCH 151/187] Update gems --- Gemfile | 46 +++---- Gemfile.lock | 249 ++++++++++++++++++---------------- config/initializers/gemoji.rb | 2 + 3 files changed, 157 insertions(+), 140 deletions(-) create mode 100644 config/initializers/gemoji.rb diff --git a/Gemfile b/Gemfile index d4cd45ce..cb097668 100644 --- a/Gemfile +++ b/Gemfile @@ -17,7 +17,7 @@ gem "pg", group: :postgres # Auth gem "devise", "~> 2.1.0" -gem 'omniauth' +gem 'omniauth', "~> 1.1.1" gem 'omniauth-google-oauth2' gem 'omniauth-twitter' gem 'omniauth-github' @@ -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/gitlabhq/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' @@ -46,13 +46,13 @@ gem "grape", "~> 0.2.1" gem "stamp" # Pagination -gem "kaminari" +gem "kaminari", "~> 0.14.1" # HAML -gem "haml-rails" +gem "haml-rails", "~> 0.3.5" # Files attachments -gem "carrierwave" +gem "carrierwave", "~> 0.7.1" # Authorization gem "six" @@ -64,21 +64,21 @@ gem "ffaker" gem "seed-fu" # Markdown to HTML -gem "redcarpet", "~> 2.1.1" +gem "redcarpet", "~> 2.2.2" gem "github-markup", "~> 0.7.4", require: 'github/markup' # Servers gem "thin", '~> 1.5.0' -gem "unicorn" +gem "unicorn", "~> 4.4.0" # Issue tags -gem "acts-as-taggable-on", "2.3.1" +gem "acts-as-taggable-on", "2.3.3" # Decorators -gem "draper" +gem "draper", "~> 0.18.0" # Background jobs -gem "resque", "~> 1.20.0" +gem "resque", "~> 1.23.0" gem 'resque_mailer' # HTTP requests @@ -87,34 +87,34 @@ gem "httparty" # Colored output to console gem "colored" -# GITLAB settings +# GitLab settings gem 'settingslogic' # Misc gem "foreman" -gem 'gemoji', require: 'emoji/railtie' gem "git" group :assets do - gem "sass-rails", "3.2.5" - gem "coffee-rails", "3.2.2" - gem "uglifier", "1.0.3" + gem "sass-rails", "~> 3.2.5" + gem "coffee-rails", "~> 3.2.2" + gem "uglifier", "~> 1.3.0" gem "therubyracer" - gem 'chosen-rails' - gem 'jquery-atwho-rails', '0.1.6' - gem "jquery-rails", "2.0.2" - gem "jquery-ui-rails", "0.5.0" - gem "modernizr", "2.5.3" - gem "raphael-rails", "1.5.2" + gem 'chosen-rails', "0.9.8" + gem 'jquery-atwho-rails', "0.1.6" + gem "jquery-rails", "2.1.3" + gem "jquery-ui-rails", "2.0.2" + gem "modernizr", "2.6.2" + gem "raphael-rails", "2.1.0" gem 'bootstrap-sass', "2.0.4" gem "font-awesome-sass-rails", "~> 2.0.0" + gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' end group :development do gem "annotate", git: "https://github.com/ctran/annotate_models.git" gem "letter_opener" - gem 'quiet_assets', '1.0.1' + gem 'quiet_assets', '~> 1.0.1' gem 'rack-mini-profiler' end @@ -144,7 +144,7 @@ end group :test do gem "simplecov", require: false - gem "shoulda-matchers" + gem "shoulda-matchers", "1.3.0" gem 'email_spec' gem 'resque_spec' gem "webmock" diff --git a/Gemfile.lock b/Gemfile.lock index 3c1fa68d..693b2060 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,10 @@ GIT remote: https://github.com/ctran/annotate_models.git - revision: 18cd39ad01829deba5aa34634b8540d6675ab978 + revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e specs: - annotate (2.4.1.beta1) + annotate (2.6.0.beta1) + activerecord (>= 2.3.0) + rake (>= 0.8.7) GIT remote: https://github.com/gitlabhq/grack.git @@ -87,78 +89,79 @@ GEM activesupport (3.2.9) i18n (~> 0.6) multi_json (~> 1.0) - acts-as-taggable-on (2.3.1) + acts-as-taggable-on (2.3.3) rails (~> 3.0) - addressable (2.2.8) + addressable (2.3.2) arel (3.0.2) - awesome_print (1.0.2) + awesome_print (1.1.0) + backports (2.6.5) bcrypt-ruby (3.0.1) - blankslate (2.1.2.4) + blankslate (3.1.2) bootstrap-sass (2.0.4.0) builder (3.0.4) - capybara (1.1.2) + capybara (1.1.3) mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) selenium-webdriver (~> 2.0) xpath (~> 0.1.4) - carrierwave (0.6.2) + carrierwave (0.7.1) activemodel (>= 3.2.0) activesupport (>= 3.2.0) charlock_holmes (0.6.9) - childprocess (0.3.2) - ffi (~> 1.0.6) - chosen-rails (0.9.8.3) + childprocess (0.3.6) + ffi (~> 1.0, >= 1.0.6) + chosen-rails (0.9.8) railties (~> 3.0) thor (~> 0.14) - coderay (1.0.6) + coderay (1.0.8) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.3.3) + coffee-script-source (1.4.0) colored (1.2) colorize (0.5.8) crack (0.3.1) daemons (1.1.9) - database_cleaner (0.8.0) + database_cleaner (0.9.1) devise (2.1.2) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.1) railties (~> 3.1) warden (~> 1.2.1) diff-lcs (1.1.3) - draper (0.17.0) + draper (0.18.0) actionpack (~> 3.2) activesupport (~> 3.2) - email_spec (1.2.1) + email_spec (1.4.0) + launchy (~> 2.1) mail (~> 2.2) - rspec (~> 2.0) erubis (2.7.0) escape_utils (0.2.4) eventmachine (1.0.0) execjs (1.4.0) multi_json (~> 1.0) - factory_girl (4.0.0) + factory_girl (4.1.0) activesupport (>= 3.0.0) - factory_girl_rails (4.0.0) - factory_girl (~> 4.0.0) + factory_girl_rails (4.1.0) + factory_girl (~> 4.1.0) railties (>= 3.0.0) faraday (0.8.4) multipart-post (~> 1.1) faye-websocket (0.4.6) eventmachine (>= 0.12.0) - ffaker (1.14.0) - ffi (1.0.11) + ffaker (1.15.0) + ffi (1.1.5) font-awesome-sass-rails (2.0.0.0) railties (>= 3.1.1) sass-rails (>= 3.1.1) - foreman (0.47.0) + foreman (0.60.2) thor (>= 0.13.6) - gemoji (1.1.1) + gemoji (1.2.1) gherkin-ruby (0.2.1) git (1.2.5) github-linguist (2.3.4) @@ -172,75 +175,82 @@ GEM gratr19 (~> 0.4.4.1) grit (~> 2.5.0) hashery (~> 1.5.0) - grape (0.2.1) + grape (0.2.2) + activesupport hashie (~> 1.2) - multi_json + multi_json (>= 1.3.2) multi_xml rack + rack-accept rack-mount + virtus gratr19 (0.4.4.1) growl (1.0.3) - guard (1.3.2) + guard (1.5.4) listen (>= 0.4.2) + lumberjack (>= 1.0.2) + pry (>= 0.9.10) thor (>= 0.14.6) - guard-rspec (1.2.1) + guard-rspec (2.1.2) guard (>= 1.1) + rspec (~> 2.11) guard-spinach (0.0.2) guard (>= 1.1) spinach - haml (3.1.6) - haml-rails (0.3.4) - actionpack (~> 3.0) - activesupport (~> 3.0) - haml (~> 3.0) - railties (~> 3.0) + haml (3.1.7) + haml-rails (0.3.5) + actionpack (>= 3.1, < 4.1) + activesupport (>= 3.1, < 4.1) + haml (~> 3.1) + railties (>= 3.1, < 4.1) hashery (1.5.0) blankslate hashie (1.2.0) hike (1.2.1) http_parser.rb (0.5.3) - httparty (0.8.3) + httparty (0.9.0) multi_json (~> 1.0) multi_xml - httpauth (0.1) + httpauth (0.2.0) i18n (0.6.1) journey (1.0.4) jquery-atwho-rails (0.1.6) - jquery-rails (2.0.2) - railties (>= 3.2.0, < 5.0) + jquery-rails (2.1.3) + railties (>= 3.1.0, < 5.0) thor (~> 0.14) - jquery-ui-rails (0.5.0) + jquery-ui-rails (2.0.2) jquery-rails railties (>= 3.1.0) json (1.7.5) jwt (0.1.5) multi_json (>= 1.0) - kaminari (0.14.0) + kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.7.4) - launchy (2.1.0) - addressable (~> 2.2.6) - letter_opener (0.0.2) - launchy + launchy (2.1.2) + addressable (~> 2.3) + letter_opener (1.0.0) + launchy (>= 2.0.4) libv8 (3.3.10.4) - libwebsocket (0.1.3) - addressable - listen (0.5.0) + libwebsocket (0.1.6) + websocket + listen (0.5.3) + lumberjack (1.0.2) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) - method_source (0.7.1) + method_source (0.8.1) mime-types (1.19) - modernizr (2.5.3) + modernizr (2.6.2) sprockets (~> 2.0) multi_json (1.3.7) multi_xml (0.5.1) multipart-post (1.1.5) mysql2 (0.3.11) net-ldap (0.2.2) - nokogiri (1.5.3) + nokogiri (1.5.5) oauth (0.4.7) oauth2 (0.8.0) faraday (~> 0.8) @@ -248,7 +258,7 @@ GEM jwt (~> 0.1.4) multi_json (~> 1.0) rack (~> 1.2) - omniauth (1.1.0) + omniauth (1.1.1) hashie (~> 1.2) rack omniauth-github (1.0.3) @@ -260,14 +270,14 @@ GEM omniauth-oauth (1.0.1) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.1.0) + omniauth-oauth2 (1.1.1) oauth2 (~> 0.8.0) omniauth (~> 1.0) - omniauth-twitter (0.0.13) + omniauth-twitter (0.0.14) multi_json (~> 1.3) omniauth-oauth (~> 1.0) - orm_adapter (0.3.0) - pg (0.14.0) + orm_adapter (0.4.0) + pg (0.14.1) poltergeist (1.0.2) capybara (~> 1.1) childprocess (~> 0.3) @@ -276,17 +286,19 @@ GEM multi_json (~> 1.0) polyglot (0.3.3) posix-spawn (0.3.6) - pry (0.9.9.6) + pry (0.9.10) coderay (~> 1.0.5) - method_source (~> 0.7.1) - slop (>= 2.4.4, < 3) + method_source (~> 0.8) + slop (~> 3.3.1) pyu-ruby-sasl (0.0.3.3) quiet_assets (1.0.1) railties (~> 3.1) rack (1.4.1) + rack-accept (0.4.5) + rack (>= 0.4) rack-cache (1.2) rack (>= 0.4) - rack-mini-profiler (0.1.9) + rack-mini-profiler (0.1.23) rack (>= 1.1.3) rack-mount (0.8.3) rack (>= 1.0.0) @@ -314,45 +326,46 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) - raindrops (0.9.0) - rake (10.0.0) - raphael-rails (1.5.2) - rb-fsevent (0.9.1) + raindrops (0.10.0) + rake (10.0.1) + raphael-rails (2.1.0) + rb-fsevent (0.9.2) rb-inotify (0.8.8) ffi (>= 0.5.0) rdoc (3.12) json (~> 1.4) - redcarpet (2.1.1) - redis (2.2.2) - redis-namespace (1.0.3) - redis (< 3.0.0) - resque (1.20.0) + redcarpet (2.2.2) + redis (3.0.2) + redis-namespace (1.2.1) + redis (~> 3.0.0) + resque (1.23.0) multi_json (~> 1.0) - redis-namespace (~> 1.0.2) + redis-namespace (~> 1.0) sinatra (>= 0.9.2) vegas (~> 0.1.2) - resque_mailer (2.0.3) - actionmailer (>= 3.0.0) - resque (>= 1.2.3) - resque_spec (0.11.0) + resque_mailer (2.1.0) + actionmailer (~> 3.0) + resque_spec (0.12.5) resque (>= 1.19.0) rspec (>= 2.5.0) - rspec (2.10.0) - rspec-core (~> 2.10.0) - rspec-expectations (~> 2.10.0) - rspec-mocks (~> 2.10.0) - rspec-core (2.10.1) - rspec-expectations (2.10.0) + rspec (2.12.0) + rspec-core (~> 2.12.0) + rspec-expectations (~> 2.12.0) + rspec-mocks (~> 2.12.0) + rspec-core (2.12.0) + rspec-expectations (2.12.0) diff-lcs (~> 1.1.3) - rspec-mocks (2.10.1) - rspec-rails (2.10.1) + rspec-mocks (2.12.0) + rspec-rails (2.12.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec (~> 2.10.0) + rspec-core (~> 2.12.0) + rspec-expectations (~> 2.12.0) + rspec-mocks (~> 2.12.0) rubyntlm (0.1.1) - rubyzip (0.9.8) - sass (3.1.19) + rubyzip (0.9.9) + sass (3.2.3) sass-rails (3.2.5) railties (~> 3.2.0) sass (>= 3.1.10) @@ -360,25 +373,24 @@ GEM seed-fu (2.2.0) activerecord (~> 3.1) activesupport (~> 3.1) - selenium-webdriver (2.22.2) + selenium-webdriver (2.26.0) childprocess (>= 0.2.5) - ffi (~> 1.0) libwebsocket (~> 0.1.3) multi_json (~> 1.0) rubyzip settingslogic (2.0.8) shoulda-matchers (1.3.0) activesupport (>= 3.0.0) - simplecov (0.6.4) + simplecov (0.7.1) multi_json (~> 1.0) - simplecov-html (~> 0.5.3) - simplecov-html (0.5.3) - sinatra (1.3.2) + simplecov-html (~> 0.7.1) + simplecov-html (0.7.1) + sinatra (1.3.3) rack (~> 1.3, >= 1.3.6) rack-protection (~> 1.2) tilt (~> 1.3, >= 1.3.3) six (0.2.0) - slop (2.4.4) + slop (3.3.3) spinach (0.5.2) colorize gherkin-ruby (~> 0.2.0) @@ -392,9 +404,9 @@ GEM rack (~> 1.0) tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.6) - stamp (0.1.6) + stamp (0.3.0) test_after_commit (0.0.1) - therubyracer (0.10.1) + therubyracer (0.10.2) libv8 (~> 3.3.10) thin (1.5.0) daemons (>= 1.0.9) @@ -406,20 +418,23 @@ GEM polyglot polyglot (>= 0.3.1) tzinfo (0.3.35) - uglifier (1.0.3) + uglifier (1.3.0) execjs (>= 0.3.0) - multi_json (>= 1.0.2) - unicorn (4.3.1) + multi_json (~> 1.0, >= 1.0.2) + unicorn (4.4.0) kgio (~> 2.6) rack raindrops (~> 0.7) vegas (0.1.11) rack (>= 1.0.0) + virtus (0.5.2) + backports (~> 2.6.1) warden (1.2.1) rack (>= 1.0) - webmock (1.8.7) + webmock (1.9.0) addressable (>= 2.2.7) crack (>= 0.1.7) + websocket (1.0.2) xpath (0.1.4) nokogiri (~> 1.3) yajl-ruby (1.1.0) @@ -428,24 +443,24 @@ PLATFORMS ruby DEPENDENCIES - acts-as-taggable-on (= 2.3.1) + acts-as-taggable-on (= 2.3.3) annotate! awesome_print bootstrap-sass (= 2.0.4) capybara - carrierwave - chosen-rails - coffee-rails (= 3.2.2) + carrierwave (~> 0.7.1) + chosen-rails (= 0.9.8) + coffee-rails (~> 3.2.2) colored database_cleaner devise (~> 2.1.0) - draper + draper (~> 0.18.0) email_spec factory_girl_rails ffaker font-awesome-sass-rails (~> 2.0.0) foreman - gemoji + gemoji (~> 1.2.1) git github-linguist (~> 2.3.4) github-markup (~> 0.7.4) @@ -458,17 +473,17 @@ DEPENDENCIES growl guard-rspec guard-spinach - haml-rails + haml-rails (~> 0.3.5) httparty jquery-atwho-rails (= 0.1.6) - jquery-rails (= 2.0.2) - jquery-ui-rails (= 0.5.0) - kaminari + jquery-rails (= 2.1.3) + jquery-ui-rails (= 2.0.2) + kaminari (~> 0.14.1) launchy letter_opener - modernizr (= 2.5.3) + modernizr (= 2.6.2) mysql2 - omniauth + omniauth (~> 1.1.1) omniauth-github omniauth-google-oauth2 omniauth-ldap! @@ -477,22 +492,22 @@ DEPENDENCIES poltergeist pry pygments.rb! - quiet_assets (= 1.0.1) + quiet_assets (~> 1.0.1) rack-mini-profiler rails (= 3.2.9) rails-dev-tweaks - raphael-rails (= 1.5.2) + raphael-rails (= 2.1.0) rb-fsevent rb-inotify - redcarpet (~> 2.1.1) - resque (~> 1.20.0) + redcarpet (~> 2.2.2) + resque (~> 1.23.0) resque_mailer resque_spec rspec-rails - sass-rails (= 3.2.5) + sass-rails (~> 3.2.5) seed-fu settingslogic - shoulda-matchers + shoulda-matchers (= 1.3.0) simplecov six spinach-rails @@ -501,7 +516,7 @@ DEPENDENCIES test_after_commit therubyracer thin (~> 1.5.0) - uglifier (= 1.0.3) - unicorn + uglifier (~> 1.3.0) + unicorn (~> 4.4.0) webmock yaml_db! diff --git a/config/initializers/gemoji.rb b/config/initializers/gemoji.rb new file mode 100644 index 00000000..8c85aad5 --- /dev/null +++ b/config/initializers/gemoji.rb @@ -0,0 +1,2 @@ +# Workaround for https://github.com/github/gemoji/pull/18 +Gitlab::Application.config.assets.paths << Emoji.images_path From 6878f55620796d0bd8160ba0df298ea0ae060fc2 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 19 Nov 2012 14:01:40 +0200 Subject: [PATCH 152/187] Bigger file name for commits diff --- app/assets/stylesheets/sections/commits.scss | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index cd74ff33..440bfed7 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -77,7 +77,7 @@ @extend .clearfix; padding: 5px 5px 5px 10px; color: #555; - border-bottom:1px solid #D8D8D8; + border-bottom:1px solid #CCC; background: #eee; background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #eee), to(#dfdfdf)); background-image: -webkit-linear-gradient(#eee 6.6%, #dfdfdf); @@ -86,19 +86,19 @@ > span { font-family: $monospace; - font-size:12px; + font-size:14px; line-height: 30px; } - + a.view-commit{ font-weight: bold; } - + .commit-short-id{ font-family: $monospace; font-size: smaller; } - + .file-mode{ font-family: $monospace; } @@ -147,7 +147,7 @@ border: 1px solid #0C0; } } - + .image-info{ margin: 5px 0 0 0; } From be1dc5544a7840d17657d3d8fcecb0d0fd4401b5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 19 Nov 2012 15:11:20 +0200 Subject: [PATCH 153/187] resque via nohup --- resque.sh | 2 +- resque_dev.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resque.sh b/resque.sh index ab67c650..0ebf319e 100755 --- a/resque.sh +++ b/resque.sh @@ -1,2 +1,2 @@ mkdir -p tmp/pids -bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid BACKGROUND=yes +nohup bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook RAILS_ENV=production PIDFILE=tmp/pids/resque_worker.pid > ./log/resque.log & diff --git a/resque_dev.sh b/resque_dev.sh index 0f1d6edb..b250caa9 100755 --- a/resque_dev.sh +++ b/resque_dev.sh @@ -1,2 +1,2 @@ mkdir -p tmp/pids -bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook VVERBOSE=1 PIDFILE=tmp/pids/resque_worker.pid RAILS_ENV=development BACKGROUND=yes +nohup bundle exec rake environment resque:work QUEUE=post_receive,mailer,system_hook VVERBOSE=1 RAILS_ENV=development PIDFILE=tmp/pids/resque_worker.pid > ./log/resque.log & From c3b074acab554fc40a8fcb6060ed7ab10e4171a4 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 19 Nov 2012 21:14:05 +0300 Subject: [PATCH 154/187] Service model and service hook --- app/assets/images/service-gitlab-ci.png | Bin 0 -> 2758 bytes app/models/service.rb | 21 +++++++++++++++ app/models/service_hook.rb | 15 +++++++++++ db/migrate/20121119170638_create_services.rb | 12 +++++++++ ...121120051432_add_service_id_to_web_hook.rb | 5 ++++ spec/models/service_hook_spec.rb | 19 +++++++++++++ spec/models/service_spec.rb | 25 ++++++++++++++++++ 7 files changed, 97 insertions(+) create mode 100644 app/assets/images/service-gitlab-ci.png create mode 100644 app/models/service.rb create mode 100644 app/models/service_hook.rb create mode 100644 db/migrate/20121119170638_create_services.rb create mode 100644 db/migrate/20121120051432_add_service_id_to_web_hook.rb create mode 100644 spec/models/service_hook_spec.rb create mode 100644 spec/models/service_spec.rb diff --git a/app/assets/images/service-gitlab-ci.png b/app/assets/images/service-gitlab-ci.png new file mode 100644 index 0000000000000000000000000000000000000000..afaa10d02b037d1aa658c3b4eec658e2bed17224 GIT binary patch literal 2758 zcmV;%3OV(OP)000V#NklvscEC8n&{Y0CaF!^NixH;k*6%RZpr{gJ1x6;^lb&i!U~)ZxGX z<(_-)_nq%t714$-bfe(G5tt(aB2J(=BFBdb2yg;%BDjSBCy-n4@xh!xoC9tlzzO6Q ze0(q`5a)nf2yg$&g)HjG;iw*OGRnW*K0+4^JZ^P%U-P6|je9Anmjt#*NiY{Yt#EI|H!U>$ZMH!=u&9?nFlLW(y^>rif(%q*P-D~9Qr=ukiS z`ubprCJ;YgoP>8u8*#xfd1CK(0x{y}FHAxwWt+Fo)#0q3vLvm4*zQC+W#!#@=}6Tm z@n&f~t{BD+04ETEAoKCT+so4tu8?8#5gj^hHUz7rbPDMh-iQH<9m)|gK3TUEr9J)F zT{d~z9CT7g>ElZ!iw#+%4#19_UsJ|2@E3+1o-(1e`bH@c*yF2 z3St~wn}Z&!4f(~DusTOLffzs1N$b3plZwykJF&l}87czqRxvp20LvmKhXcC4egRk( zQ#H_*lo+gv&`cZt;@L{H4_Sq=vngR3nFJdXqY$rBAW|WR$?kxjvcsoWJ5WuUV?4%7 z*!I)q*hD%ji%PD|IZDr%@DY{V{u{dNb|vB);TrsGK|J0qy^7Dr;K{MgtN(Uxu;sB4`@pn4+N=6{#K$5(_QivwFTVvwJkgd!5Y z?@tlFw_4v@r2mrD{@8T91WqFRodzcmA+>i!CL;Z1*mz7Qh{mb0HARbgO2tih9%|H2 zWPq7n*xk@TT8Rt_A2BW%`=BP_J|3gCQT$^~4!&yZ#d|f^rV(ggX%oJ@ZV<>yk_;?c z9Qal?;sgD$^<=5gRk?}-dD)OtM%i#&Cuq4l4Nf4Ifzl}hMQO0(LJb-R#>&EY?4Yh> zQE1>zc<$6uxg(9i;$9G_Z^#ClV+3&;e=vJNOWsTrebNGzNFqX7FLiJmuXc zd^b4)XWNbVeO1#0ftWtpaO@%!vgzV?O%&<7^cd_Yu12GI$R#n>$3|jfN)+BGsYkid zwMWH-y__;s`_LH4cm^U6v{D)NJeY}7`d++SeeJfV?}?ajY);kQa{}$oosWb71rAoX zq3~J{N=S@5NxmkKh(5e7_a*|Z(rWPi!qN$0KfZ`(5~A^)ga~XqK`!;EYnOU)Aeo;_ zlkxXDJw9#ebcsQJ7P;PJHXdxyoIngIo6U(oKA43lr5uME+wo6olU>D@1T7v< z2)`|XvehcQl9MuLABbHg{BA`CPLa;ZKV6AHe<@VdRx?i~gWmlry}P)>h&`2)8HhR2 zKRr`{F3a@tQ?MvS5XVn_p@Y;{?D}xnNAaiC*-+3kub0%K_C|*{b-;YGJ6M2%1RO)ra4d zH%^o=Mxg&tXZDvHof-QAyVEOJOy5UYGmdxnOfyDjGKuM}5Rn8QJd#bmksW*KzOIHe z9$TxF*1tGJjrH-7h*kOF!^$>%(%JzTZ{sInwAx27Ybtp%6iE^VHrVu z!}MWyLj_;gz%Cgj!%=ce0)_fY@!mrVgz-%SLpV^|f;JMc;{qz{v@t1r1g-hK9MBX-&mBh3RM)G%F(bY^4Xl1lUxCbjCm;55#zeSMo_#|z( zp61$q@(R@CtpBg*8?@ums8GDTG*NieLQZoNH5KgeFx|uAL~{>*U0efg@K|TcHP94P ztyId`y;cs@_@$9*eGJC|H?_%n%j&>3cXyo4uD>``B=Qp|!u0Xg6A+Ci`GHb)_rl!*Cd) zyRZiGm_Dj%#d*qni4p!2*^Cot2C5D^btdY%%vLANWX4%3Q^-jd_{n_eZb*V4a$sj} zMMIYv{d9V>Vgm(tmWAGEfx$H949C+3sudEn^;*!?@4A&{<6?-MVF5DOX`I0{4C9a; zjM&Ub3{pyjuQhfLf@O;ZG#@J?4V`A8Q%sFgp_S$sBJwb|oMlL@#!t{rvk5kyVPK;5 zvtQYGIbAG=lKURyKbCdJgJtf@)_yurVx&a}%x0Rq^6Y(c8-G_;!(ZZY1UP{_4!L(t z$O+_K`|0u3Z~}Q8a_^du6Ue*v)8nh*1oAlK-Zdd7kaz8;$5+D%ZIDzH}9v? Date: Mon, 19 Nov 2012 21:24:05 +0300 Subject: [PATCH 155/187] Annotated. schema updated --- app/models/event.rb | 33 +++++++------ app/models/group.rb | 25 +++++----- app/models/issue.rb | 37 ++++++++------- app/models/key.rb | 29 ++++++------ app/models/merge_request.rb | 43 +++++++++-------- app/models/milestone.rb | 29 ++++++------ app/models/note.rb | 33 +++++++------ app/models/project.rb | 44 +++++++++--------- app/models/project_hook.rb | 15 +++--- app/models/protected_branch.rb | 23 +++++----- app/models/snippet.rb | 31 ++++++------- app/models/system_hook.rb | 25 +++++----- app/models/user.rb | 69 ++++++++++++++-------------- app/models/users_project.rb | 25 +++++----- app/models/web_hook.rb | 25 +++++----- app/models/wiki.rb | 29 ++++++------ app/views/projects/_form.html.haml | 10 ++-- db/schema.rb | 12 ++++- spec/factories.rb | 12 +++++ spec/models/event_spec.rb | 6 +-- spec/models/group_spec.rb | 12 ++--- spec/models/issue_spec.rb | 10 ++-- spec/models/key_spec.rb | 6 +-- spec/models/merge_request_spec.rb | 22 ++++----- spec/models/milestone_spec.rb | 12 ++--- spec/models/note_spec.rb | 6 +-- spec/models/project_spec.rb | 17 +++---- spec/models/protected_branch_spec.rb | 10 ++-- spec/models/snippet_spec.rb | 10 ++-- spec/models/system_hook_spec.rb | 8 ++-- spec/models/user_spec.rb | 30 ++++++------ spec/models/users_project_spec.rb | 12 ++--- spec/models/web_hook_spec.rb | 8 ++-- spec/models/wiki_spec.rb | 6 +-- 34 files changed, 365 insertions(+), 359 deletions(-) diff --git a/app/models/event.rb b/app/models/event.rb index 0ea3224a..2b92783c 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -1,3 +1,19 @@ +# == Schema Information +# +# Table name: events +# +# id :integer not null, primary key +# target_type :string(255) +# target_id :integer +# title :string(255) +# data :text +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# action :integer +# author_id :integer +# + class Event < ActiveRecord::Base include PushEvent @@ -144,20 +160,3 @@ class Event < ActiveRecord::Base end end end - -# == Schema Information -# -# Table name: events -# -# id :integer not null, primary key -# target_type :string(255) -# target_id :integer -# title :string(255) -# data :text -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# action :integer -# author_id :integer -# - diff --git a/app/models/group.rb b/app/models/group.rb index ef8c7463..1ff6872f 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: groups +# +# id :integer not null, primary key +# name :string(255) not null +# code :string(255) not null +# owner_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + class Group < ActiveRecord::Base attr_accessible :code, :name, :owner_id @@ -22,16 +34,3 @@ class Group < ActiveRecord::Base User.joins(:users_projects).where(users_projects: {project_id: project_ids}).uniq end end - -# == Schema Information -# -# Table name: groups -# -# id :integer not null, primary key -# name :string(255) not null -# code :string(255) not null -# owner_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# - diff --git a/app/models/issue.rb b/app/models/issue.rb index 1acdfdd3..1de9d0f9 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1,3 +1,21 @@ +# == Schema Information +# +# Table name: issues +# +# id :integer not null, primary key +# title :string(255) +# assignee_id :integer +# author_id :integer +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# closed :boolean default(FALSE), not null +# position :integer default(0) +# branch_name :string(255) +# description :text +# milestone_id :integer +# + class Issue < ActiveRecord::Base include IssueCommonality include Votes @@ -13,22 +31,3 @@ class Issue < ActiveRecord::Base opened.assigned(user) end end - -# == Schema Information -# -# Table name: issues -# -# id :integer not null, primary key -# title :string(255) -# assignee_id :integer -# author_id :integer -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# closed :boolean default(FALSE), not null -# position :integer default(0) -# branch_name :string(255) -# description :text -# milestone_id :integer -# - diff --git a/app/models/key.rb b/app/models/key.rb index e4710b85..5dac1c1c 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: keys +# +# id :integer not null, primary key +# user_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# key :text +# title :string(255) +# identifier :string(255) +# project_id :integer +# + require 'digest/md5' class Key < ActiveRecord::Base @@ -67,18 +81,3 @@ class Key < ActiveRecord::Base Key.where(identifier: identifier).count == 0 end end - -# == Schema Information -# -# Table name: keys -# -# id :integer not null, primary key -# user_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# key :text -# title :string(255) -# identifier :string(255) -# project_id :integer -# - diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 16e13db7..0766e5ba 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -1,3 +1,24 @@ +# == Schema Information +# +# Table name: merge_requests +# +# id :integer not null, primary key +# target_branch :string(255) not null +# source_branch :string(255) not null +# project_id :integer not null +# author_id :integer +# assignee_id :integer +# title :string(255) +# closed :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# st_commits :text(2147483647) +# st_diffs :text(2147483647) +# merged :boolean default(FALSE), not null +# state :integer default(1), not null +# milestone_id :integer +# + require Rails.root.join("app/models/commit") require Rails.root.join("app/roles/static_model") @@ -198,25 +219,3 @@ class MergeRequest < ActiveRecord::Base 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 end - -# == Schema Information -# -# Table name: merge_requests -# -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# project_id :integer not null -# author_id :integer -# assignee_id :integer -# title :string(255) -# closed :boolean default(FALSE), not null -# created_at :datetime not null -# updated_at :datetime not null -# st_commits :text(4294967295 -# st_diffs :text(4294967295 -# merged :boolean default(FALSE), not null -# state :integer default(1), not null -# milestone_id :integer -# - diff --git a/app/models/milestone.rb b/app/models/milestone.rb index 1dcc93bf..a50831a2 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: milestones +# +# id :integer not null, primary key +# title :string(255) not null +# project_id :integer not null +# description :text +# due_date :date +# closed :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + class Milestone < ActiveRecord::Base attr_accessible :title, :description, :due_date, :closed @@ -39,18 +53,3 @@ class Milestone < ActiveRecord::Base "expires at #{due_date.stamp("Aug 21, 2011")}" if due_date end end - -# == Schema Information -# -# Table name: milestones -# -# id :integer not null, primary key -# title :string(255) not null -# project_id :integer not null -# description :text -# due_date :date -# closed :boolean default(FALSE), not null -# created_at :datetime not null -# updated_at :datetime not null -# - diff --git a/app/models/note.rb b/app/models/note.rb index d7701c38..60846e04 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -1,3 +1,19 @@ +# == Schema Information +# +# Table name: notes +# +# id :integer not null, primary key +# note :text +# noteable_id :string(255) +# noteable_type :string(255) +# author_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# project_id :integer +# attachment :string(255) +# line_code :string(255) +# + require 'carrierwave/orm/activerecord' require 'file_size_validator' @@ -107,20 +123,3 @@ class Note < ActiveRecord::Base note.start_with?('-1') || note.start_with?(':-1:') end end - -# == Schema Information -# -# Table name: notes -# -# id :integer not null, primary key -# note :text -# noteable_id :string(255) -# noteable_type :string(255) -# author_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# project_id :integer -# attachment :string(255) -# line_code :string(255) -# - diff --git a/app/models/project.rb b/app/models/project.rb index 5b59f227..30b53431 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1,3 +1,24 @@ +# == Schema Information +# +# Table name: projects +# +# id :integer not null, primary key +# name :string(255) +# path :string(255) +# description :text +# created_at :datetime not null +# updated_at :datetime not null +# private_flag :boolean default(TRUE), not null +# code :string(255) +# owner_id :integer +# default_branch :string(255) +# issues_enabled :boolean default(TRUE), not null +# wall_enabled :boolean default(TRUE), not null +# merge_requests_enabled :boolean default(TRUE), not null +# wiki_enabled :boolean default(TRUE), not null +# group_id :integer +# + require "grit" class Project < ActiveRecord::Base @@ -26,6 +47,7 @@ class Project < ActiveRecord::Base has_many :wikis, dependent: :destroy has_many :protected_branches, dependent: :destroy has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id' + has_many :services, dependent: :destroy delegate :name, to: :owner, allow_nil: true, prefix: true @@ -163,25 +185,3 @@ class Project < ActiveRecord::Base issues.tag_counts_on(:labels) end end - -# == Schema Information -# -# Table name: projects -# -# id :integer not null, primary key -# name :string(255) -# path :string(255) -# description :text -# created_at :datetime not null -# updated_at :datetime not null -# private_flag :boolean default(TRUE), not null -# code :string(255) -# owner_id :integer -# default_branch :string(255) -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null -# group_id :integer -# - diff --git a/app/models/project_hook.rb b/app/models/project_hook.rb index 92f6d1f0..aebf2054 100644 --- a/app/models/project_hook.rb +++ b/app/models/project_hook.rb @@ -1,16 +1,15 @@ -class ProjectHook < WebHook - belongs_to :project -end - # == Schema Information # # Table name: web_hooks # -# id :integer not null, primary key +# id :integer not null, primary key # url :string(255) # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# type :string(255) default("ProjectHook") +# created_at :datetime not null +# updated_at :datetime not null +# type :string(255) default("ProjectHook") # +class ProjectHook < WebHook + belongs_to :project +end diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index 926692f1..c54aa3ce 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -1,3 +1,14 @@ +# == Schema Information +# +# Table name: protected_branches +# +# id :integer not null, primary key +# project_id :integer not null +# name :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null +# + class ProtectedBranch < ActiveRecord::Base include GitHost @@ -18,15 +29,3 @@ class ProtectedBranch < ActiveRecord::Base project.commit(self.name) end end - -# == Schema Information -# -# Table name: protected_branches -# -# id :integer not null, primary key -# project_id :integer not null -# name :string(255) not null -# created_at :datetime not null -# updated_at :datetime not null -# - diff --git a/app/models/snippet.rb b/app/models/snippet.rb index 3525219e..997c19bd 100644 --- a/app/models/snippet.rb +++ b/app/models/snippet.rb @@ -1,3 +1,18 @@ +# == Schema Information +# +# Table name: snippets +# +# id :integer not null, primary key +# title :string(255) +# content :text +# author_id :integer not null +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# file_name :string(255) +# expires_at :datetime +# + class Snippet < ActiveRecord::Base include Linguist::BlobHelper @@ -48,19 +63,3 @@ class Snippet < ActiveRecord::Base expires_at && expires_at < Time.current end end - -# == Schema Information -# -# Table name: snippets -# -# id :integer not null, primary key -# title :string(255) -# content :text -# author_id :integer not null -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# file_name :string(255) -# expires_at :datetime -# - diff --git a/app/models/system_hook.rb b/app/models/system_hook.rb index f56b80f4..3bc9089f 100644 --- a/app/models/system_hook.rb +++ b/app/models/system_hook.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: web_hooks +# +# id :integer not null, primary key +# url :string(255) +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# type :string(255) default("ProjectHook") +# + class SystemHook < WebHook def self.all_hooks_fire(data) SystemHook.all.each do |sh| @@ -9,16 +21,3 @@ class SystemHook < WebHook Resque.enqueue(SystemHookWorker, id, data) end end - -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# type :string(255) default("ProjectHook") -# - diff --git a/app/models/user.rb b/app/models/user.rb index b0484698..6d539c1f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,37 @@ +# == Schema Information +# +# Table name: users +# +# id :integer not null, primary key +# email :string(255) default(""), not null +# encrypted_password :string(255) default(""), not null +# reset_password_token :string(255) +# reset_password_sent_at :datetime +# remember_created_at :datetime +# sign_in_count :integer default(0) +# current_sign_in_at :datetime +# last_sign_in_at :datetime +# current_sign_in_ip :string(255) +# last_sign_in_ip :string(255) +# created_at :datetime not null +# updated_at :datetime not null +# name :string(255) +# admin :boolean default(FALSE), not null +# projects_limit :integer default(10) +# skype :string(255) default(""), not null +# linkedin :string(255) default(""), not null +# twitter :string(255) default(""), not null +# authentication_token :string(255) +# dark_scheme :boolean default(FALSE), not null +# theme_id :integer default(1), not null +# bio :string(255) +# blocked :boolean default(FALSE), not null +# failed_attempts :integer default(0) +# locked_at :datetime +# extern_uid :string(255) +# provider :string(255) +# + class User < ActiveRecord::Base include Account @@ -79,38 +113,3 @@ class User < ActiveRecord::Base end end end - -# == Schema Information -# -# Table name: users -# -# id :integer not null, primary key -# email :string(255) default(""), not null -# encrypted_password :string(128) default(""), not null -# reset_password_token :string(255) -# reset_password_sent_at :datetime -# remember_created_at :datetime -# sign_in_count :integer default(0) -# current_sign_in_at :datetime -# last_sign_in_at :datetime -# current_sign_in_ip :string(255) -# last_sign_in_ip :string(255) -# created_at :datetime not null -# updated_at :datetime not null -# name :string(255) -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string(255) default(""), not null -# linkedin :string(255) default(""), not null -# twitter :string(255) default(""), not null -# authentication_token :string(255) -# dark_scheme :boolean default(FALSE), not null -# theme_id :integer default(1), not null -# bio :string(255) -# blocked :boolean default(FALSE), not null -# failed_attempts :integer default(0) -# locked_at :datetime -# extern_uid :string(255) -# provider :string(255) -# - diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 967c78f2..6231088f 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: users_projects +# +# id :integer not null, primary key +# user_id :integer not null +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# project_access :integer default(0), not null +# + class UsersProject < ActiveRecord::Base include GitHost @@ -119,16 +131,3 @@ class UsersProject < ActiveRecord::Base self.class.access_roles.invert[self.project_access] end end - -# == Schema Information -# -# Table name: users_projects -# -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# project_access :integer default(0), not null -# - diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb index db773c55..ac3e10cf 100644 --- a/app/models/web_hook.rb +++ b/app/models/web_hook.rb @@ -1,3 +1,15 @@ +# == Schema Information +# +# Table name: web_hooks +# +# id :integer not null, primary key +# url :string(255) +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# type :string(255) default("ProjectHook") +# + class WebHook < ActiveRecord::Base include HTTParty @@ -22,16 +34,3 @@ class WebHook < ActiveRecord::Base end end end - -# == Schema Information -# -# Table name: web_hooks -# -# id :integer not null, primary key -# url :string(255) -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# type :string(255) default("ProjectHook") -# - diff --git a/app/models/wiki.rb b/app/models/wiki.rb index 895c2896..252a97e8 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -1,3 +1,17 @@ +# == Schema Information +# +# Table name: wikis +# +# id :integer not null, primary key +# title :string(255) +# content :text +# project_id :integer +# created_at :datetime not null +# updated_at :datetime not null +# slug :string(255) +# user_id :integer +# + class Wiki < ActiveRecord::Base attr_accessible :title, :content, :slug @@ -38,18 +52,3 @@ class Wiki < ActiveRecord::Base end end - -# == Schema Information -# -# Table name: wikis -# -# id :integer not null, primary key -# title :string(255) -# content :text -# project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# slug :string(255) -# user_id :integer -# - diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 8bdeda1c..9ee65942 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -10,9 +10,8 @@ .input = f.text_field :name, placeholder: "Example Project", class: "xxlarge" - %hr - .adv_settings - %h6 Advanced settings: + %fieldset + %legend Advanced settings: .clearfix = f.label :path do Path @@ -34,9 +33,8 @@ .input= f.select(:default_branch, @project.heads.map(&:name), {}, style: "width:210px;") - unless @project.new_record? - %hr - .adv_settings - %h6 Features: + %fieldset + %legend Features: .clearfix = f.label :issues_enabled, "Issues" diff --git a/db/schema.rb b/db/schema.rb index e7eb5696..b1154270 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 => 20121026114600) do +ActiveRecord::Schema.define(:version => 20121120051432) do create_table "events", :force => true do |t| t.string "target_type" @@ -127,6 +127,15 @@ ActiveRecord::Schema.define(:version => 20121026114600) do t.datetime "updated_at", :null => false end + create_table "services", :force => true do |t| + t.string "type" + t.string "title" + t.string "token" + t.integer "project_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "snippets", :force => true do |t| t.string "title" t.text "content" @@ -203,6 +212,7 @@ ActiveRecord::Schema.define(:version => 20121026114600) do t.datetime "created_at", :null => false t.datetime "updated_at", :null => false t.string "type", :default => "ProjectHook" + t.integer "service_id" end create_table "wikis", :force => true do |t| diff --git a/spec/factories.rb b/spec/factories.rb index 7b2a2efa..7c33f0ec 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -132,4 +132,16 @@ FactoryGirl.define do name project end + + factory :service do + type "" + title "GitLab CI" + token "x56olispAND34ng" + project + end + + factory :service_hook do + url + service + end end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index d68ebb86..49cb49db 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -2,14 +2,14 @@ # # Table name: events # -# id :integer not null, primary key +# id :integer not null, primary key # target_type :string(255) # target_id :integer # title :string(255) # data :text # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null # action :integer # author_id :integer # diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 5ae40658..6ae2cb20 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -2,12 +2,12 @@ # # Table name: groups # -# id :integer not null, primary key -# name :string(255) not null -# code :string(255) not null -# owner_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# name :string(255) not null +# code :string(255) not null +# owner_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null # require 'spec_helper' diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 9c69f868..4c52a094 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -2,15 +2,15 @@ # # Table name: issues # -# id :integer not null, primary key +# id :integer not null, primary key # title :string(255) # assignee_id :integer # author_id :integer # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# closed :boolean default(FALSE), not null -# position :integer default(0) +# created_at :datetime not null +# updated_at :datetime not null +# closed :boolean default(FALSE), not null +# position :integer default(0) # branch_name :string(255) # description :text # milestone_id :integer diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 80dfff08..6d2310df 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -2,10 +2,10 @@ # # Table name: keys # -# id :integer not null, primary key +# id :integer not null, primary key # user_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null # key :text # title :string(255) # identifier :string(255) diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 4bf42ef9..d70647f6 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -2,20 +2,20 @@ # # Table name: merge_requests # -# id :integer not null, primary key -# target_branch :string(255) not null -# source_branch :string(255) not null -# project_id :integer not null +# id :integer not null, primary key +# target_branch :string(255) not null +# source_branch :string(255) not null +# project_id :integer not null # author_id :integer # assignee_id :integer # title :string(255) -# closed :boolean default(FALSE), not null -# created_at :datetime not null -# updated_at :datetime not null -# st_commits :text(4294967295 -# st_diffs :text(4294967295 -# merged :boolean default(FALSE), not null -# state :integer default(1), not null +# closed :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# st_commits :text(2147483647) +# st_diffs :text(2147483647) +# merged :boolean default(FALSE), not null +# state :integer default(1), not null # milestone_id :integer # diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb index 0e5cf7dd..431985d0 100644 --- a/spec/models/milestone_spec.rb +++ b/spec/models/milestone_spec.rb @@ -2,14 +2,14 @@ # # Table name: milestones # -# id :integer not null, primary key -# title :string(255) not null -# project_id :integer not null +# id :integer not null, primary key +# title :string(255) not null +# project_id :integer not null # description :text # due_date :date -# closed :boolean default(FALSE), not null -# created_at :datetime not null -# updated_at :datetime not null +# closed :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null # require 'spec_helper' diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb index d7390537..4f9352b9 100644 --- a/spec/models/note_spec.rb +++ b/spec/models/note_spec.rb @@ -2,13 +2,13 @@ # # Table name: notes # -# id :integer not null, primary key +# id :integer not null, primary key # note :text # noteable_id :string(255) # noteable_type :string(255) # author_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null # project_id :integer # attachment :string(255) # line_code :string(255) diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 1cf4f586..4f7afd9d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2,20 +2,20 @@ # # Table name: projects # -# id :integer not null, primary key +# id :integer not null, primary key # name :string(255) # path :string(255) # description :text -# created_at :datetime not null -# updated_at :datetime not null -# private_flag :boolean default(TRUE), not null +# created_at :datetime not null +# updated_at :datetime not null +# private_flag :boolean default(TRUE), not null # code :string(255) # owner_id :integer # default_branch :string(255) -# issues_enabled :boolean default(TRUE), not null -# wall_enabled :boolean default(TRUE), not null -# merge_requests_enabled :boolean default(TRUE), not null -# wiki_enabled :boolean default(TRUE), not null +# issues_enabled :boolean default(TRUE), not null +# wall_enabled :boolean default(TRUE), not null +# merge_requests_enabled :boolean default(TRUE), not null +# wiki_enabled :boolean default(TRUE), not null # group_id :integer # @@ -37,6 +37,7 @@ describe Project do it { should have_many(:hooks).dependent(:destroy) } it { should have_many(:wikis).dependent(:destroy) } it { should have_many(:protected_branches).dependent(:destroy) } + it { should have_many(:services).dependent(:destroy) } end describe "Mass assignment" do diff --git a/spec/models/protected_branch_spec.rb b/spec/models/protected_branch_spec.rb index 874c4e4d..7340ce50 100644 --- a/spec/models/protected_branch_spec.rb +++ b/spec/models/protected_branch_spec.rb @@ -2,11 +2,11 @@ # # Table name: protected_branches # -# id :integer not null, primary key -# project_id :integer not null -# name :string(255) not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# project_id :integer not null +# name :string(255) not null +# created_at :datetime not null +# updated_at :datetime not null # require 'spec_helper' diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index ada5fcdb..b474d88c 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -2,13 +2,13 @@ # # Table name: snippets # -# id :integer not null, primary key +# id :integer not null, primary key # title :string(255) # content :text -# author_id :integer not null -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null +# author_id :integer not null +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null # file_name :string(255) # expires_at :datetime # diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb index 5f923911..a99e91d3 100644 --- a/spec/models/system_hook_spec.rb +++ b/spec/models/system_hook_spec.rb @@ -2,12 +2,12 @@ # # Table name: web_hooks # -# id :integer not null, primary key +# id :integer not null, primary key # url :string(255) # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# type :string(255) default("ProjectHook") +# created_at :datetime not null +# updated_at :datetime not null +# type :string(255) default("ProjectHook") # require "spec_helper" diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index b9654d70..4ac699b1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2,31 +2,31 @@ # # Table name: users # -# id :integer not null, primary key -# email :string(255) default(""), not null -# encrypted_password :string(128) default(""), not null +# id :integer not null, primary key +# email :string(255) default(""), not null +# encrypted_password :string(255) default(""), not null # reset_password_token :string(255) # reset_password_sent_at :datetime # remember_created_at :datetime -# sign_in_count :integer default(0) +# sign_in_count :integer default(0) # current_sign_in_at :datetime # last_sign_in_at :datetime # current_sign_in_ip :string(255) # last_sign_in_ip :string(255) -# created_at :datetime not null -# updated_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null # name :string(255) -# admin :boolean default(FALSE), not null -# projects_limit :integer default(10) -# skype :string(255) default(""), not null -# linkedin :string(255) default(""), not null -# twitter :string(255) default(""), not null +# admin :boolean default(FALSE), not null +# projects_limit :integer default(10) +# skype :string(255) default(""), not null +# linkedin :string(255) default(""), not null +# twitter :string(255) default(""), not null # authentication_token :string(255) -# dark_scheme :boolean default(FALSE), not null -# theme_id :integer default(1), not null +# dark_scheme :boolean default(FALSE), not null +# theme_id :integer default(1), not null # bio :string(255) -# blocked :boolean default(FALSE), not null -# failed_attempts :integer default(0) +# blocked :boolean default(FALSE), not null +# failed_attempts :integer default(0) # locked_at :datetime # extern_uid :string(255) # provider :string(255) diff --git a/spec/models/users_project_spec.rb b/spec/models/users_project_spec.rb index 2ad9a0bd..1f896324 100644 --- a/spec/models/users_project_spec.rb +++ b/spec/models/users_project_spec.rb @@ -2,12 +2,12 @@ # # Table name: users_projects # -# id :integer not null, primary key -# user_id :integer not null -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null -# project_access :integer default(0), not null +# id :integer not null, primary key +# user_id :integer not null +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# project_access :integer default(0), not null # require 'spec_helper' diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index 8f8decb8..aa040b50 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -2,12 +2,12 @@ # # Table name: web_hooks # -# id :integer not null, primary key +# id :integer not null, primary key # url :string(255) # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null -# type :string(255) default("ProjectHook") +# created_at :datetime not null +# updated_at :datetime not null +# type :string(255) default("ProjectHook") # require 'spec_helper' diff --git a/spec/models/wiki_spec.rb b/spec/models/wiki_spec.rb index 96aebd2d..9750b81d 100644 --- a/spec/models/wiki_spec.rb +++ b/spec/models/wiki_spec.rb @@ -2,12 +2,12 @@ # # Table name: wikis # -# id :integer not null, primary key +# id :integer not null, primary key # title :string(255) # content :text # project_id :integer -# created_at :datetime not null -# updated_at :datetime not null +# created_at :datetime not null +# updated_at :datetime not null # slug :string(255) # user_id :integer # From 85007434645c817e7674003bbdda0674287dd106 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 19 Nov 2012 21:44:05 +0300 Subject: [PATCH 156/187] Post Receive Refactored. Service hooks also triggered now --- app/roles/push_observer.rb | 121 +++++++++++++++++++----------- spec/models/project_hooks_spec.rb | 14 ++-- spec/workers/post_receive_spec.rb | 14 ++-- 3 files changed, 89 insertions(+), 60 deletions(-) diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb index 947ed423..f8a8df23 100644 --- a/app/roles/push_observer.rb +++ b/app/roles/push_observer.rb @@ -2,9 +2,45 @@ # # Triggered by PostReceive job module PushObserver - def observe_push(oldrev, newrev, ref, user) + # 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. + def trigger_post_receive(oldrev, newrev, ref, user) data = post_receive_data(oldrev, newrev, ref, user) + # Create push event + self.observe_push(data) + + if push_to_branch? ref, oldrev + # Close merged MR + self.update_merge_requests(oldrev, newrev, ref, user) + + # Execute web hooks + self.execute_hooks(data.dup) + + # Execute project services + self.execute_services(data.dup) + end + + # 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 + + def push_to_branch? ref, oldrev + ref_parts = ref.split('/') + + # Return if this is not a push to a branch (e.g. new commits) + !(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000") + end + + def observe_push(data) Event.create( project: self, action: Event::Pushed, @@ -13,34 +49,36 @@ module PushObserver ) end - def update_merge_requests(oldrev, newrev, ref, user) - return true unless ref =~ /heads/ - 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 - - 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] !~ /heads/ || oldrev == "00000000000000000000000000000000" - - data = post_receive_data(oldrev, newrev, ref, user) - + def execute_hooks(data) hooks.each { |hook| hook.execute(data) } end + def execute_services(data) + services.each do |service| + + # Call service hook for service if it has one + service.service_hook.execute if service.service_hook + end + end + + # Produce a hash of post-receive data + # + # data = { + # before: String, + # after: String, + # ref: String, + # user_id: String, + # user_name: String, + # repository: { + # name: String, + # url: String, + # description: String, + # homepage: String, + # }, + # commits: Array, + # total_commits_count: Fixnum + # } + # def post_receive_data(oldrev, newrev, ref, user) push_commits = commits_between(oldrev, newrev) @@ -87,27 +125,20 @@ module PushObserver data end - # 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. - def trigger_post_receive(oldrev, newrev, ref, user) - # Create push event - self.observe_push(oldrev, newrev, ref, user) + def update_merge_requests(oldrev, newrev, ref, user) + return true unless ref =~ /heads/ + branch_name = ref.gsub("refs/heads/", "") + c_ids = self.commits_between(oldrev, newrev).map(&:id) - # Close merged MR - self.update_merge_requests(oldrev, newrev, ref, user) + # 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 } - # Execute web hooks - self.execute_hooks(oldrev, newrev, ref, user) + # 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) } - # 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 + true end end diff --git a/spec/models/project_hooks_spec.rb b/spec/models/project_hooks_spec.rb index ee441ec4..7c8f05b1 100644 --- a/spec/models/project_hooks_spec.rb +++ b/spec/models/project_hooks_spec.rb @@ -11,13 +11,15 @@ describe Project, "Hooks" do describe "Post Receive Event" do it "should create push event" do oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master' - project.observe_push(oldrev, newrev, ref, @user) + data = project.post_receive_data(oldrev, newrev, ref, @user) + + project.observe_push(data) event = Event.last event.should_not be_nil event.project.should == project event.action.should == Event::Pushed - event.data == project.post_receive_data(oldrev, newrev, ref, @user) + event.data.should == data end end @@ -25,7 +27,7 @@ describe Project, "Hooks" do context "with no web hooks" do it "raises no errors" do lambda { - project.execute_hooks('oldrev', 'newrev', 'ref', @user) + project.execute_hooks({}) }.should_not raise_error end end @@ -41,7 +43,7 @@ describe Project, "Hooks" do @project_hook.should_receive(:execute).once @project_hook_2.should_receive(:execute).once - project.execute_hooks('oldrev', 'newrev', 'refs/heads/master', @user) + project.trigger_post_receive('oldrev', 'newrev', 'refs/heads/master', @user) end end @@ -53,12 +55,12 @@ describe Project, "Hooks" do it "when pushing a branch for the first time" do @project_hook.should_not_receive(:execute) - project.execute_hooks('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user) + project.trigger_post_receive('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user) end it "when pushing tags" do @project_hook.should_not_receive(:execute) - project.execute_hooks('oldrev', 'newrev', 'refs/tags/v1.0.0', @user) + project.trigger_post_receive('oldrev', 'newrev', 'refs/tags/v1.0.0', @user) end end diff --git a/spec/workers/post_receive_spec.rb b/spec/workers/post_receive_spec.rb index 22e3e0d0..bbc91f44 100644 --- a/spec/workers/post_receive_spec.rb +++ b/spec/workers/post_receive_spec.rb @@ -27,16 +27,12 @@ describe PostReceive do PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false end - it "asks the project to execute web hooks" do + it "asks the project to trigger all hooks" do Project.stub(find_by_path: project) - project.should_receive(:execute_hooks).with('sha-old', 'sha-new', 'refs/heads/master', project.owner) - - PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) - end - - it "asks the project to observe push/create event data" do - Project.stub(find_by_path: project) - project.should_receive(:observe_push).with('sha-old', 'sha-new', 'refs/heads/master', project.owner) + project.should_receive(:execute_hooks) + project.should_receive(:execute_services) + project.should_receive(:update_merge_requests) + project.should_receive(:observe_push) PostReceive.perform(project.path, 'sha-old', 'sha-new', 'refs/heads/master', key_id) end From 406a0c809b3c10d8fb2754cf626094b98ee78aeb Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Mon, 19 Nov 2012 22:34:05 +0300 Subject: [PATCH 157/187] GitLabCi Service imtegration --- .../images/service-disabled-gitlab-ci.png | Bin 0 -> 2178 bytes app/assets/images/service-gitlab-ci.png | Bin 2758 -> 2393 bytes .../stylesheets/gitlab_bootstrap/common.scss | 3 ++ app/controllers/services_controller.rb | 37 +++++++++++++++ app/models/gitlab_ci_service.rb | 29 ++++++++++++ app/models/project.rb | 1 + app/models/service.rb | 2 +- app/roles/push_observer.rb | 4 +- app/views/projects/_project_head.html.haml | 4 ++ app/views/services/_gitlab_ci.html.haml | 42 ++++++++++++++++++ app/views/services/edit.html.haml | 2 + app/views/services/index.html.haml | 15 +++++++ config/routes.rb | 6 +++ .../20121120103700_add_active_to_service.rb | 5 +++ ...121120113838_add_project_url_to_service.rb | 5 +++ db/schema.rb | 10 +++-- 16 files changed, 158 insertions(+), 7 deletions(-) create mode 100644 app/assets/images/service-disabled-gitlab-ci.png create mode 100644 app/controllers/services_controller.rb create mode 100644 app/models/gitlab_ci_service.rb create mode 100644 app/views/services/_gitlab_ci.html.haml create mode 100644 app/views/services/edit.html.haml create mode 100644 app/views/services/index.html.haml create mode 100644 db/migrate/20121120103700_add_active_to_service.rb create mode 100644 db/migrate/20121120113838_add_project_url_to_service.rb diff --git a/app/assets/images/service-disabled-gitlab-ci.png b/app/assets/images/service-disabled-gitlab-ci.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1f9d0b50d01604383045d307369096fbfbda7f GIT binary patch literal 2178 zcma)8c{JPG7LK86C^cPkRf#sejaJn~4MiR?R1gmpQzg{!NTkF(R8*U)Xd1n=YAR}a zrV!es{e;-oJ01wa-~+ud~+K``h3C&PjE&w-Ogs5(R-k z;x^V6PQdyUu&csC!2E}h8V6YT!kw&OpqkGrY+xgVxoKqqI{tgSYAbsNctr5lsBjQS zOy+On1HH^u0GuZYHVDg;(_*rs7sY0iEM9;>!u&QC=FZWR>$x5dGAyN}0{bcAu!dI2 ziHA;VqI?zn=Z2CVML&{%8NGR%(oM$238_X^buvj{pkK{!EKvUr7xd6c_Pc-d0IX7oTM;O5T-_yv{n<87EUqaKljv3 z7%a&z@;@h0@W0Oeyul;fg+Ft0()t#=*aRm>$E2Y^zley;%*@|POG|}G?@$RZb8;?f zX)VsZBZc5_{60-nLu^9)(V+`=nR8HHQ89PGS+;X+{b(4Get88#osNkw6mo zUtoFrxHi0+H3v6@;MMg&c)$G<4s5?A7oD456q|u&PgOiIOkjJo? znCltft%Y70rwUmF0-<>N*(~}w{OkH2&~D; zfA^Six!gZ9Gx_iv)7L?&ripgCN=F+U9feaPqodS<0?I^)e{gUbP>q!p2+>TfGQr+n z;(|l|`}IiRW??~oMglLZy1H6}vWPbrWD|C{+&UWVey^XC>6buVAT>;#0*l4^P)~*z zOYyJgn}dEOn#RP$kc7U5&M?d?M=`XC5%cLY0^;K0QWB)CgLpETtgWwa1(rV8;A@%) zX=rNFu#x6)ICcmG($y7?L`qp&TJG%ZNQyqtIrL;iQ~h*$NvF@2S5>_R@N1evI5?bE zR#qmdUNJR2o8+VYsME*5amAtF2GzDiJEwnz8+*?2kS)+2lm&r640bpGapmOXejda_ zFJInX?34fGPitW$Tyk-7`B49KA)dd5{VPs@PPEVf$x~9C`Cophj z@arc`-Ba5VfVmxrcn(vzfx#emV>;P{dIlrcWf@QRoEYlZ+3YzcngJb!&9%SaTKQY$ z=;Lk-GT`lze?v)$W<)F4=IeT-oV@%+2;{Awj#R3Jgt51_!t3T{g|zOlg|G{PllNyg znQL4Oz!$;Qm6Z?WQ=Tn^)GuWY$7|VH@8(|B)lr9sogzFSvKTbl+$$`K*4Ea4cxXtc z(-k{I52q>8Hzb7}Jw3_2eumC!_dAp9%Xo#aza6{2BEY{B3=e)Cgu9}#p{1Nlfmm!e zu8DKV4entwv-9#?eBZRRwEQ5Buy;+G2u}DBafd6+$X1i$*!Jf=J#bk|baeEKy1J{# zll*R8UYaTr|3o6qvDo!O?7atOa%m@8S)WHnWD^n+LPA0uot%=H-;p;3;{?3Y;m@eC zoB6%csVOfns=n{);?K#+*^h5e2x#6BD20etI6scsoJobvZ@}hRtx>7)Vu1a3S4S$y z?oYusva+&+V`FdxLcGFxb#T(Qg}*KC`hn`$*cea<087uy@&LK3UDKd_x_Wx5&0v5# zcNkH0&t?|RyFEU}Pws_n$;yu(7R5t@!^1E%y72c3unpvKk!leNf*+D%$JqCB@1)pEJ-LtvptE&WvO;t@z(fAteUw`!aWo&PU`Jw!AI0@Q>9TuzA z>GPCIm4eFk75cs!Ujwo=j@u=3mIuDf%-E|_ePUuzM;HYk3?^Crig$TXhvZ7fhkCo; zGv}B3b0CiaP&>bGeZw34FdXE zmc)T7^8Behv`)6dnKO67!lY}*)5h1jzi&yVbpyI{NczI@=jN(xZ*Oa7+o85dvzq}}ta$BsrE9=H3MHx5DSkROfRMn8sb*?# zS65f5Crons;p$X1rS$st_RnKua`jMOo$NOgA%H0OtAwJ_L^tTeB8cF9^Tzzl=g&#+ z=Jq$#mp0ZY-5BeP6lkAY^;ng`B~{8b6B7guhlBU*kBfr$X_6h*vj5-H`YoW?1BH?* nR@+DGYG`Q8@0lf^T{6YJQEaHS-QNK|2p}6vdy5*FPx5~N!<-za literal 0 HcmV?d00001 diff --git a/app/assets/images/service-gitlab-ci.png b/app/assets/images/service-gitlab-ci.png index afaa10d02b037d1aa658c3b4eec658e2bed17224..bcb30a3fb1ada06b21c05de1814b7b6bea9e7652 100644 GIT binary patch literal 2393 zcmV-f38wamP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyx3 z3MeP^Lm4^%00`MhL_t(|+U=ZcY+KbGz<>8%U;FxXbL}Kf?4(H==hZAt3nfs7ST!Lb zp{nC0m^Q>{~krU?ZA;d0>MQhizyHYfdoPz zfe=U_1QG~@Kms9e43G1Vp*Tv?e%Q;dAR@09>Qr8fCk-(RgpP9A6;tq&4wy&s;gvg z?=Wvo&V6QM{^6D&9pwghztPR2nf=t?SLM`b_v(Df<7Sh`MJAVLBA(=LV<8TQ!bNQ> z?KYmeri~Nf7<-PK{9+4K-bgNQ6zL1);91D&yHxW4t;VD(V+c z79Lv0ES!zoTB`HVWsN-5GgQOPZhQxX<0+%zgT^c~|)izP~w$EI}rhr#lp( zuEar`*G-$(&7tube$)5iQu~yd10a#kez7Bv&u-=6%NkK6i9K(h;Dx?%R8>Y%B$BBt zSNc8t;;U`k-MoR(c!FbdA4Qg*{_7+U|Km7S<#sF<86__v17`NpI&8VMROf-Vdd6c3 ze%{&7JL7YpNTf1ZTD@)_-_go-Rb_Ne&2w~aLF7Q^u*ouyT-JogrgG0;yLc-!$L6{c zTB~)M{cg6@8BFKWeD^>P06RBS6!kANYy`^fC`#ea$>lD+Q@TF8l^?VRktBHVjSm=1 zBxtO1(-LsgUTct6^ZewU6Xf!6-=mmXLbqAFW8!w-lB%IGuuG^Ni(d{bn zl*zBVPZKpwB;cGTKiV2x%7N}|+Q7AyUH~4vJP5$|-uZxu#pDH#%WG4)Js4o4+kxMq z5zUy4$CKz$DrNCF z)un3^;M6QEBuyUcJc(UZP$h|^5U4<%%K^aA*#+G8m51cCS@>iB7#2msr)x;k@*L>- z<6}%Oq`0NY&;Ef)x~3vb#*-HuYwKKg_H1iLl_h#Y5&k(k$5nn0TT6A?OLg|VcY^*% zyr|F5I+`)FdHymu#g6JScKA!#>@BnnCDW_kuijmlgT6=%m-fkX;Lr+S9D;l)m#cy|D=P34x2{x$E{Y`6fJ z%d9S1g`rVtXzN0rbrXR$>IH$qnG7h!W_+uun%c7w>U>@p9A6dz0Ca~1yHx=|Qx$x= zc2Q$`< zBV<;|%>qu1Y(7sapTlwqmFL!lK*NzZey5F~$Hm}6u@qHyjm=*7vOfEUKHo|1jYLVC zIqJMlYFu`zof-kBMoUQ{Qds2WA@Jy2bm?ysV?4fc)-n)|v!z@o z;ItD;ri4Hj!qJ%pz8vsU>$EQu=$~NNWJdhxxO(Do}T94QxUS{srNX!xv_Ft zd#fU0w=SPfuU6Pior$mhz=zH*#|>@=$L3eA@!Z>7Lx<1cxq)$BK0PUtXn>*EA``JB zU#TkP)-@7Nx2mrBeR)1zbgFV{)awr39Gm6I?jgo9DH;MUTB~)oRT)c5)cGiqM5SYS z`JukVNh+Hoyhd`|H4|YWZE{;ffabHCijT9&aM9s2$mL;Q{~1w8TpEN$=B`(}n2e|R zdN9D9jn&k+>`T{GS)#>o@yO+k?5eLImxtIYrTfg;OS<*q0_@CUigYedt?r<<+=<~( zQDg~Sweanh4J+nAJ2&`>esA--X)AT}``%G3YZU&{Ql8y^??sj*cDDy<^|+TLwaOCP zeID*@t^wfL<71@d^-(Nc7fYB$maw~3?s~P0KkU4mU9}bLs;wYyW|>WY@gYLOXJS2*kEY7tRM_>> zVXp8QbodRf@Eg>ZI5|EOrEfMy=foTbN2jSNbKthEyp)}eFS565m|L6t1a$|7sxo$7 z-L}SUU$O6jQ5jW{+1oSB(NKgNf)!j}?PDks=jr!{dA@&wC$4Sf`i(xkHkG+lAxTb} zS#IBdggw_ZbN{AVA}NzUofzlIt|4kFod4Av7*3U!PEYds$TZsnUak&!>F^tblNko) z<2-YGl*3bDf|bto^4O5p+rM`)vpJ$klUOoKEMbx~vuG9tyG=&7t9V>iKE8MiOvQ-A zGql%~EEU+s=M&6D)0o*j8!HOS(AaE(smSUt05+64@aZ-(**tU66!VK2lIbj(s^D>{ z_;eeCp*Z1qhRro4*eo&wlQCjRljeY%(b)uxDHDq#;kK((d+jK)bU|~lm@000V#NklvscEC8n&{Y0CaF!^NixH;k*6%RZpr{gJ1x6;^lb&i!U~)ZxGX z<(_-)_nq%t714$-bfe(G5tt(aB2J(=BFBdb2yg;%BDjSBCy-n4@xh!xoC9tlzzO6Q ze0(q`5a)nf2yg$&g)HjG;iw*OGRnW*K0+4^JZ^P%U-P6|je9Anmjt#*NiY{Yt#EI|H!U>$ZMH!=u&9?nFlLW(y^>rif(%q*P-D~9Qr=ukiS z`ubprCJ;YgoP>8u8*#xfd1CK(0x{y}FHAxwWt+Fo)#0q3vLvm4*zQC+W#!#@=}6Tm z@n&f~t{BD+04ETEAoKCT+so4tu8?8#5gj^hHUz7rbPDMh-iQH<9m)|gK3TUEr9J)F zT{d~z9CT7g>ElZ!iw#+%4#19_UsJ|2@E3+1o-(1e`bH@c*yF2 z3St~wn}Z&!4f(~DusTOLffzs1N$b3plZwykJF&l}87czqRxvp20LvmKhXcC4egRk( zQ#H_*lo+gv&`cZt;@L{H4_Sq=vngR3nFJdXqY$rBAW|WR$?kxjvcsoWJ5WuUV?4%7 z*!I)q*hD%ji%PD|IZDr%@DY{V{u{dNb|vB);TrsGK|J0qy^7Dr;K{MgtN(Uxu;sB4`@pn4+N=6{#K$5(_QivwFTVvwJkgd!5Y z?@tlFw_4v@r2mrD{@8T91WqFRodzcmA+>i!CL;Z1*mz7Qh{mb0HARbgO2tih9%|H2 zWPq7n*xk@TT8Rt_A2BW%`=BP_J|3gCQT$^~4!&yZ#d|f^rV(ggX%oJ@ZV<>yk_;?c z9Qal?;sgD$^<=5gRk?}-dD)OtM%i#&Cuq4l4Nf4Ifzl}hMQO0(LJb-R#>&EY?4Yh> zQE1>zc<$6uxg(9i;$9G_Z^#ClV+3&;e=vJNOWsTrebNGzNFqX7FLiJmuXc zd^b4)XWNbVeO1#0ftWtpaO@%!vgzV?O%&<7^cd_Yu12GI$R#n>$3|jfN)+BGsYkid zwMWH-y__;s`_LH4cm^U6v{D)NJeY}7`d++SeeJfV?}?ajY);kQa{}$oosWb71rAoX zq3~J{N=S@5NxmkKh(5e7_a*|Z(rWPi!qN$0KfZ`(5~A^)ga~XqK`!;EYnOU)Aeo;_ zlkxXDJw9#ebcsQJ7P;PJHXdxyoIngIo6U(oKA43lr5uME+wo6olU>D@1T7v< z2)`|XvehcQl9MuLABbHg{BA`CPLa;ZKV6AHe<@VdRx?i~gWmlry}P)>h&`2)8HhR2 zKRr`{F3a@tQ?MvS5XVn_p@Y;{?D}xnNAaiC*-+3kub0%K_C|*{b-;YGJ6M2%1RO)ra4d zH%^o=Mxg&tXZDvHof-QAyVEOJOy5UYGmdxnOfyDjGKuM}5Rn8QJd#bmksW*KzOIHe z9$TxF*1tGJjrH-7h*kOF!^$>%(%JzTZ{sInwAx27Ybtp%6iE^VHrVu z!}MWyLj_;gz%Cgj!%=ce0)_fY@!mrVgz-%SLpV^|f;JMc;{qz{v@t1r1g-hK9MBX-&mBh3RM)G%F(bY^4Xl1lUxCbjCm;55#zeSMo_#|z( zp61$q@(R@CtpBg*8?@ums8GDTG*NieLQZoNH5KgeFx|uAL~{>*U0efg@K|TcHP94P ztyId`y;cs@_@$9*eGJC|H?_%n%j&>3cXyo4uD>``B=Qp|!u0Xg6A+Ci`GHb)_rl!*Cd) zyRZiGm_Dj%#d*qni4p!2*^Cot2C5D^btdY%%vLANWX4%3Q^-jd_{n_eZb*V4a$sj} zMMIYv{d9V>Vgm(tmWAGEfx$H949C+3sudEn^;*!?@4A&{<6?-MVF5DOX`I0{4C9a; zjM&Ub3{pyjuQhfLf@O;ZG#@J?4V`A8Q%sFgp_S$sBJwb|oMlL@#!t{rvk5kyVPK;5 zvtQYGIbAG=lKURyKbCdJgJtf@)_yurVx&a}%x0Rq^6Y(c8-G_;!(ZZY1UP{_4!L(t z$O+_K`|0u3Z~}Q8a_^du6Ue*v)8nh*1oAlK-Zdd7kaz8;$5+D%ZIDzH}9v? :service, :url => project_service_path(@project, @service), :method => :put) do |f| + - if @service.errors.any? + .alert-message.block-message.error + %ul + - @service.errors.full_messages.each do |msg| + %li= msg + + + .control-group + = f.label :active, "Active", class: "control-label" + .controls + = f.check_box :active + + .control-group + = f.label :active, "Project URL", class: "control-label" + .controls + = f.text_field :project_url, class: "input-xlarge", placeholder: "http://ci.gitlabhq.com/projects/3" + + .control-group + = f.label :token, class: "control-label" do + CI Project token + .controls + = f.text_field :token, class: "input-xlarge", placeholder: "GitLab CI project specific token" + + + .form-actions + = f.submit 'Save', class: 'btn save-btn' +   + = link_to 'Test settings', test_project_service_path(@project), class: 'btn btn-small' diff --git a/app/views/services/edit.html.haml b/app/views/services/edit.html.haml new file mode 100644 index 00000000..d893847f --- /dev/null +++ b/app/views/services/edit.html.haml @@ -0,0 +1,2 @@ += render "projects/project_head" += render 'gitlab_ci' diff --git a/app/views/services/index.html.haml b/app/views/services/index.html.haml new file mode 100644 index 00000000..3894fcee --- /dev/null +++ b/app/views/services/index.html.haml @@ -0,0 +1,15 @@ += render "projects/project_head" +%h3.page_title Services +%hr + +.row + .span6 + .padded + %p.slead Continuous integration server from GitLab + .thumbnail.left + = link_to edit_project_service_path(@project, :gitlab_ci) do + - if @gitlab_ci_service.try :active + = image_tag 'service-gitlab-ci.png' + - else + = image_tag 'service-disabled-gitlab-ci.png' + diff --git a/config/routes.rb b/config/routes.rb index bf762865..98cf7e81 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -133,6 +133,12 @@ Gitlab::Application.routes.draw do end end + resources :services, constraints: { id: /[^\/]+/ }, only: [:index, :edit, :update] do + member do + get :test + end + end + resources :deploy_keys resources :protected_branches, only: [:index, :create, :destroy] diff --git a/db/migrate/20121120103700_add_active_to_service.rb b/db/migrate/20121120103700_add_active_to_service.rb new file mode 100644 index 00000000..f45ef52e --- /dev/null +++ b/db/migrate/20121120103700_add_active_to_service.rb @@ -0,0 +1,5 @@ +class AddActiveToService < ActiveRecord::Migration + def change + add_column :services, :active, :boolean, default: false, null: false + end +end diff --git a/db/migrate/20121120113838_add_project_url_to_service.rb b/db/migrate/20121120113838_add_project_url_to_service.rb new file mode 100644 index 00000000..13ffbdb1 --- /dev/null +++ b/db/migrate/20121120113838_add_project_url_to_service.rb @@ -0,0 +1,5 @@ +class AddProjectUrlToService < ActiveRecord::Migration + def change + add_column :services, :project_url, :string, null: true + end +end diff --git a/db/schema.rb b/db/schema.rb index b1154270..27b1f4aa 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 => 20121120051432) do +ActiveRecord::Schema.define(:version => 20121120113838) do create_table "events", :force => true do |t| t.string "target_type" @@ -131,9 +131,11 @@ ActiveRecord::Schema.define(:version => 20121120051432) do t.string "type" t.string "title" t.string "token" - t.integer "project_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.integer "project_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "active", :default => false, :null => false + t.string "project_url" end create_table "snippets", :force => true do |t| From 9f65c274efbebf569b9d5576a33eabebda31e7e9 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 14:16:04 +0200 Subject: [PATCH 158/187] Fix ci service creation logic --- app/controllers/services_controller.rb | 2 +- app/models/gitlab_ci_service.rb | 10 +++++++--- app/views/services/_gitlab_ci.html.haml | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index b0fd7742..50f7e97a 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -19,7 +19,7 @@ class ServicesController < ProjectResourceController @service = @project.gitlab_ci_service if @service.update_attributes(params[:service]) - redirect_to :back + redirect_to edit_project_service_path(@project, :gitlab_ci) else render 'edit' end diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb index f5734dc2..020dc868 100644 --- a/app/models/gitlab_ci_service.rb +++ b/app/models/gitlab_ci_service.rb @@ -14,12 +14,16 @@ class GitlabCiService < Service attr_accessible :project_url - validates :project_url, presence: true - validates :token, presence: true + validates :project_url, presence: true, if: :activated? + validates :token, presence: true, if: :activated? delegate :execute, to: :service_hook, prefix: nil - after_save :compose_service_hook + after_save :compose_service_hook, if: :activated? + + def activated? + active + end def compose_service_hook hook = service_hook || build_service_hook diff --git a/app/views/services/_gitlab_ci.html.haml b/app/views/services/_gitlab_ci.html.haml index b2e2add3..3c9820b3 100644 --- a/app/views/services/_gitlab_ci.html.haml +++ b/app/views/services/_gitlab_ci.html.haml @@ -11,7 +11,7 @@ %hr -= form_for(@service, :as => :service, :url => project_service_path(@project, @service), :method => :put) do |f| += form_for(@service, :as => :service, :url => project_service_path(@project, :gitlab_ci), :method => :put) do |f| - if @service.errors.any? .alert-message.block-message.error %ul @@ -39,4 +39,5 @@ .form-actions = f.submit 'Save', class: 'btn save-btn'   - = link_to 'Test settings', test_project_service_path(@project), class: 'btn btn-small' + - if @service.valid? && @service.active + = link_to 'Test settings', test_project_service_path(@project), class: 'btn btn-small' From 93fdc4ca9d073ad73beacfd673ddc4e5652111ab Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 14:19:55 +0200 Subject: [PATCH 159/187] Reannotated --- app/models/gitlab_ci_service.rb | 16 +++++++++------- app/models/project_hook.rb | 1 + app/models/service.rb | 16 +++++++++------- app/models/service_hook.rb | 1 + app/models/system_hook.rb | 1 + app/models/web_hook.rb | 1 + spec/models/service_hook_spec.rb | 1 + spec/models/service_spec.rb | 16 +++++++++------- spec/models/system_hook_spec.rb | 1 + spec/models/web_hook_spec.rb | 1 + 10 files changed, 34 insertions(+), 21 deletions(-) diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb index 020dc868..0bce425f 100644 --- a/app/models/gitlab_ci_service.rb +++ b/app/models/gitlab_ci_service.rb @@ -2,13 +2,15 @@ # # Table name: services # -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# token :string(255) -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# token :string(255) +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# active :boolean default(FALSE), not null +# project_url :string(255) # class GitlabCiService < Service diff --git a/app/models/project_hook.rb b/app/models/project_hook.rb index aebf2054..2576fc97 100644 --- a/app/models/project_hook.rb +++ b/app/models/project_hook.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # class ProjectHook < WebHook diff --git a/app/models/service.rb b/app/models/service.rb index 70e29701..17a7a656 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -2,13 +2,15 @@ # # Table name: services # -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# token :string(255) -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# token :string(255) +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# active :boolean default(FALSE), not null +# project_url :string(255) # class Service < ActiveRecord::Base diff --git a/app/models/service_hook.rb b/app/models/service_hook.rb index aedd0eef..4cd2b272 100644 --- a/app/models/service_hook.rb +++ b/app/models/service_hook.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # class ServiceHook < WebHook diff --git a/app/models/system_hook.rb b/app/models/system_hook.rb index 3bc9089f..2ae5b131 100644 --- a/app/models/system_hook.rb +++ b/app/models/system_hook.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # class SystemHook < WebHook diff --git a/app/models/web_hook.rb b/app/models/web_hook.rb index ac3e10cf..df58fa93 100644 --- a/app/models/web_hook.rb +++ b/app/models/web_hook.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # class WebHook < ActiveRecord::Base diff --git a/spec/models/service_hook_spec.rb b/spec/models/service_hook_spec.rb index 25fc4096..0b0262c9 100644 --- a/spec/models/service_hook_spec.rb +++ b/spec/models/service_hook_spec.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # require "spec_helper" diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 0329b9a9..1a58f680 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -2,13 +2,15 @@ # # Table name: services # -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# token :string(255) -# project_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# token :string(255) +# project_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# active :boolean default(FALSE), not null +# project_url :string(255) # require 'spec_helper' diff --git a/spec/models/system_hook_spec.rb b/spec/models/system_hook_spec.rb index a99e91d3..9d03b56c 100644 --- a/spec/models/system_hook_spec.rb +++ b/spec/models/system_hook_spec.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # require "spec_helper" diff --git a/spec/models/web_hook_spec.rb b/spec/models/web_hook_spec.rb index aa040b50..2d930173 100644 --- a/spec/models/web_hook_spec.rb +++ b/spec/models/web_hook_spec.rb @@ -8,6 +8,7 @@ # created_at :datetime not null # updated_at :datetime not null # type :string(255) default("ProjectHook") +# service_id :integer # require 'spec_helper' From f6248c255e1cd6d6d27f1a8d9ac38adc75157c09 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 14:22:00 +0200 Subject: [PATCH 160/187] User custom method for services array --- app/models/project.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 95a2c6c9..d313c778 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -47,7 +47,6 @@ class Project < ActiveRecord::Base has_many :wikis, dependent: :destroy has_many :protected_branches, dependent: :destroy has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id' - has_many :services, dependent: :destroy has_one :gitlab_ci_service, dependent: :destroy delegate :name, to: :owner, allow_nil: true, prefix: true @@ -185,4 +184,8 @@ class Project < ActiveRecord::Base def issues_labels issues.tag_counts_on(:labels) end + + def services + [gitlab_ci_service].compact + end end From ed92cfdebd99680048b1a4b697cb338bb93b4170 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 16:46:22 +0200 Subject: [PATCH 161/187] Fix method call for service hook --- app/roles/push_observer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/roles/push_observer.rb b/app/roles/push_observer.rb index ea9347d0..2ee60646 100644 --- a/app/roles/push_observer.rb +++ b/app/roles/push_observer.rb @@ -57,7 +57,7 @@ module PushObserver services.each do |service| # Call service hook only if it is active - service.execute if service.active + service.execute(data) if service.active end end From 10d8b77b500e708f39f565f7f020814b4446a419 Mon Sep 17 00:00:00 2001 From: Alexander Simonov Date: Tue, 20 Nov 2012 18:57:45 +0200 Subject: [PATCH 162/187] Clean old rails2 style code --- config/initializers/4_resque.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/config/initializers/4_resque.rb b/config/initializers/4_resque.rb index 2a5721ec..3d167a6a 100644 --- a/config/initializers/4_resque.rb +++ b/config/initializers/4_resque.rb @@ -1,11 +1,9 @@ # Custom Redis configuration -rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..' -rails_env = ENV['RAILS_ENV'] || 'development' -config_file = File.join(rails_root, 'config', 'resque.yml') +config_file = Rails.root.join('config', 'resque.yml') if File.exists?(config_file) resque_config = YAML.load_file(config_file) - Resque.redis = resque_config[rails_env] + Resque.redis = resque_config[Rails.env] end # Queues From 18bc873d53e79ef947b4d3fd66413c32e29fc1cb Mon Sep 17 00:00:00 2001 From: Alexander Simonov Date: Tue, 20 Nov 2012 18:59:00 +0200 Subject: [PATCH 163/187] Resque must be running in the own namespace --- config/initializers/4_resque.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/4_resque.rb b/config/initializers/4_resque.rb index 3d167a6a..419dbe06 100644 --- a/config/initializers/4_resque.rb +++ b/config/initializers/4_resque.rb @@ -5,7 +5,7 @@ if File.exists?(config_file) resque_config = YAML.load_file(config_file) Resque.redis = resque_config[Rails.env] end - +Resque.redis.namespace = 'resque:gitlab' # Queues Resque.watch_queue(PostReceive.instance_variable_get("@queue")) From ebcbe0c87b12d10c40c6a3fa13ceec02e8220090 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 20:34:05 +0300 Subject: [PATCH 164/187] Add status badge for MR --- app/assets/stylesheets/sections/merge_requests.scss | 5 +++++ app/helpers/merge_requests_helper.rb | 4 ++++ app/models/gitlab_ci_service.rb | 4 ++++ app/models/project.rb | 4 ++++ app/views/merge_requests/show/_mr_box.html.haml | 3 +++ 5 files changed, 20 insertions(+) diff --git a/app/assets/stylesheets/sections/merge_requests.scss b/app/assets/stylesheets/sections/merge_requests.scss index 78e3fa39..9087e7c2 100644 --- a/app/assets/stylesheets/sections/merge_requests.scss +++ b/app/assets/stylesheets/sections/merge_requests.scss @@ -138,3 +138,8 @@ li.merge_request { } } +.status-badge { + height: 32px; + width: 100%; + @include border-radius(5px); +} diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb index 16855989..b23c4a8f 100644 --- a/app/helpers/merge_requests_helper.rb +++ b/app/helpers/merge_requests_helper.rb @@ -38,4 +38,8 @@ module MergeRequestsHelper classes << " merged" if mr.merged? classes end + + def ci_status_path + @project.gitlab_ci_service.commit_badge_path(@merge_request.last_commit.sha) + end end diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb index 0bce425f..24b70323 100644 --- a/app/models/gitlab_ci_service.rb +++ b/app/models/gitlab_ci_service.rb @@ -32,4 +32,8 @@ class GitlabCiService < Service hook.url = [project_url, "/build", "?token=#{token}"].join("") hook.save end + + def commit_badge_path sha + project_url + "/status?sha=#{sha}" + end end diff --git a/app/models/project.rb b/app/models/project.rb index d313c778..3cbc9417 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -188,4 +188,8 @@ class Project < ActiveRecord::Base def services [gitlab_ci_service].compact end + + def gitlab_ci? + gitlab_ci_service && gitlab_ci_service.active + end end diff --git a/app/views/merge_requests/show/_mr_box.html.haml b/app/views/merge_requests/show/_mr_box.html.haml index 26636435..b4b4be29 100644 --- a/app/views/merge_requests/show/_mr_box.html.haml +++ b/app/views/merge_requests/show/_mr_box.html.haml @@ -6,6 +6,9 @@ - else .alert-message.success.status_info Open = gfm escape_once(@merge_request.title) + - if @project.gitlab_ci? + .right + = image_tag ci_status_path, class: 'status-badge' .middle_box_content %div From 236584c2f804286b8cffab69c40deb0bca8c8632 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 20:01:25 +0200 Subject: [PATCH 165/187] update bootstrap to 2.2.1.1 --- Gemfile | 2 +- Gemfile.lock | 5 +++-- app/assets/stylesheets/gitlab_bootstrap/typography.scss | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index cb097668..b0f31a61 100644 --- a/Gemfile +++ b/Gemfile @@ -106,7 +106,7 @@ group :assets do gem "jquery-ui-rails", "2.0.2" gem "modernizr", "2.6.2" gem "raphael-rails", "2.1.0" - gem 'bootstrap-sass', "2.0.4" + gem 'bootstrap-sass', "2.2.1.1" gem "font-awesome-sass-rails", "~> 2.0.0" gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' end diff --git a/Gemfile.lock b/Gemfile.lock index 693b2060..d5be48d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,7 +97,8 @@ GEM backports (2.6.5) bcrypt-ruby (3.0.1) blankslate (3.1.2) - bootstrap-sass (2.0.4.0) + bootstrap-sass (2.2.1.1) + sass (~> 3.2) builder (3.0.4) capybara (1.1.3) mime-types (>= 1.16) @@ -446,7 +447,7 @@ DEPENDENCIES acts-as-taggable-on (= 2.3.3) annotate! awesome_print - bootstrap-sass (= 2.0.4) + bootstrap-sass (= 2.2.1.1) capybara carrierwave (~> 0.7.1) chosen-rails (= 0.9.8) diff --git a/app/assets/stylesheets/gitlab_bootstrap/typography.scss b/app/assets/stylesheets/gitlab_bootstrap/typography.scss index 97e85492..0afad789 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/typography.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/typography.scss @@ -2,6 +2,9 @@ * Headers * */ + +body { font-size: 13px; } +h1, h2, h3, h4, h5, h6 { margin:0 } h3, h4, h5, h6 { line-height: 36px; } h5 { font-size:14px; } h3.page_title { From 942c41011954e6b43ebc74340c668aa616e98e5b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 23:05:15 +0200 Subject: [PATCH 166/187] Implemented bootstrap 2.2.1.1. Restyled header panel --- .../stylesheets/gitlab_bootstrap/buttons.scss | 4 + .../gitlab_bootstrap/typography.scss | 4 +- app/assets/stylesheets/main.scss | 4 + app/assets/stylesheets/sections/header.scss | 85 ++++++------ app/assets/stylesheets/sections/projects.scss | 5 + app/assets/stylesheets/themes/ui_basic.scss | 32 ----- app/assets/stylesheets/themes/ui_mars.scss | 40 ++---- app/assets/stylesheets/themes/ui_modern.scss | 121 +++++------------- app/views/commits/_diffs.html.haml | 12 +- app/views/layouts/_head_panel.html.haml | 48 ++++--- app/views/layouts/_search.html.haml | 2 +- app/views/projects/_clone_panel.html.haml | 6 +- app/views/shared/_clone_panel.html.haml | 4 +- 13 files changed, 134 insertions(+), 233 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss index 4f631a3e..5f44362f 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss @@ -1,6 +1,8 @@ .btn { @include bg-gradient(#f7f7f7, #d5d5d5); border-color:#aaa; + font-size: 13px; + line-height: 17px; &:hover { @include bg-gray-gradient; border-color:#bbb; @@ -84,6 +86,7 @@ &.small { @extend .btn-small; + line-height: 16px; } &.active { @@ -94,6 +97,7 @@ &.very_small { font-size:11px; padding:2px 6px; + line-height: 16px; margin:2px; } diff --git a/app/assets/stylesheets/gitlab_bootstrap/typography.scss b/app/assets/stylesheets/gitlab_bootstrap/typography.scss index 0afad789..efe336cd 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/typography.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/typography.scss @@ -3,10 +3,10 @@ * */ -body { font-size: 13px; } -h1, h2, h3, h4, h5, h6 { margin:0 } +h1, h2, h3, h4, h5, h6 { margin: 0; } h3, h4, h5, h6 { line-height: 36px; } h5 { font-size:14px; } + h3.page_title { color:#456; font-size:20px; diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 698dd44a..099d5043 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -1,3 +1,7 @@ +/** Override bootstrap variables **/ +$baseFontSize: 13px !default; +$baseLineHeight: 18px !default; + @import "bootstrap"; @import "bootstrap-responsive"; @import 'font-awesome'; diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index 8328a5ab..1ad10f98 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -3,18 +3,27 @@ * */ header { - width:100%; - padding:0; - margin:0; - top:1px; - left:0; - background: #F1F1F1; /* for non-css3 browsers */ - border-bottom: 1px solid #ccc; - box-shadow: 0 -1px 0 white inset; - -moz-box-shadow: 0 -1px 0 white inset; - -webkit-box-shadow: 0 -1px 0 white inset; + &.navbar-gitlab { + .navbar-inner { + height:45px; + padding: 5px; + background: #F1F1F1; + + .nav > li > a { + color: $style_color; + text-shadow: 0 1px 0 #fff; + } + + /** NAV block with links and profile **/ + .nav { + float: right; + margin-right: 0; + } + } + } + z-index:10; - height:60px; + /*height:60px;*/ /** * @@ -22,21 +31,19 @@ header { * */ .app_logo { - width:200px; + width:170px; float:left; - position:relative; - top:-5px; a { float:left; + padding: 0px; h1 { - padding-top: 5px; width:90px; background: url('logo_dark.png') no-repeat 0px -3px; float:left; margin-left:5px; - font-size:36px; - line-height:36px; + font-size:30px; + line-height:48px; font-weight:normal; color:$style_color; text-shadow: 0 1px 1px #FFF; @@ -47,7 +54,6 @@ header { } .separator { - margin-left:20px; float: left; height: 60px; width: 1px; @@ -56,13 +62,6 @@ header { margin-top: -10px; } } - .container { - .top_panel_content { - margin:auto; - position:relative; - padding:15px 0; - } - } /** * @@ -74,33 +73,23 @@ header { float:left; margin:0; margin-right:30px; - font-size:36px; - line-height:36px; + font-size:30px; + line-height:48px; font-weight:normal; color:$style_color; text-shadow: 0 1px 1px #FFF; font-family: 'Korolev', sans-serif; } - .fbtn { - float: right; - margin-right:10px; - .btn { - margin-left:7px; - background: #F1F1F1; - border: 1px solid #CCC; - } - } - - /** * * Search box * */ .search { - float: right; margin-right: 45px; + margin-left:10px; + margin-top: 2px; .search-input { @extend .span2; @@ -108,8 +97,13 @@ header { background-repeat: no-repeat; background-position: 10px; padding-left:25px; - @include border-radius(5px); - border:1px solid #ccc; + font-size: 13px; + @include border-radius(2px); + border:1px solid #c6c6c6; + box-shadow:none; + &:focus { + @extend .span3; + } } } @@ -121,7 +115,7 @@ header { .account-box { position: absolute; right: 0; - top: 13px; + top: 6px; z-index: 10000; width: 128px; font-size: 11px; @@ -129,13 +123,13 @@ header { display: block; cursor: pointer; img { - @include border-radius(4px); + @include border-radius(2px); right: 5px; position: absolute; width: 28px; height: 28px; display: block; - top: 2px; + top:1px; &:after { content: " "; display: block; @@ -186,7 +180,7 @@ header { background: #333; display: none; z-index: 100000; - border-radius: 5px; + @include border-radius(4px); width: 100px; position: absolute; right: 10px; @@ -200,6 +194,7 @@ header { display: block; text-shadow: none; border-bottom: 1px solid #555; + font-size: 12px; &:hover { color:#eee; background: #444; diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index b1f20a3e..a17d2c96 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -85,9 +85,14 @@ } .project_clone_holder { + .btn { + height: 27px; + } input[type="text"] { + height: 17px; border: 1px solid #BBB; box-shadow: none; + padding: 4px 10px; } } diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss index cf5eda1c..09ff0747 100644 --- a/app/assets/stylesheets/themes/ui_basic.scss +++ b/app/assets/stylesheets/themes/ui_basic.scss @@ -15,36 +15,4 @@ color: $blue_link; } } - - header { - .fbtn { - .btn { - background-color: #F8F8F8; - background-image: -webkit-gradient(linear,left top,left bottom,from(#F8F8F8),to(#ECECEC)); - background-image: -webkit-linear-gradient(top,#F8F8F8,#ECECEC); - background-image: -moz-linear-gradient(top,#F8F8F8,#ECECEC); - background-image: -ms-linear-gradient(top,#F8F8F8,#ECECEC); - background-image: -o-linear-gradient(top,#F8F8F8,#ECECEC); - background-image: linear-gradient(top,#F8F8F8,#ECECEC); - filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f8f8f8',EndColorStr='#ececec'); - border-color: #C6C6C6; - margin-left:7px; - @include border-radius(3px); - box-shadow:none; - color:#666; - } - } - .search { - .search-input { - @include border-radius(3px); - border-color: #C6C6C6; - box-shadow:none; - } - } - .pic { - img { - @include border-radius(3px); - } - } - } } diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss index 77507569..3773e61c 100644 --- a/app/assets/stylesheets/themes/ui_mars.scss +++ b/app/assets/stylesheets/themes/ui_mars.scss @@ -14,42 +14,24 @@ * */ header { - background: #474D57 url('bg-header.png') repeat-x bottom; - box-shadow:none; - border-bottom: 1px solid #444; - .fbtn { - .btn { - i { - position: relative; - top: 1px; - } - margin-left:8px; - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#31363E)); - background-image: -webkit-linear-gradient(#595D63 6.6%, #31363E); - background-image: -moz-linear-gradient(#595D63 6.6%, #31363E); - background-image: -o-linear-gradient(#595D63 6.6%, #31363E); - font-size: 12px; - &:hover { - background-image: -webkit-gradient(linear, 0 0, 0 30, color-stop(0.066, #595D63), to(#2C2F35)); - background-image: -webkit-linear-gradient(#595D63 6.6%, #2C2F35); - background-image: -moz-linear-gradient(#595D63 6.6%, #202227); - background-image: -o-linear-gradient(#595D63 6.6%, #202227); - background-position:0 0; - color:#fff; - } + &.navbar-gitlab { + .navbar-inner { + background: #474D57 url('bg-header.png') repeat-x bottom; + border-bottom: 1px solid #444; - border: 1px solid #31363E; - color:#D6DADF; - text-shadow: 0 -1px 0 #000000; + .nav > li > a { + color: #eee; + text-shadow: 0 1px 0 #444; + } } } + .search { float: right; margin-right: 45px; .search-input { border: 1px solid rgba(0, 0, 0, 0.7); - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset; background-color: #D2D5DA; background-color: rgba(255, 255, 255, 0.5); @@ -65,7 +47,7 @@ a { h1 { background: url('logo_white.png') no-repeat 0px -3px; - color:#fff; + color:#eee; text-shadow: 0 1px 1px #111; } } @@ -75,7 +57,7 @@ } .project_name { - color:#fff; + color:#eee; text-shadow: 0 1px 1px #111; } } diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss index 8b942149..73445ec6 100644 --- a/app/assets/stylesheets/themes/ui_modern.scss +++ b/app/assets/stylesheets/themes/ui_modern.scss @@ -4,91 +4,34 @@ * * Next items should be placed there * - link colors - * - header styles - * - main menu styles + * - header restyles * */ .ui_modern { + /* * Application Header * */ header { - height:40px; - background-image: -moz-linear-gradient(top, #333, #222); - background-image: -ms-linear-gradient(top, #333, #222); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#333), to(#222)); - background-image: -webkit-linear-gradient(top, #333, #222); - background-image: -o-linear-gradient(top, #333, #222); - background-image: linear-gradient(top, #333, #222); - background-repeat: repeat-x; - background-repeat: repeat-x; - filter: progid:dximagetransform.microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0); - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); - .container .top_panel_content { padding: 5px 0; } + &.navbar-gitlab { + .navbar-inner { + background: #333; + border-bottom: 1px solid #111; - - /** - * - * Logo holder - * - */ - .app_logo { - width:160px; - a { - h1 { - background: none; - color:#DDD; - font-size:30px; - text-shadow: 0 1px 1px #111; - padding-left: 0; + .nav > li > a { + color: #eee; + text-shadow: 0 1px 0 #111; } } - .separator { - width: 1px; - height: 40px; - margin: 0 10px; - overflow: hidden; - background: #222; - border-left: 1px solid #333; - } } - .fbtn { - .btn { - i { - position: relative; - top: 2px; - } - background:none; - margin-left:8px; - font-size: 13px; - line-height: 19px; - color:#ccc; - &:hover { - color:#fff; - } - border: none; - box-shadow:none; - text-shadow: 0 -1px 0 #000000; - border-left: 1px solid #333; - } - } - - /** - * - * Search box - * - */ .search { float: right; margin-right: 45px; .search-input { border: 1px solid rgba(0, 0, 0, 0.7); - box-shadow: 0 1px 0 rgba(255, 255, 255, 0.2), 0 2px 2px rgba(0, 0, 0, 0.4) inset; background-color: #D2D5DA; background-color: rgba(255, 255, 255, 0.5); @@ -96,36 +39,30 @@ background-color: white; } } - .search-input::-webkit-input-placeholder { - color: #666; - } } + .search-input::-webkit-input-placeholder { + color: #666; + } + .app_logo { + a { + h1 { + background: url('logo_white.png') no-repeat 0px -3px; + color:#eee; + text-shadow: 0 1px 1px #111; + } + } + .separator { + display:none; + } - /** - * - * Project / Area name - * - */ + } .project_name { - line-height:36px; - font-size:30px; - color:#DDD; + color:#eee; text-shadow: 0 1px 1px #111; } - - /** - * - * Account box - * - */ - .account-box { - top:6px; - img { - top:1px; - right: 5px; - width: 26px; - height: 26px; - } - } } + /* + * End of Application Header + * + */ } diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml index 6ffc6d8b..53c2319f 100644 --- a/app/views/commits/_diffs.html.haml +++ b/app/views/commits/_diffs.html.haml @@ -22,7 +22,7 @@ .diff_file_header - if diff.deleted_file %span= diff.old_path - + - if @commit.prev_commit = link_to project_tree_path(@project, tree_join(@commit.prev_commit_id, diff.new_path)), {:class => 'btn right view-commit'} do View file @ @@ -31,11 +31,11 @@ %span= diff.new_path - if diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode %span.file-mode= "#{diff.a_mode} → #{diff.b_mode}" - - = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn right view-commit'} do + + = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)), {:class => 'btn very_small right view-commit'} do View file @ %span.commit-short-id= @commit.short_id(6) - + %br/ .diff_file_content -# Skipp all non non-supported blobs @@ -51,10 +51,10 @@ %div.image-info= "#{number_to_human_size file.size}" - else .diff_file_content_image.img_compared - .image.diff_removed + .image.diff_removed %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(old_file.data)}"} %div.image-info= "#{number_to_human_size file.size}" - .image.diff_added + .image.diff_added %img{src: "data:#{file.mime_type};base64,#{Base64.encode64(file.data)}"} %div.image-info= "#{number_to_human_size file.size}" - else diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index 4eed58e2..dd7cba22 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -1,29 +1,35 @@ -/ Page Header -%header.top_panel_holder - .container - .top_panel_content +%header.navbar.navbar-static-top.navbar-gitlab + .navbar-inner + .container %div.app_logo = link_to root_path, class: "home", title: "Home" do - %h1 - GITLAB + %h1 GITLAB %span.separator %h1.project_name= title - = render "layouts/search" - .fbtn + %ul.nav - if current_user.is_admin? - = link_to admin_root_path, class: "btn small", title: "Admin area" do - %i.icon-cog - Admin + %li + = link_to admin_root_path, title: "Admin area" do + %i.icon-cog + Admin - if current_user.can_create_project? - = link_to new_project_path, class: "btn small", title: "Create New Project" do - %i.icon-plus - Project - .account-box - = link_to profile_path, class: "pic" do - = image_tag gravatar_icon(current_user.email) - .account-links - = link_to profile_path, class: "username" do - My profile - = link_to 'Logout', destroy_user_session_path, class: "logout", method: :delete + %li + = link_to new_project_path, title: "Create New Project" do + %i.icon-plus + Project + %li + = render "layouts/search" + %li + .account-box + = link_to profile_path, class: "pic" do + = image_tag gravatar_icon(current_user.email) + .account-links + = link_to profile_path, class: "username" do + %i.icon-user.icon-white + My profile + = link_to destroy_user_session_path, class: "logout", method: :delete do + %i.icon-signout.icon-white + Logout + = render "layouts/init_auto_complete" diff --git a/app/views/layouts/_search.html.haml b/app/views/layouts/_search.html.haml index 80ecc530..7ea90798 100644 --- a/app/views/layouts/_search.html.haml +++ b/app/views/layouts/_search.html.haml @@ -1,5 +1,5 @@ .search - = form_tag search_path, method: :get do |f| + = form_tag search_path, method: :get, class: 'navbar-form pull-left' do |f| = text_field_tag "search", nil, placeholder: "Search", class: "search-input" :javascript diff --git a/app/views/projects/_clone_panel.html.haml b/app/views/projects/_clone_panel.html.haml index aa1a9cdc..461f4fea 100644 --- a/app/views/projects/_clone_panel.html.haml +++ b/app/views/projects/_clone_panel.html.haml @@ -6,12 +6,12 @@ .right - unless @project.empty_repo? - if can? current_user, :download_code, @project - = link_to archive_project_repository_path(@project), class: "btn small grouped" do + = link_to archive_project_repository_path(@project), class: "btn grouped" do %i.icon-download-alt Download - if @project.merge_requests_enabled && can?(current_user, :write_merge_request, @project) - = link_to new_project_merge_request_path(@project), title: "New Merge Request", class: "btn small grouped" do + = link_to new_project_merge_request_path(@project), title: "New Merge Request", class: "btn grouped" do Merge Request - if @project.issues_enabled && can?(current_user, :write_issue, @project) - = link_to new_project_issue_path(@project), title: "New Issue", class: "btn small grouped" do + = link_to new_project_issue_path(@project), title: "New Issue", class: "btn grouped" do Issue diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml index 947dc478..924eb3fc 100644 --- a/app/views/shared/_clone_panel.html.haml +++ b/app/views/shared/_clone_panel.html.haml @@ -1,4 +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 + %button{class: "btn active", :"data-clone" => @project.ssh_url_to_repo} SSH + %button{class: "btn", :"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" From 4d846c09b1982016356256afeb40dd252215429b Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Tue, 20 Nov 2012 23:18:44 +0200 Subject: [PATCH 167/187] Fixed spec --- app/assets/stylesheets/gitlab_bootstrap/buttons.scss | 4 ++-- spec/models/project_spec.rb | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss index 5f44362f..b66723d4 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss @@ -2,7 +2,7 @@ @include bg-gradient(#f7f7f7, #d5d5d5); border-color:#aaa; font-size: 13px; - line-height: 17px; + line-height: 18px; &:hover { @include bg-gray-gradient; border-color:#bbb; @@ -86,7 +86,7 @@ &.small { @extend .btn-small; - line-height: 16px; + line-height: 18px; } &.active { diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 4f7afd9d..5bcab924 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -37,7 +37,6 @@ describe Project do it { should have_many(:hooks).dependent(:destroy) } it { should have_many(:wikis).dependent(:destroy) } it { should have_many(:protected_branches).dependent(:destroy) } - it { should have_many(:services).dependent(:destroy) } end describe "Mass assignment" do From ec7a1c504f2549ed9093d489f395050568f3b2a8 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 00:18:36 +0200 Subject: [PATCH 168/187] Fix tabs line height --- app/assets/stylesheets/gitlab_bootstrap/common.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/stylesheets/gitlab_bootstrap/common.scss b/app/assets/stylesheets/gitlab_bootstrap/common.scss index bef0780f..c1b28801 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/common.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/common.scss @@ -40,6 +40,7 @@ > a { padding:8px 20px; margin-right: 7px; + line-height: 19px; border-color: #EEE; color:#888; border-bottom: 1px solid #ddd; From b39002ce8861c1c76806501309ff159d4d65f375 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 00:40:29 +0200 Subject: [PATCH 169/187] Use namespace for gitlab resque --- lib/hooks/post-receive | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/hooks/post-receive b/lib/hooks/post-receive index 4e596679..4a3ce372 100755 --- a/lib/hooks/post-receive +++ b/lib/hooks/post-receive @@ -8,5 +8,5 @@ do # For every branch or tag that was pushed, create a Resque job in redis. pwd=`pwd` reponame=`basename "$pwd" | sed s/\.git$//` - env -i redis-cli rpush "resque:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1 + env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$reponame\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1 done From 3ab33fcfca85e65931844124bda83148b6e27f69 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 09:04:32 +0200 Subject: [PATCH 170/187] Add post-receive file content validation --- lib/tasks/gitlab/status.rake | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/tasks/gitlab/status.rake b/lib/tasks/gitlab/status.rake index 508c41a2..cbc77abb 100644 --- a/lib/tasks/gitlab/status.rake +++ b/lib/tasks/gitlab/status.rake @@ -2,7 +2,7 @@ namespace :gitlab do namespace :app do desc "GITLAB | Check GitLab installation status" task :status => :environment do - puts "Starting diagnostics".yellow + puts "\nStarting diagnostics".yellow git_base_path = Gitlab.config.git_base_path print "config/database.yml............" @@ -86,17 +86,24 @@ namespace :gitlab do end if Project.count > 0 - puts "Validating projects repositories:".yellow + puts "\nValidating projects repositories:".yellow Project.find_each(:batch_size => 100) do |project| - print "#{project.name}....." + print "* #{project.name}....." hook_file = File.join(project.path_to_repo, 'hooks', 'post-receive') unless File.exists?(hook_file) puts "post-receive file missing".red - return + next end - puts "post-receive file ok".green + original_content = File.read(Rails.root.join('lib', 'hooks', 'post-receive')) + new_content = File.read(hook_file) + + if original_content == new_content + puts "post-receive file ok".green + else + puts "post-receive file content does not match".red + end end end From c1c1a1eeeecaadfd68a586adb8d6fd4daab4064f Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 09:14:15 +0200 Subject: [PATCH 171/187] Restored old h6 of bootstrap. Fixed buttons line-height --- app/assets/stylesheets/gitlab_bootstrap/buttons.scss | 3 --- .../stylesheets/gitlab_bootstrap/typography.scss | 5 +++++ app/assets/stylesheets/sections/projects.scss | 10 +++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss index b66723d4..f9249e87 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/buttons.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/buttons.scss @@ -1,8 +1,6 @@ .btn { @include bg-gradient(#f7f7f7, #d5d5d5); border-color:#aaa; - font-size: 13px; - line-height: 18px; &:hover { @include bg-gray-gradient; border-color:#bbb; @@ -86,7 +84,6 @@ &.small { @extend .btn-small; - line-height: 18px; } &.active { diff --git a/app/assets/stylesheets/gitlab_bootstrap/typography.scss b/app/assets/stylesheets/gitlab_bootstrap/typography.scss index efe336cd..fe3bd68b 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/typography.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/typography.scss @@ -14,6 +14,11 @@ h3.page_title { line-height: 28px; } +h6 { + color: #888; + text-transform: uppercase; +} + /** CODE **/ pre { font-family:'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; diff --git a/app/assets/stylesheets/sections/projects.scss b/app/assets/stylesheets/sections/projects.scss index a17d2c96..c9d386ab 100644 --- a/app/assets/stylesheets/sections/projects.scss +++ b/app/assets/stylesheets/sections/projects.scss @@ -85,14 +85,18 @@ } .project_clone_holder { + input[type="text"], .btn { - height: 27px; + font-size:12px; + line-height: 18px; + margin: 0; + padding: 3px 10px; } + input[type="text"] { - height: 17px; border: 1px solid #BBB; box-shadow: none; - padding: 4px 10px; + margin-left: -1px; } } From d18e2bd59d3003e2ae38116688e350bfc2774ae7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 06:14:05 +0300 Subject: [PATCH 172/187] styled error message --- app/assets/stylesheets/common.scss | 9 +++++---- app/views/shared/_no_ssh.html.haml | 9 ++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 843b683f..5eedd8ff 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -628,10 +628,11 @@ li.note { .error_message { @extend .cred; - border-bottom: 1px solid #D21; - padding-bottom:20px; - text-align:center; - margin-bottom:10px; + border-left: 4px solid #E99; + padding: 10px; + margin-bottom: 10px; + background: #FEE; + padding-left: 20px; } .oauth_select_holder { diff --git a/app/views/shared/_no_ssh.html.haml b/app/views/shared/_no_ssh.html.haml index a11f2bc4..c75a1d93 100644 --- a/app/views/shared/_no_ssh.html.haml +++ b/app/views/shared/_no_ssh.html.haml @@ -1,8 +1,3 @@ - if current_user.require_ssh_key? - %h6.error_message - %span - You won't be able to pull or push project code until you - %strong - = link_to new_key_path, class: "vlink" do - add an SSH key - to your profile + %p.error_message + You won't be able to pull or push project code until you #{link_to 'add an SSH key', new_key_path} to your profile From 6bf656970d9e4ccb1a46c78917844de6d72aad89 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 08:14:05 +0300 Subject: [PATCH 173/187] Use fieldset. Improved profile --- app/assets/stylesheets/common.scss | 12 ------ app/assets/stylesheets/sections/header.scss | 23 +++++------ app/assets/stylesheets/sections/nav.scss | 2 +- app/assets/stylesheets/sections/profile.scss | 14 +++++++ app/views/keys/index.html.haml | 2 +- app/views/profile/account.html.haml | 13 +++--- app/views/profile/design.html.haml | 31 +++++++-------- app/views/profile/show.html.haml | 42 ++++++++++---------- 8 files changed, 66 insertions(+), 73 deletions(-) diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index 5eedd8ff..aeaddb0b 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -20,18 +20,6 @@ body { float:right; } -.profile_avatar_holder { - float:left; - width:60px; - height:60px; - margin-right:20px; - img { - width:60px; - height:60px; - background:#eee; - } -} - .visible_link, .author_link { diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index 1ad10f98..90a57363 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -156,12 +156,7 @@ header { display: block; } } .account-links { - background: #79C3E0; - display: none; border-radius: 5px; - width: 100px; - margin-top: 0; - float: right; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); position: relative; &:before { @@ -171,33 +166,33 @@ header { position: absolute; border: 5px solid transparent; border-color: rgba(255, 255, 255, 0); - border-bottom-color: #333; + border-bottom-color: #555; text-indent: -9999px; top: -10px; line-height: 0; right: 10px; z-index: 10; } - background: #333; + background: #555; display: none; z-index: 100000; @include border-radius(4px); width: 100px; position: absolute; - right: 10px; - top: 42px; + right: 5px; + top: 38px; margin-top: 0; float: right; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); a { - color: #EEE; - padding: 6px 10px; + color: #fff; + padding: 7px 10px; display: block; text-shadow: none; - border-bottom: 1px solid #555; + border-bottom: 1px solid #666; font-size: 12px; &:hover { - color:#eee; - background: #444; + color:#fff; + background: #333; } } } diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss index 98bc7275..57072169 100644 --- a/app/assets/stylesheets/sections/nav.scss +++ b/app/assets/stylesheets/sections/nav.scss @@ -6,7 +6,7 @@ ul.main_menu { border-radius: 4px; margin: auto; margin:30px 0; - border:1px solid #AAA; + border:1px solid #BBB; height:37px; @include bg-gray-gradient; position:relative; diff --git a/app/assets/stylesheets/sections/profile.scss b/app/assets/stylesheets/sections/profile.scss index 206da3a9..e945ca00 100644 --- a/app/assets/stylesheets/sections/profile.scss +++ b/app/assets/stylesheets/sections/profile.scss @@ -6,3 +6,17 @@ } } } + +.profile_avatar_holder { + float:left; + width:60px; + height:60px; + margin-right:20px; + img { + width:60px; + height:60px; + background:#fff; + padding: 1px; + border: 1px solid #ddd; + } +} diff --git a/app/views/keys/index.html.haml b/app/views/keys/index.html.haml index fd5a9dad..f5a8283a 100644 --- a/app/views/keys/index.html.haml +++ b/app/views/keys/index.html.haml @@ -18,5 +18,5 @@ - if @keys.blank? %tr %td{colspan: 3} - %h3.nothing_here_message There are no SSH keys with access to your account. + %p.nothing_here_message There are no SSH keys with access to your account. diff --git a/app/views/profile/account.html.haml b/app/views/profile/account.html.haml index 112963cc..1e3a8b1a 100644 --- a/app/views/profile/account.html.haml +++ b/app/views/profile/account.html.haml @@ -1,7 +1,6 @@ - if Gitlab.config.omniauth_enabled? %fieldset - %legend - %h3.page_title Social Accounts + %legend Social Accounts .oauth_select_holder %p.hint Tip: Click on icon to activate sigin with one of the following services - User.omniauth_providers.each do |provider| @@ -11,10 +10,9 @@ %fieldset %legend - %h3.page_title - Private token - %span.cred.right - keep it secret! + Private token + %span.cred.right + keep it secret! .padded = form_for @user, url: profile_reset_private_token_path, method: :put do |f| .data @@ -31,8 +29,7 @@ = f.submit 'Generate', class: "btn success btn-build-token" %fieldset - %legend - %h3.page_title Password + %legend Password = form_for @user, url: profile_password_path, method: :put do |f| .padded %p.slead After successful password update you will be redirected to login page where you should login with new password diff --git a/app/views/profile/design.html.haml b/app/views/profile/design.html.haml index d70483a2..4eace607 100644 --- a/app/views/profile/design.html.haml +++ b/app/views/profile/design.html.haml @@ -1,7 +1,6 @@ = form_for @user, url: profile_update_path, remote: true, method: :put do |f| - %div - %h3.page_title Application theme - %br + %fieldset + %legend Application theme .themes_opts = label_tag do .prev @@ -23,19 +22,19 @@ %br .clearfix - %h3.page_title Code review - %br - .themes_opts - = label_tag do - .prev - = image_tag "white.png" - = f.radio_button :dark_scheme, false - White code preview - = label_tag do - .prev - = image_tag "dark.png" - = f.radio_button :dark_scheme, true - Dark code preview + %fieldset + %legend Code review + .themes_opts + = label_tag do + .prev + = image_tag "white.png" + = f.radio_button :dark_scheme, false + White code preview + = label_tag do + .prev + = image_tag "dark.png" + = f.radio_button :dark_scheme, true + Dark code preview :javascript $(function(){ diff --git a/app/views/profile/show.html.haml b/app/views/profile/show.html.haml index 7b625291..7d9e90cf 100644 --- a/app/views/profile/show.html.haml +++ b/app/views/profile/show.html.haml @@ -1,5 +1,5 @@ .profile_avatar_holder - = image_tag gravatar_icon(@user.email, 90), class: "styled_image" + = image_tag gravatar_icon(@user.email, 90) %h3.page_title = @user.name %br @@ -19,21 +19,23 @@ .control-group = f.label :name, class: "control-label" .controls - = f.text_field :name, class: "input-xlarge" + = f.text_field :name, class: "input-xlarge", required: true %span.help-block Enter your name, so people you know can recognize you. .control-group = f.label :email, class: "control-label" .controls - = f.text_field :email, class: "input-xlarge" + = f.text_field :email, class: "input-xlarge", required: true %span.help-block We also use email for avatar detection. .span5.right - %div.tips - %h6 Tips: + %fieldset.tips + %legend Tips: %ul + %li + %p You can change your password on Account page -unless Gitlab.config.disable_gravatar? %li - %p.hint You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"} + %p You can change your avatar at #{link_to "gravatar.com", "http://gravatar.com"} - if Gitlab.config.omniauth_enabled? && @user.provider? %li @@ -41,7 +43,6 @@ You can login through #{@user.provider.titleize}! = link_to "click here to change", profile_account_path - %hr .row .span7 .control-group @@ -59,23 +60,22 @@ = f.text_area :bio, rows: 6, class: "input-xlarge", maxlength: 250 %span.help-block Tell us about yourself in fewer than 250 characters. .span5.right - .ui-box.white - .ui-box-body - %h4 - Personal projects: - %small.right - %span= current_user.my_own_projects.count - of - %span= current_user.projects_limit + %fieldset + %legend + Personal projects: + %small.right + %span= current_user.my_own_projects.count + of + %span= current_user.projects_limit + .padded .progress .bar{style: "width: #{current_user.projects_limit_percent}%;"} - .ui-box.white - .ui-box-body - %h4 - SSH public keys: - %strong.right= link_to current_user.keys.count, keys_path - + %fieldset + %legend + SSH public keys: + %strong.right= link_to current_user.keys.count, keys_path + .padded = link_to "Add Public Key", new_key_path, class: "btn small" .form-actions From 00464099704ec16ad64faa3fe8c19d931ee7037a Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 08:14:05 +0300 Subject: [PATCH 174/187] I prefer icons on header --- app/assets/javascripts/main.js.coffee | 4 ++ app/assets/stylesheets/sections/header.scss | 58 +++++++++++++++++--- app/assets/stylesheets/themes/ui_basic.scss | 18 ++++++ app/assets/stylesheets/themes/ui_color.scss | 47 +--------------- app/assets/stylesheets/themes/ui_gray.scss | 47 +--------------- app/assets/stylesheets/themes/ui_modern.scss | 47 +--------------- app/views/layouts/_head_panel.html.haml | 12 ++-- 7 files changed, 81 insertions(+), 152 deletions(-) diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee index b41651bf..3f4b0f61 100644 --- a/app/assets/javascripts/main.js.coffee +++ b/app/assets/javascripts/main.js.coffee @@ -30,6 +30,10 @@ $ -> # Initialize tooltips $('.has_tooltip').tooltip() + # Bottom tooltip + $('.has_bottom_tooltip').tooltip(placement: 'bottom') + + # 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/header.scss b/app/assets/stylesheets/sections/header.scss index 32f6d855..0db40ec9 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -12,6 +12,8 @@ header { .nav > li > a { color: $style_color; text-shadow: 0 1px 0 #fff; + font-size: 18px; + padding: 11px; } /** NAV block with links and profile **/ @@ -51,15 +53,6 @@ header { height:40px; font-family: 'Korolev', sans-serif; } - - } - .separator { - float: left; - height: 60px; - width: 1px; - background: white; - border-left: 1px solid #DDD; - margin-top: -10px; } } @@ -218,5 +211,52 @@ header { border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; border-bottom: 0; } } + + + + /* + * Dark header + * + */ + &.header-dark { + &.navbar-gitlab { + .navbar-inner { + background: #708090; + border-bottom: 1px solid #AAA; + + .nav > li > a { + color: #fff; + text-shadow: 0 1px 0 #111; + } + } + } + + .search { + .search-input { + background-color: #D2D5DA; + background-color: rgba(255, 255, 255, 0.5); + + &:focus { + background-color: white; + } + } + } + .search-input::-webkit-input-placeholder { + color: #666; + } + .app_logo { + a { + h1 { + background: url('logo_white.png') no-repeat 0px 2px; + color:#fff; + text-shadow: 0 1px 1px #111; + } + } + } + .project_name { + color:#fff; + text-shadow: 0 1px 1px #111; + } + } } diff --git a/app/assets/stylesheets/themes/ui_basic.scss b/app/assets/stylesheets/themes/ui_basic.scss index 09ff0747..1f3d3d3d 100644 --- a/app/assets/stylesheets/themes/ui_basic.scss +++ b/app/assets/stylesheets/themes/ui_basic.scss @@ -15,4 +15,22 @@ color: $blue_link; } } + + .app_logo { + .separator { + margin-left: 0; + margin-right: 0; + } + } + + .separator { + float: left; + height: 60px; + width: 1px; + background: white; + border-left: 1px solid #DDD; + margin-top: -10px; + margin-left: 10px; + margin-right: 10px; + } } diff --git a/app/assets/stylesheets/themes/ui_color.scss b/app/assets/stylesheets/themes/ui_color.scss index 4497892d..8c60fabb 100644 --- a/app/assets/stylesheets/themes/ui_color.scss +++ b/app/assets/stylesheets/themes/ui_color.scss @@ -8,61 +8,16 @@ * */ .ui_color { - /* * Application Header * */ header { - + @extend .header-dark; &.navbar-gitlab { .navbar-inner { background: #657; - border-bottom: 1px solid #AAA; - - .nav > li > a { - color: #fff; - text-shadow: 0 1px 0 #111; - } } } - - .search { - float: right; - margin-right: 45px; - .search-input { - border: 1px solid #aaa; - background-color: #D2D5DA; - background-color: rgba(255, 255, 255, 0.5); - - &:focus { - background-color: white; - } - } - } - .search-input::-webkit-input-placeholder { - color: #666; - } - .app_logo { - a { - h1 { - background: url('logo_white.png') no-repeat 0px 2px; - color:#fff; - text-shadow: 0 1px 1px #111; - } - } - .separator { - display:none; - } - - } - .project_name { - color:#fff; - text-shadow: 0 1px 1px #111; - } } - /* - * End of Application Header - * - */ } diff --git a/app/assets/stylesheets/themes/ui_gray.scss b/app/assets/stylesheets/themes/ui_gray.scss index 5ee2b0dd..e80137a6 100644 --- a/app/assets/stylesheets/themes/ui_gray.scss +++ b/app/assets/stylesheets/themes/ui_gray.scss @@ -8,61 +8,16 @@ * */ .ui_gray { - /* * Application Header * */ header { - + @extend .header-dark; &.navbar-gitlab { .navbar-inner { background: #708090; - border-bottom: 1px solid #AAA; - - .nav > li > a { - color: #fff; - text-shadow: 0 1px 0 #111; - } } } - - .search { - float: right; - margin-right: 45px; - .search-input { - border: 1px solid #aaa; - background-color: #D2D5DA; - background-color: rgba(255, 255, 255, 0.5); - - &:focus { - background-color: white; - } - } - } - .search-input::-webkit-input-placeholder { - color: #666; - } - .app_logo { - a { - h1 { - background: url('logo_white.png') no-repeat 0px 2px; - color:#fff; - text-shadow: 0 1px 1px #111; - } - } - .separator { - display:none; - } - - } - .project_name { - color:#fff; - text-shadow: 0 1px 1px #111; - } } - /* - * End of Application Header - * - */ } diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss index 0bb14cdd..32b5ad7d 100644 --- a/app/assets/stylesheets/themes/ui_modern.scss +++ b/app/assets/stylesheets/themes/ui_modern.scss @@ -8,61 +8,16 @@ * */ .ui_modern { - /* * Application Header * */ header { - + @extend .header-dark; &.navbar-gitlab { .navbar-inner { background: #567; - border-bottom: 1px solid #AAA; - - .nav > li > a { - color: #fff; - text-shadow: 0 1px 0 #111; - } } } - - .search { - float: right; - margin-right: 45px; - .search-input { - border: 1px solid #aaa; - background-color: #D2D5DA; - background-color: rgba(255, 255, 255, 0.5); - - &:focus { - background-color: white; - } - } - } - .search-input::-webkit-input-placeholder { - color: #666; - } - .app_logo { - a { - h1 { - background: url('logo_white.png') no-repeat 0px 2px; - color:#fff; - text-shadow: 0 1px 1px #111; - } - } - .separator { - display:none; - } - - } - .project_name { - color:#fff; - text-shadow: 0 1px 1px #111; - } } - /* - * End of Application Header - * - */ } diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index dd7cba22..38e1d7f0 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -9,14 +9,16 @@ %ul.nav - if current_user.is_admin? %li - = link_to admin_root_path, title: "Admin area" do - %i.icon-cog - Admin + = link_to admin_root_path, title: "Admin area", class: 'has_bottom_tooltip', 'data-original-title' => 'Admin area' do + %i.icon-cogs - if current_user.can_create_project? %li - = link_to new_project_path, title: "Create New Project" do + = link_to new_project_path, title: "Create New Project", class: 'has_bottom_tooltip', 'data-original-title' => 'New project' do %i.icon-plus - Project + %li + = link_to profile_path, title: "Your Profile", class: 'has_bottom_tooltip', 'data-original-title' => 'Your profile' do + %i.icon-user + %span.separator %li = render "layouts/search" %li From 898d09a21ef3bf937d0b9379dd13c917b553e859 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 12:45:15 +0200 Subject: [PATCH 175/187] Gitlab_meta to 3.1. Added workaround for 500 Redis error until it will be fixed --- Gemfile | 2 +- Gemfile.lock | 4 ++-- app/controllers/admin/dashboard_controller.rb | 9 +++++-- app/views/admin/dashboard/index.html.haml | 24 ++++++++++++------- 4 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Gemfile b/Gemfile index b0f31a61..f723f587 100644 --- a/Gemfile +++ b/Gemfile @@ -152,5 +152,5 @@ group :test do end group :production do - gem "gitlab_meta", '3.0' + gem "gitlab_meta", '3.1' end diff --git a/Gemfile.lock b/Gemfile.lock index d5be48d1..0e3a9810 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -171,7 +171,7 @@ GEM mime-types (~> 1.19) pygments.rb (>= 0.2.13) github-markup (0.7.4) - gitlab_meta (3.0) + gitlab_meta (3.1) gitolite (1.1.0) gratr19 (~> 0.4.4.1) grit (~> 2.5.0) @@ -465,7 +465,7 @@ DEPENDENCIES git github-linguist (~> 2.3.4) github-markup (~> 0.7.4) - gitlab_meta (= 3.0) + gitlab_meta (= 3.1) gitolite (= 1.1.0) grack! grape (~> 0.2.1) diff --git a/app/controllers/admin/dashboard_controller.rb b/app/controllers/admin/dashboard_controller.rb index 5152f6fa..827dd0cf 100644 --- a/app/controllers/admin/dashboard_controller.rb +++ b/app/controllers/admin/dashboard_controller.rb @@ -1,8 +1,13 @@ class Admin::DashboardController < AdminController 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) + + @resque_accessible = true + @workers = Resque.workers + @pending_jobs = Resque.size(:post_receive) + + rescue Redis::InheritedError + @resque_accessible = false end end diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 3e26f566..b0b59a46 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -4,13 +4,21 @@ %h5 Resque Workers .data.padded - = link_to admin_resque_path do - %h1{class: @workers.present? ? "cgreen" : "cred"} - = @workers.count - %hr - %p - %strong{class: @pending_jobs > 0 ? "cred" : "cgreen"} - #{@pending_jobs} post receive jobs waiting + - if @resque_accessible + = link_to admin_resque_path do + %h1{class: @workers.present? ? "cgreen" : "cred"} + = @workers.count + %hr + %p + %strong{class: @pending_jobs > 0 ? "cred" : "cgreen"} + #{@pending_jobs} post receive jobs waiting + - else + = link_to admin_resque_path do + %h1.cdark ? + %hr + %p + %strong Resque status unknown + .span4 .ui-box @@ -42,6 +50,6 @@ %hr - @users.each do |user| %p - = link_to [:admin, user] do + = link_to [:admin, user] do = user.name %small= user.email From a0f2f05e50312efcbf878f877fcde7888a52e3e1 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 12:52:55 +0200 Subject: [PATCH 176/187] Updated README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a8f8c0bb..1816629d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ GitLab is a free project and repository management application * Ubuntu/Debian * ruby 1.9.3+ -* mysql or sqlite +* MySQL * git * gitolite * redis From cc5391515a71956820723a77ec121c4ab1abc626 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 13:27:11 +0200 Subject: [PATCH 177/187] Updated ROADMAP and CHANGELOG --- CHANGELOG | 18 ++++++++++++++++++ ROADMAP.md | 9 +++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 58111484..2eca1f14 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,21 @@ +v 3.1.0 + - Updated gems + - Services: Gitlab CI integration + - Events filter on dashboard + - Own namespace for redis/resque + - Optimized commit diff views + - add alphabetical order for projects admin page + - Improved web editor + - Commit stats page + - Documentation split and cleanup + - Link to commit authors everywhere + - Restyled milestones list + - added Milestone to Merge Request + - Restyled Top panel + - Refactored Satellite Code + - Added file line links + - moved from capybara-webkit to poltergeist + phantomjs + v 3.0.3 - Fixed bug with issues list in Chrome - New Feature: Import team from another project diff --git a/ROADMAP.md b/ROADMAP.md index 093a23f5..465342f8 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,7 +5,6 @@ * 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 @@ -15,5 +14,11 @@ ### Merge Request -* CI build status * Save code fragments with MR comments + +### Services + +* Campfire integration service +* Hipchat integration service +* Travis CI integration service +* Jenkins CI integration service From 8c5b79a923770195d5c6cb73ac1451df81351910 Mon Sep 17 00:00:00 2001 From: Martins Polakovs Date: Wed, 21 Nov 2012 12:21:12 +0000 Subject: [PATCH 178/187] Fixes :notice after project is created When projects were created in projects_controller create.js.haml passed notice as url parameter and therefore notice was not displayed in the page after redirect to the project page --- app/controllers/projects_controller.rb | 3 ++- app/views/projects/create.js.haml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 7d70852f..72080070 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -21,9 +21,10 @@ class ProjectsController < ProjectResourceController @project = Project.create_by_user(params[:project], current_user) respond_to do |format| + flash[:notice] = 'Project was successfully created.' if @project.saved? format.html do if @project.saved? - redirect_to(@project, notice: 'Project was successfully created.') + redirect_to @project else render action: "new" end diff --git a/app/views/projects/create.js.haml b/app/views/projects/create.js.haml index e8684565..ce73fe0c 100644 --- a/app/views/projects/create.js.haml +++ b/app/views/projects/create.js.haml @@ -1,6 +1,6 @@ - if @project.saved? :plain - location.href = "#{project_path(@project, notice: 'Project was successfully created.')}"; + location.href = "#{project_path(@project)}"; - else - if @project.git_error? location.href = "#{errors_githost_path}"; From 4c6c24856cc326e26b6f7ac91ee6eae9fcc722f7 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Wed, 21 Nov 2012 07:14:05 +0300 Subject: [PATCH 179/187] Themes refactored --- app/assets/images/gitlab_classic.png | Bin 3054 -> 0 bytes app/assets/images/gitlab_default.png | Bin 6435 -> 0 bytes app/assets/images/gitlab_modern.png | Bin 3892 -> 0 bytes app/assets/images/logo_dark.png | Bin 2858 -> 2589 bytes app/assets/images/logo_white.png | Bin 1681 -> 1517 bytes app/assets/stylesheets/common.scss | 19 ------ app/assets/stylesheets/main.scss | 9 ++- app/assets/stylesheets/sections/header.scss | 10 +-- app/assets/stylesheets/sections/themes.scss | 53 +++++++++++++++ app/assets/stylesheets/themes/ui_color.scss | 68 +++++++++++++++++++ app/assets/stylesheets/themes/ui_gray.scss | 68 +++++++++++++++++++ app/assets/stylesheets/themes/ui_mars.scss | 2 +- app/assets/stylesheets/themes/ui_modern.scss | 14 ++-- app/views/profile/design.html.haml | 21 ++++-- lib/gitlab/theme.rb | 6 +- 15 files changed, 224 insertions(+), 46 deletions(-) delete mode 100644 app/assets/images/gitlab_classic.png delete mode 100644 app/assets/images/gitlab_default.png delete mode 100644 app/assets/images/gitlab_modern.png create mode 100644 app/assets/stylesheets/sections/themes.scss create mode 100644 app/assets/stylesheets/themes/ui_color.scss create mode 100644 app/assets/stylesheets/themes/ui_gray.scss diff --git a/app/assets/images/gitlab_classic.png b/app/assets/images/gitlab_classic.png deleted file mode 100644 index 4e189e220abb3d6e08f067802f95cdbe862853bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3054 zcmd5;c{J2rA0NZWHl+tccofPmlXdV|M#xh3CHu&}j7B4orC~Bzitt!Qlbx|&Cs2D~-Qqnkuj1LP1rs5qMUc=8;!M`9%Q1V-NbzNk1 ziqKqIyZUUa_5gN6N2ASjPiv)TzIaGyX{O~U=(usj$!`tI*Yjle(CZ}*Y(>$A{DGr& za$o1fJpi5?7m1AN|GiB@|Qgbb5~d>7XkrE zGeG>Cb}W?T02B)Ldo$~Q+04u77iujokS2T8>~MqixTHLjT#yklM)7!WPP^w7dpx`U z=%3kl#ycv?C3Ave}_DdS-d_QHBU`0E?LTbdS7=?Vw-x;mLTe$QoP1})d$ z3{=f+V;R5Z7iAYl1JI10yWFGJYXx%_Q!kxzn?l=%hln41CkoN`YGO5P6}DoB`FUB% z+@^4D^wFkL-`Exkv3A>8s(xm_gyLoSsAM>e5)qu7l1&Z9)h)&;?3>WpA5_k7Wln z*}!_9hqa>xIS{MNp9mqX*9z=s8~OQIv3sYJ#i5 z4LFr7j;9c^3y)k~1dX3CnO(m!RYA;5qeA3(bhtnx1?zZ5<2i53-ZN5!*E$zYxoaCI z@J*2J7B=UDN5XM5MfR;_nLAveJBHV-WdukwotvRlV_F|dd_qI#c9eqfNWH^fXP;@J zFD0VqB_4C5+Ko9|-O}n@&`&(oTQOmlOA(PuzZZ3mbZ0HV@U9hm(OqwcNhoU>+XrL! zj+pnVTy|O`-fBhgnX*ubUue#)LW@U5bO&8_jR>?z@O?Vr4mNGi)T?KW#hCF>HOH$p z-5-HgjSe&z96x@e-qHUw3?j}QRbE7oR@w9k&~aQ#cVUOO`8|ZsNCQ57uG$;IfagV)&s)tG&fmc8GW4rKfIqkBIsL zf#rATYY=d0m0?5dA_YHqUBZ}M&&sHR``}MMe|=t#Ff~*XQdGToumQXxnhGe>rFN@Z# z^-+czJBUfz=n!=cS`&ntShpKd+R=M99GZ(p%B%)NT)So|c5~bNZ8>v5(u}Wbjo<9U zeRyTqjmGwri$xKDYa-T|Tm9HsX3LQD6yzz-MU#=;j0U*1Vj?ja*{P(_fDONW{Mb8i z?hCqMOzV4C>O^=k-Fx|rm3wEf%k-+@(gUo|4hQdNrRibfNsImVoG4Gt=>+KXE_Gw; zwzn4IhfqQEp3ygz$S-Qp`D?l01-hY75e^0rPPPfvGL#Es5h{-Fbq0d%ECJQ)mjxmE z6L{EztU;K-B-Nk%WDuQSP+6$Ph=o#l;r*s935>IK9YodtrvZ~rXWfkknBTlK|Kn2q z;>90=EacL}UI#U<^HRrqK9owS8H`;9IBAL8$%eRK#Pht$8bodhG=N?ylYJ~BCu_v` z8>Ti{ZNTDfA>c{K{6oOx@2o6wtl2}+;M6W~(txG$YS(?dm3|@M0cs4@coKk+ilCau z0TAMl_#rI-g4P0$5(G#j2s>121t8P!i7K7^6#xVw)!drP00haAO`HE`1H2IOFK59c zL65CsulT?{8y-@cn2toOPQ)foOgEYXp*HG#p*safGl<+@chibFRGobhiVvA>FFS9D zv8@JwrVf$oNU|FUMI$IvcdcvkB_E*J~G%;r{_MR-6b6|^+T(ZSeWgKH^NuCor zGyV*>kJ*-8TbpiO{`Rg!HFy&4eRWO6A^rHbsb-!fz=Z$LgRNu(R>u~35Ta!ibg)qi z#?hw7DDX9|#Q3JtQbXXw=#cgqYBhtlZ=dv zd|UzjJ-<5HfW`=Pgx?4AFh170EYGxIoBiKOe4p#lb9;e_6BZE(*rfNW-dY??g-gN; zSP)*PjrB-$Li*b$8nmLz53V+uw1&+3zs*w%Tb;aARaZw2pp{$u_>`S}#Z?c+aB*a? z@zuF?7(Y=*D|7St4(B4fqV~&wG52Xi6+i#)ZV{tiCs)_i z1b=vO8CX!sy|g80!Ul^~$;!#0rT(e??dTWN&f3}&CXZRUkhV-CvyLc8ouUsLC_U-ukCg;xm$OS!CO!6tu z0c{HLF>lOE*p*033Ai$ZS-d&!rcP~FMFtDPk>NWq})U$daBp-y|X#O=mX$#fko?BnJ zYCU>BlRirQ!6^(!ffTRT|7C|U^bYHD@s8z;Hy(=>p4D|OOlXG&2WgV$meEI4bI6Cn4DE5ZT8vP}&h8Uc* zzdl<6oZ9^2BwsA?w!T3LiyDN(HMJc?jZMhKQ2h7~f z%`Ig(V1CgL=~?Osh$TX^a~vG8G+J;o?_`8)dsvb~&2>*PzrYjphZkFA5Zv6{B~b*$ zX}7pC^BjV&1-G={$kfynSy|f8)_Y`lo`pnIdkK>Tm}5;_4LCS(ykgIu^~$JOoX?x= z)BEG?kfO*P#s$kDG$YJ1sO^jxQ6+B}r;=weDQ6gWd*vfhTGAO2**00@)O3}~l2+|l z_nrV18D{=$oC~Fz4;}QF9-|=SXbDsIvck+>Zl?I#8kzKiJjv;K_o!+ZrxA z&~^Hw4a5nK?qz#@HqzeK5lM&n&$1Wj>q9P+T?816U|JCAi4Y&Ggm=Y=>aM@z)?dc>GX_U6;1|`^@<}z9uTc^(7$H( zJOH(N?;)zl24INy6e{`{5VuDI95A{6y?}njrpM@sebBt!{m7$QmtA`MDO zNKd*$aCA%8`}khHckk8z=6|uBi#^}-J>L`G^PJBj?&+#C&~egHP*5;vYN*@?~m`i<&AySyk^T_?-h3@)vuJK-gL|;El-#C7)vqnFBcL{ zw~VYmZ1vh*w-3I+RIyQa+(SC~{It^DKEt_{V<<~0xNt42Tk-tFWq-9Hkm|E)BwL05 zxnHWJMJT`PK(t`fz%Gtk2}6kaailV7@X@?eeI5u;8(L_Aaf4++q-Y z{u$#axi@p8YZ=_faDRPrE&hRSNxz=rq|LC`?sB#D^t3~G@oyd%6 z#PHm)orV(X)+)yNdghzkMiGmd-P9|==b1j+?GC|>ZN(<_XU++Wsn&zHk{Zqf@+``P<8s{wB3%Tqo(I$Tng;rt>&Q~8ey^4Uo7%p452@gp~cKUH@vq|~T> zfys>tyhOV$-dh2y;E@ba>M$v1H}ZuDW=+cz24}h^odEk^*{Y%5nA$qTi0|>9TVw6! z^ymP&Cw=876D0>#W0Ri3VRQ5?BZP#?PW@q&LWyfQ6(T&-cQ3g_5<4$aRMj+_@twJ~Dle%{nB`pl>L41W;0?mCw@8AOG#wGd5-N=c&(VxRThBtCO0){QS~rWm|5D z%nz#;q3zva6M1Z@&CClGXQY#-ll|4QUbR3smZ^Y~D$kg@qypa5^Qd!WTa-c$`J?z{ znA~sMl94OM#$HPwiiCo0F9b8;A7_0o`o3pqU6hcGFx|L7c}rXA1P5^i=J%)lH;#7C zUJ`wk!@;tai*7Et;$dsUA`(#FuL!kJ-crZ=pPzap{MW*{MNp%{YAfb)%ez;hosd2! z6!yTDlRiM+iV{X~%3UXx(BXo2i6)}d=q&t7BUx3HFsGpHGQsDlsRW?;(W!Ak6y$`* z&z^iND+7!vsQiwWgnu*#Ys7kbAV!8w{C(TuJjl6`i?g-l6uXQ5XUhe}?r*kaskePk zw%U3&p8u#q0INy>oj?DVuq?z3+}QOE{i6O0n4HVM%c)#YE3vAg#%+Zhp1G9SibQd> zeDmCyc=;`~^|Cn+9+lj}lHzHhZ))#}m5y-?dH_rSWyc}#X9hCUvh2hE8N+HYIrVg1 zceU{+6SeC#BGweS4P=-9lpoX`uh;6bm@)1#@~t@2i$e)JhDmcMQ6>`v$`IatL6d|V z1)|kdYQyLalllW4>raQCuvRgQYMX@6@DHBoA22^v_QGTTj@xAV7ULn_1 zwEY#LF9jn!xF0%ZxmqQCGLXQBZ8OO8nDT5(4%H93DOppHe|Pg0!=F$tM^QBwakkAL zOo~+%%$rKVG>_8r_y>~a0ND@h1R>J|j>Z^eT+I4`Sz!|C#OnQX3%P|fm;6CeA-B>k zMIJQu3o0j>5fm+SNKny`ARc?^;EPI`q-WgKgQ(bI_9mKSBy@~{vR42_mQ}c+f^6#b z^g=VN`7WlQT*a~QWo2ayB#gD}nvz8JYSRASgyamaAyP7-)#u}#2`JEQzhbgfID5r&IV*_7#3IL0q{lbKkeoa`T0UMTc3yH)gR($2$YRj66b|BiFt?jlR%FX^zE8a zJQ5LmCG3~Nt{#0%_y{Zdg1RWKWoxc2Ggc%gLRH(p8BZe{y3?;G(=}XiQN9tCTmKKl_uwb``))>8`E!R)VCha!>koh=$^jojZIog>wTcH(#+qw@GqC9ikbyOxlM!i+&u$o~plJ)3~nows> zHuQf;=wW%$B>`y7gvRS_S4-2^${Qw58`q@Gy}fa^lX>nTG##y^!kG!Tm$V)Dl%J2k z)c;Y>Bb7qou%qFj5e)k2r60K~S^P=RjBdrMG&C{wKLe_R4}c?*8f%fwH-N{ggl!%F z@>9?cK0Lnqb=p8mXWgjnKcjtu>)A-YfxbhlnmNN-F#pTBAk1CIPz$Nj4ED0=rI94=(7RV*5SlpF~!HTh&(O=F0rx6Q`W54tmH$Uiv&@OEhsTc^?IyNw9`)idfx_t_}D3mnmF94 z*>_4dtERKexZ_>n#t8LvVy3vBV|ghBb7`LcW=d9E@4;_J90r9Hw86SG6FjxM0!t=* zcDj3BZE0RNx`O=lljhHZCmfZ+sQKN)alg6k5~eaK*y&ZuZtNEccW#)Ro(gQ$ra$+V z7)C)F(x8XVWN#Ga2qrMNdlOox6Ufr2l6p=}ER?VvG_RxB)kMo8BpV$k@|lGp_*Tyd ziHv8}cer|(XPq*^9N_%o?4r%LFa1pFh6Wc$0pszu{|vB6ZB;^ee4MbJy9Kq2Q%IG8 z3jW@#7V0E@gvy0#W3z;9ixF*)rs&C%9G=S^BwsUE_0%TBQ1D}wU(MzW1LLxUM(@x31_c2gEn2oE2DeG!pd1wPnekKBF?FkV=jK>5(|%qNzRc}|hBExieSnd&Xg2WB*9vh}UqgrHfk74N zDlWyxWV2H8)3icWdfCkzBGdFgwF&5nXO#WULjG>a=1EgF0w}m8DVJ5xO40x4&)oKD z$@F%_PAbkVLeRkYisD-ibz`ZmrhO89VCTyqf}{)5 zv)MXI6^UBOGg@!@AiAsI`qK8mAr0wL)KQMf?ty;KmuG6V&W-7f7Rm}`N?SR7{I_kZ zvknu`OV^`XPv6y;pu`(nT_dNT7$B)^d$(fzKhR@m@{KA#BWQ#&V7lKL;p8Nk3459b z)Z8K7hqhad*vX+Uu+(h5!b;>&5Sl!vmf);XKnOZcVPX-cZhm6eQ1{vJ2>$HNH+O{u z(h~f*0rH2yP&4V7uH>9VJba%%Bx6nnqJ)=<<$s_oZ1zH#wEUYcDUms4+OoYQBJ?$L zWAu9wBjlNGR&RY?xg2)o$dY(J{`<3ZepG*h$=nAjqxgk0G4)4)eqCUZ5p$n7Y;8So zG%TWBBwThyEOh$HdjDiG<4;N=hjbG!+Qd$}Bbxl@Q=S}FS{Gt&a9LqA^&B0HUe$; zZ2{RAO7z5JiHl{o=EdCuS$X{q%mznA{tNc+ztB9B#`T%TtVx35>YtL!zmAO(=?z)e zv}WkGE%Yt58fO1eY5^j2YuaRZ$*bjOO3gyA%7d6wOY(2N`j z-t;!s0X zHc`4R8%W5v1<|Kih9aikLjf3?mOS%7@l*>!>vNbTka@^2@|)|u`s<!oEV z6oF(;WMJt|70V5%cphguXQtdB$ajOyFS^+Ob>+qn>l8^x^3%nTci5pUcCgEsXC?ij zfi`?>{j2ugmnF&9=iMWP=^GJfmGPN#XNK4#XWuQK-0+4u^nvI#J=sjpKkvWKezOj8 zO$$@TcUgod9G)5uEci(^Hz|e)RZg7sq9n8JweweE7{$cP=cLpa|-Qi|iZtx##fxR)jzSjLiH1Av^m(tLz+QdjAV%z_?Apu=T!dklG-jlvMF zMP;87K}AqzHx~Df!E&SJGiIOANz$R?jH~CmT7@|%_0$Zxm(0dKjq)Q0CJ9%nQWV%SOgrxS7xaU#KXXO znL{iWBqb`i_5kLq{Ge_rLv0;Z(2BQ|$a`v_d|sB6@`{<6C`g6PiUMUPPEzJF5`opC zAz(N_`Rz8vl%Y#ipzbgE)hh&+&aa z!Xo||cFpi2gDTLh3etthtY!K@R?vu#I7t*Mk{J$i4)LITiT@1>HPT3Dof3ziC7PmY z)ACK00D-%U7Hu&cis~^}O2GPmMM@BlPVvV>FY%WNZ#M>Cu%E1PtMJ};7_W3RS*6Vb z!`BW7U~$@ZsO>qkg+t-OTw<8%Km`hRs^&I0{$SHSn@Y+GXm3{A|v8! zy-YOy_Xx-s=y<+eA7X^W9+nS3D+QPBuKWYvRZG~%-wZjfIOG5v+7q^1X2so=PiVwtAXmQBc#)BCh!uo%=;^_GL zyc6FMe{HD5LY)hRiv-%;rFx+!-7f9^?ac-%8xF6Q*ZklCqYOG{a9Rd2LjIDU)6bi2iB_>c;Kss<+cgO09G&QMk5Uq&+6HC-(z?0 zv%`h-cH`n_ckKFeqbI=-?RAJ0j|4L*;JD>nnLp9;A+W-LA7?GdF+SRZCw^oZT2?vj zSIfYK?t*!ZSJ>|jJkYy^J-%P>=j**Y__$v-{S{XnVC<~*?35sx>RHdFvKKPL-Y&p= zL?S9zfHZLK#I|coIMb(ZtlUl*#iE7)U9~(YVg?NOvQu`EK|gV;<1VR(GV!hh-OfWS zdbgd^LiY&dNvG@W|E!7hU-s%%TWpULu2s3zG4%QAT1gv^OYyTkRf2A>l#uQsIKt#! zV2Ez!@meGna*nZZGMpaFz0S-c{u=8ewbRD}=_i~ywopFT{6zk3Q!rUy^W5QMGQ4~@ ztO0}%_<5(WU~>>qSSPfv$+(Wplbb?Ou1iA#cRTr9S<9}^j4ot&_k4dd$dXbJH`n&s zLsK9ggheCt65nPN7TWxUIfkzveuXAj!ob?E(Mm0(u-xk@c}RXolN|_V%?!^U>7J|~ zy%;>i!t8TK(UV6#IF-eYCwARs5b$0WF?}P`(xC+U#N~myDgXrjMj){83+m;3(EEXy z-vsj1XYd+_w18AroH52$707{r5$_&uKkD4c!>9x^L)_TG`d*v%YAi6TPHej+oI|es zw<3f;79eWgo%!Hml%wc06QE`IQ`_pQ&)xiM(ChHPW?-$}kXmdqTa{kj7F8K;T;233 zxlJ7b!%E|SY6U5#c>M@vSQq2)-dl}ORWwKBVa=KVr7XUtR6Z~fp{ob-vVFq^^vg`!G<7JRqz;j?-JM~-Ztc`g zhR{A!^ehCU3Hm?_Qowl`(heS6IJnm9GDPs-VQC9(9|8hkYfQhmzWnHaSm8O{PTlCQ&m@`2x}Vje*lD$`yl`T diff --git a/app/assets/images/gitlab_modern.png b/app/assets/images/gitlab_modern.png deleted file mode 100644 index b2d73b7a789f048a9947d68a0b942abe57c0b2e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3892 zcmdT{`8(9@+ny0cJz`{EvpsgQSC(WOqQPVzONOWnLbj}>!dSl^`%WUJp`nnyGK4{d z8O;nyLv|YL*xpai_c-3a;Qi(O;ja)#7`fdF=T6N&~eubK&NV6_l`4xCR8v@$I)X-z66& z1uO;r7etQOFg~V{ef9}2tF(p70sKGiwwBhFc)!g8P;>h)UV%RVx ze_t$P?8@?b(TuLo{4iyCdzHNF?jiA5P~v+;iA!gcQ-P+hy^&@^!4l^NV{6d}hcQaK z!^AdTYiE%}eS7Z~7y3USd>SN1u&|0mQ^mNgPj?9520fMGqsiai`C<~I=Tfz+kh$FT7??)D>M@ zZ3VSZua0+S6T}9lJ0daMn#&xu+IL;>-|BBwr(G4$xHs0*R7l_hgV7>POK&_rdF^e? zvRLfVl5U}lf9%s278uTEU*JeS9XaO5Wh8N4+ow))p{y-encO-a*>T$7jzo3C-{>-a zy{P3yx$-GGW?)p!RE~nC ze~rFqc(lD#0TCjH9A5vuyE@_E{!YRKhrMJ{(!V^_DAW9dHxCy*NxpB~b+b^5c0=#v zkbZ+%%GjJW%`4}Fy>KkSOSDhZFC+ZrlI(cMisE70IqHdF^v3R}u!HqfS<~_)7Sr@2 zRY<$3Y(UWlQbx-0g5*O}_{)P1ST0E$Nh5B|05*rDPT{eh8 z`@OdwkSZj;fO43klKU^wQVmf>e?5S2R497DXZbCmBP zob{u9y_+5nPDt~<*Y#|t3JC+8Qa|qnp=5WcN#dUyNO7rUT_H6rk+r;x?jJ1Gu?Z+a>yrBxR_s{l@k^Gp)^y`zz6 z2L}{|2kI1iRtOh3hZ?IiuN7=m$q*SkAgeC-;XWmBU>ZbpLJ6r#mOZAGrajNUTW91os~Ey;CzBo}sSXeB<@ z#oKj6|KK%?v<-15k<^mZ%Pj^*`}OO~AywQvb;D#1#%pf99~IABT9^tv#jZVhD8mQf zm7gmEI7%3ttEX3UtHLCCJn^D3^CX*9$xyM5!_hW<I9nZz~h6+Tjn`0cfAb$4)P z8lb-k)kZ9G`^EYrL_ivbUs+c&4SQKs=?*#_I4rMgUY|JyH1FG%Y0xA>%VU0t7gXre z3F^{T`rgM*jowar@EbTKKHHwDc3AOMRV2bdnRm)GO<2w-;k@0u9s!(1(&d=L@Wq*~ zuBC-cX^U}o4RRvZiutAWtRBi3)t)=_-+G7=>y!CZ?B53-F#uwv-T3j%ZYHllJHTyi z5ep~ZrH9`{;T>K(mirgY&dF_kDt++#gE=ePQQu|sHe?RpvS}tK(R8zdq?J`MGH0is z*q!LtA2CnJfA0&U#I**|&~JT-F!?S{_yp*Rd*tdn7r%_tcQTs%sm`kFl^RV2AW+w%#`?bnX?;*r5383qHa;V1T0S*b~%#2*tb zl#%k?nV2(7nYeXQ8wXVHlz{NVhg=uqG`Px0_loS&V_-0zX0;d=6OF5M{h17JF#ZAAPXejJSP=mn$(BgjfC` zM&7_U)DHkg=4YDD+U?4;u#Sch3nuP1W?9rH@f|?CUk1!{<~Zi3GXIb^z{!QSD`a4y zhH=PSD`vdB3aP*%=fy)y^`n0jD>cEGa+qbc@J%lAgd8cLXirHUk-M-lN<+QC-+$&V z<#ffAy|Q^>S|e1r8Ydgdii_M{x-*!)kCXt_%tY_HUI|&s`eSsQ-`*AX87avQ=-fB; ze^29Gq`VKd)C(pn;;Tsh4lYlzvmO-ys0N7cu~<>5TEN;UIyD$~9_=8Ux?(#161i&o zw`Cru2ggA5ee_M-ppT{-)JoaCQxRCN>XEq*;CTQYxG?q3H@E0=py6qDK`Hm>?QGqR z?o(?1l$PbY(pO9X*Mp1PS;;TTAF{R@Db|ru={jsUJU&=gL-w#vwMR4_ZWGO6LK9CE2K4~&qUXY#zU-^yT`NIO5zLREvB+%B{)^o6k=Cf|!Mi&8ZW}g|m zGv)KdO4FN=XA={jSO!fYiA#j0i|R?_G1)u0GDYsL*%8M9UCII&vmdYo6S*FFZ1vRh z{Fe+mvUf+JVl`30^Mo4zf0E>&KxL7l zTToj=?Cg)cMUTZs4~KQuvy>1`vi*R)P-Yj>vZRpwbS!a3iPVnBFhm`JPyBId48weW zxLCnTck^khTs`LVL(pO1(^YIK$nub z&u|vt1&v9A;g~8Cx6U+AxCj;)?HIE+n@}{K5w=3YsXh2^AieYK9G}-{g~<(6@%@Qf z>GgK{aLC(&lnU-bq>Sgw(_38Rdr>FCPbb;5M>nj`_8bFRMg!bq1d&RrQgLaqc5e1B zCIylo79kTj+YrtET9)~J5HPAbcAu83i`xVZMDJ3odwTnBpW{{hoJ?{?MTNN*TmZn6 zj(qryQ`ohRydjx&l!F1UecR`1$Ne-k3uhhA=O`>S8S6f*L1)2(%kiIww z&OK@qFAov2DS{ldev#?Agjb%qQb~HY@EozpiP%(jZOvMjAGtl^JyN0+Zc1s7(26sE-GUT=N4nEBeR!&#(H z?5NN;y!gU3M#g+kqKE|2hvqt6sTdwrL^}yIHvakN8Y2FkU;mR9-QWSmK>bA&yjQ5I z6sTH)lM11blj%?WylNT>Jy@+*IFWNh7ysrmV*&#$@Xs6AR9^-_f~>gBX_X6XQjbAE zHOw8WS3J%BZPYyh*CVc2vta^^2?p>USIc(ugYOD{n^!OD%RHm(0aLORz-U*b_r`-$ zox&U{TMo9iuM)%#IZU#ae>S*J0o0z;{s(arI8^%e+v~4 z8wT<=$=Uz_37ttqK~z}7?O1DY8`Ty5?&`6UtpwYWBUzH8hb3FqYWJ?}04XU2LMdr* z+9_b@;122VXgh7EGi9JH4J`wN85o9kfR+xFc9^LFGe?Wir{Mx(s+;h&JbMAM)yTJeD5`#dP{8LCNs<YU!VzFFSDwXEaf9dqij4?l@ z^iPr`xeA2>0Kn_@A{vb@auAEf$k^DJ;e!u8KsX$JljFGi2qArfAT+F6wTjg1%CdZ> zGRKY`Bcdq!Wm*1Pu~;+?4Gn#X5W=^$wb^uiLtW|{6h-;GrfCO{969ou)9D;j6y=8& zi)AH%iK(fn%JlTK-h-a@fA;pMqA1q^Sm$&)AL2OfcjE$g=qs=K>e-vqoQe@Qz7fxyN) zb1v-d?F9gIc6P3zl>Rvs3SBPIWxJp45BItSAZ@931@hxeP}l zku&<|%1$nqe>>;=i4!NX4u_-BXf%G9%jGgtQ&WrPjrD_2D1_0`QItxhXB!(E?^-A= zMn*-eft0a@p#;3u~>erY1%CSuz&x40Dz(>S8^O@ zQ50n&f1l64KnPJxCewFBQGAk8%In$IvqUNNF~(k0RrM-O)3S*~;)YtSwu=xF_Ikao z0M6)Yn)Z;UX;Pj-5BUM`hNk4;Zc|6J3wfAZ$doA+=Wrvb>;YPApRZKqPH5`fD@ zQGA3_df9;k2mTXSUtb>pfam!TW6V@26n+4pR!@h@28(tW#k@4jEtv?yb2OD2;kb#`_x>L-rl zfBr}axh_U+rJ*zI=Y^LaR(PK(`c?>8Ea-!Bvj zBWAPN+R)Gt)ikY1Rn^TiGc()lc012;+|M|U8_+cEG=QT3xcT|{Q&y|>!DKS|uI{g+ zqXUNzA4V`3TroB_R+J=ZBV#O-PN$z;e^knHxx58{Hy8{)kWQzSVzJl&fXnCe0DxRB zH*d9Cf5RA~X0!QGo6YtxW9(~;v2j&Z4YRYeAcQc+m{zG&wyCPRk>j{;&d$!>Ix;e{ z-eR$w2`Uf>=s`8P-R`2#=ZgV&6o49!#~ZM;;TAIYTsR!QAArf{^Et1+`f5^-e_hMq z)yJS9soq>S?ZaF3lS(f4Pcyw0z zx+sdDaX1_eu~^Ip04rCnM1Oz(a#(3u=ACglMM8+)Q%x-`Ep|Z=IweWk5s5^cOJg~+ z`?A?A0)YT>xg5-9^E(!cWn8&(B>-U4rcH$B`OhwpgsUV;dQp~T{*oBL-FM$@6a?X|U@*8506ZQ~ zNDzdUdJ3~#W9t%+#{mG1e~pcNOG^voIL<&R?GZ)suMUT!dD&+FD5<9*k|ezmi^ckz znwnZ&E>}0DbOivo-R@=YhxOcT{rdF=kH-@RV2?y18$?mu(cIkJy7aPp)i z(*_73&T_f@R3?*|2?PQdA0I!bZ|;17WilC1N|8t;DyL4Jda_cfOgA+(J??NghRtU4 z6>Hb7)uAE}U@w4w0XU_v4Tr;5RIAlIA>_M?qL}CA=C)=snVCo=a^9dWNjx6U=P0G` zdA(k<-|z1}m!8+_f29ko`0dWl&ds0b4-ow_Vz=7`K@fIDqtSu(_V&Qo*x1q=(W-Db ze0ww+-PPUQeU0807bD~nGKOQvj_FPQjHYQ!)3jd>E&x$`dwY=Q`FjZ=PP^TH*PcCl za4x3%u?D6?#Kgn|wrtsg?c2BC3gB9f;|>x+N~)^%5<=eNQF;E=y?gg+q9`JrPG7VS za;asl=k=6Q4`XaI$8k2s*bB*I@`!%xy4Xy8ETUic7O>7J%d+`W{;e%1{{|3=!G45F RBN_kz002ovPDHLkV1nvM=U4y$ delta 2826 zcmV+l3-$D!6si^>iBL{Q4GJ0x0000DNk~Le0000k0000h2nGNE00(rsgpnaWe+U#3 zHy27(uMhwL3aUv&K~z}7?OA(pRMi>(&fVR6cQ>1C9-D-a>}DU?*S*>MeY;sq@RqiU+{Goy@-jMh>iK8)f1dAgzjMCd`5xy2d^^4!|3?E61tPNe{eEL+ZsW#{ zU%MTg^Yj1RZnqH;EjF8tW%CHx4~((t@p!yVlB8FO=n+ILXlZG=BIC1p5%C5@Y%VJ+ zvtEfjV+_n@bD65Dj~k7~R{-FU&1UoF6soJM`>w;`*a`r8L~KFCqeL_#e?xC=Z5<;s z-rT%-^K?F+?=2#F0}=NjqBEQBak<9GtXjD;d%?F7(FYEPDcDq9tpdpw7?&3g|VIKTk_CQqJxZE0!gyhI|=sMqVOlxhk_s!1Hd-Ud3{$`*T>_*XxF>%!t2|%?K*Md z#4Z4Mn23rPW4FX&f3eMhKp-gy!V97(Hl96uHm|U-5cllabGp0x^Ys)J6*#{B&JP$UuwX1f#-A0nbth`8PB^|~u6D)g7adp2zpT~}08RH3Ts zi$pYth<5@2tXZ=rLpLH~6A>*WqD=q*Wkp4~4X>`Qo~o+qf71W}RaI3p(r^+~RozTP z$E&NWmrZo|lVy1xB7Pvt@`m#V*yFi5y;)n#X7iZSER3G8*=&0lV_pET4h#%*008&- ze47|!H*n6wAAb1Z?JGQM}RP@%#b+AdyJ)0DwD{N|`(!Pfv}< zb7^J4VDMHVf7%HE;BvWsPDE{rqF62khpQbK7$Kq|91idCcsx%uHa6zTvaCfSk!e?? zOi`2v5%FKLEPoV@M$5nIESk}chQQq9#42bAvjI9EIA^`aN$jHc_4;?x*005A0vA~(3p_~S{w6p*s z>KS8B0JuFKk9+ib{kx2@=QT}>W%CnJIp=)e!Gj0g01&$@!@XYb&3e85XI))g-^rf$ z`Fu{Jf6@3hV=SLB#sI*ON~J!I$K${6>gsy*VqR=+ZU!Q91HeYk`7A*Y3OMI607#`$ zshvGNJx!-ipN;_l?C$D7I><_w1!SNZ*ZQ53~>CX?y*(aecNqFxY$ ze8yOOXlSTwU|?XoAP5#w6j!OL`jRZm5&*yhfA`&Yfn3^CKF;}e&iPcv7}qqdX>f4x zDbD#YV@$T&?WGz1hF~yL-af`Tzs>9Q3ZtPaWGjzEA|)o1>3LBUt?ljY!Z>wu-{(I( zCJ4gaR;zV602B`o4|k4?jO;WR3@_&8KF ze;bX)9RR=qU?d)okBsxa-c%}eMij*#WNaKS0kNT>p(y9P{?w^cuf<}qT#iRthbjN42CcOZ0qUi zd5nn0xTm+bcd);|f91%?$Vd74`5XHB`XX&@Z8s&8$t^yg?-tH^i71NK2LgffVc^`k zbEwnl6aXmk`FszSl$3nh(b2Ku`0?XwL{VH8i^X2iH0^=$BAcdZr#a_01Hi}qfBpTv zKVG_Y?BOJ$LICIhfS+ob_A(;s7-OQQX=gJ$PrdL0tX;Ykyk2jfD2l(->-CEV2M60l zQ7kr_&65CtCzHv<$jC^;kt0V=q!UUDV{APDBsu2{0Ah?WHat9>uvjeX+S}V-kHum< zbAYqkx0;%o!lOrz4ur$uqEsrie;oj3FJ8QOxTU4#Lf3>sp-G6i!|isjPbVO&!C)}v ziod~N(CGL3qjhz4QxGvsM88oK<(SjyEYH%pDijL!xm>Q>B9VwnMAtZ-PJgb7a{01l znIfwk0KnmJ1XNYs9SVh>C89{q29=16i1@O{2b<02pE+};v7(})6cM{*S)P7b#a+g*va+%u z5$!-kT|+|yL&Qb^fa|Wie=eu&{Q2{9(!#2mlO}v|%iy+JttIKr`(r2+ntw&bj;PaR z3jEDPbZ2JXZnrlsTC|8wo-`?^Y++$xfvTzx644VxwAt-;-`mj8V9doYePOg~%9JTe z8WK0ivizs3D(;pnSptzr#6(2VR5)t=$Jf2w-TK{{!UcaiU@7L7Sr~m*K zi)DH!6q{h2TsAfjD} zxG;UuQ-_G|i@-)0Z}-CCuvt-*x#xhM3tPQ?J-Q`1#P4>l2taJgJYtJV5! zB9SN%MX^Pv({(Obuz+WkpI)EOw}EqBX)>7>wzajLVE#sYg30U}5v@@aWw$KLOSA3( z8xirJ!C>%_iTpgnCVCOUU~rNsicbT8l`%HRIWK06-I;wC{!RZ7wuFe*{?B~58?R;; czk>Jt7aI_+8J-YZZ2$lO07*qoM6N<$f+;X(IsgCw diff --git a/app/assets/images/logo_white.png b/app/assets/images/logo_white.png index 3f74025449c2e1a3aa4af6052098366e89ae90c2..366e3f3f3b9f16a15f43a7f3fdd04aa2470a177f 100644 GIT binary patch delta 1488 zcmV;>1uy!M4ebjdiBL{Q4GJ0x0000DNk~Le0000d0000a2nGNE017uFn~@VZDZ7sLa5b9wV}0zmLm8Piyw%JQD4MJp|&Vii9+JH=z~=Ipio7lBDLSu z#%9!3Xk$YxLQBNo&j>-`G4=d*82a~-VtA1hj9U)D=cb6 zL{t+6x?!;0^LXu7Rn^k?RCSyBlzP>{0BitJ2h|^{GY(=*syCMJ-UUn=1zPJo5D_1# z-%J2@Bci|2r@Pj9 ze?*v>OMf!+Hua&1xIQ9w0XwRydZ)4Ez(8isjfmlh7>bC&h*+d<%*-P)^O}fQ77=^Y zT@f*onfn?ORp%8jgAs9NX6^-6M#QAd{QoGXrkOpg{yZY~R8{q-()NRhSR4_LsejAN zHR^GhIY)gjGhdB}*CS$gX8x~$KRO~-N5t}on17j>@2Vpa@tZQC^D^_f%zUu)pAiwK zW#-1rytrjx0=EL^0BeA0HP9CWZvgiI-%wWo{bOZXZEO#4qPhMe1%~!FY)~fZ6H;o!EXXW8-}X+)<0~&M~1rudZxr8&I!MuU6+D zj7+I#sW$-^G-ow1q`p2bjRRH#&o;TaUw?fK*aQ4WeNVj~7;F&|qtEKrUiCWQ!V+IQfu1J& zGt_O(n5vqj^r~AU;)tvZ>L=Hm>IV_=p?YmZJRT9dGV{8KxLX~rsw!&3HmSF(%YP%{ z#fW$#Gj~NqPiDSVRn`8w@yz^hM9cv$R|iJz)VOCD*siXryQZ!Z>bvSa>U?0KIz|19 zdS7i72GrlFe^tK%%mh{d&#BJ?C$z9VsjTh`>ahpJvU+)8=>#gZrzw^yU}iP1~cO|4?D0&W3rDg&pe-7SJVf!T%S z7pr%wzi*UBW##{&ZUmM9E7YkCJ2g)={->4puK_Os-&gzECB+u?<^tr{2Eg*%F5B;| zjqh&=cpI9kPjpW4(n;#mZ3(~rado@;?Q%c24zLZ6O>TPb?W7XwOrQr?rGGx%!baQD zxu?{2(}BLCvtxnlFR`{kJsarjApFOuLuw!JxH>d0iL3!!RRB%_jsljoGoUU9_NpVm zze=Us4%k%SIJFnJ7g#@TU2Xd4`M?$+fm!OwtqcKOzy+ncSOa963HJi$miw!KAE{l3 zTGpg`gZh)gMKkNV+Q|(~0)IcKt|;x7s9QV5=6DU?s%|co@B(!fP>r{gDq*n{=v9AQ z=%??nO0g!2`EC*WW7Ik7^xC^_^$hiU>gi>xIGV{teZHh_D`onmLyEJpDi-w&V28R^ zoeNAa1e(AQFi)LPBjg@nA+TEAp{}3sBao(&YL>bk_!h88ty=Xj)PJ+IY+#;Hk8hT( zPFEhRn=>1zNz5rO3nH$PJb#rF!0a~Ahd>SWGMF$@NHa7OL zg;q8cmDzkaZp=dkn3;|9jwR}O5ivO;UWjB;Bxxi1= qZvwrai*vtv2~>nUCmDn$BI08Pewc~WiBL{Q4GJ0x0000DNk~Le0000k0000h2nGNE00(rsgpnZ@2><{9 z008+zyMK{DAAblG6B-YA(FdLY00t3BL_t(o!|j<_Y}8d0#_x2xOrZ;9DTON178oeB z2|GxE07{V{1w+KxrX`TDXaxgd6O4g}GKSrVF)nBTQBb2%iHah|B^Db{P&SQ-Pz7Yg{l_-JAr3_d}E9$ zA3xsHgnxj3z%<}q;1ghh+AF1uJAeUzKm5>+mV0ae$AHdi%K|tg4>$^x+O~pj z-3%}e_y(97HogO}5jX=J0@ec4fg!F<0>fo`AL`n-TID!n=19u}H*MNv+kBGgEYKmE z;6C76AP>0H7-Q<{>TF*=@GMXVjL|K;4$K3(cz>-I3WZF?@ z8nD(FV{&tHq6&T^utonz>K2lK4Z4k*R)D`-WG44HZIkr76DWvh5kIgO$OhW0Z9VWA zkbm3K`0hAn2JjxR%JH{CIkvAyQBhnPm;&t6{|A60Kt?QcXl}7)1f&25q^P#Qr@)9r zuWyC4eAYr!YerE=^KFG}#}YQnMGF_&MfL-Ou2krEKp-F3pU}R}D#;)4*&X z)not83RbC!2t5gS*Q33=NZ1d+kHX&*z{)spu@Kk=oCp2@eg%F8o_7VTKYrYf-wI5N z*F;i9kh*vXK3zh82fQyK8int>fHY%_S-N4AVXkD!#-2{;av#YOI%2-inu>a|so5ZOuf`|Uy-?0?Hd^>Ki&YhGTo+sYDptk?WSZk{H*r2XBb`Z{Ti=bA_TV5q(}Q2kzKf*@I}z?QX$krZ|hgq`25~PE%8p z^^0WSO<NHJ@Od2smE|Q5{ATJ^)s?Wctq63fj*z#%wXhWIh{Xnv5~+jWM%)KHsVT z%7?Hj`&FVfN^)zU4q$vf-;RqgYK-}_h4=Xj|A5=F>y1FP00000NkvXXu0mjfqfQbV diff --git a/app/assets/stylesheets/common.scss b/app/assets/stylesheets/common.scss index aeaddb0b..e45cb876 100644 --- a/app/assets/stylesheets/common.scss +++ b/app/assets/stylesheets/common.scss @@ -584,25 +584,6 @@ li.note { } } -.themes_opts { - padding-left:20px; - - label { - width:175px; - margin-right:40px; - - .prev { - @extend .thumbnail; - height:120px; - width:175px; - margin-bottom:10px; - img { - width:180px; - } - } - } -} - .git_error_tips { @extend .span6; text-align:left; diff --git a/app/assets/stylesheets/main.scss b/app/assets/stylesheets/main.scss index 099d5043..7ae32b3a 100644 --- a/app/assets/stylesheets/main.scss +++ b/app/assets/stylesheets/main.scss @@ -118,14 +118,12 @@ $monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono' @import "themes/ui_basic.scss"; /** - * UI mars theme + * UI themes: */ @import "themes/ui_mars.scss"; - -/** - * UI Modern theme - */ @import "themes/ui_modern.scss"; +@import "themes/ui_gray.scss"; +@import "themes/ui_color.scss"; /** * GitLab bootstrap. @@ -159,6 +157,7 @@ $monospace: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono' @import "sections/merge_requests.scss"; @import "sections/graph.scss"; @import "sections/events.scss"; +@import "sections/themes.scss"; /** * This scss file redefine chozen selectbox styles for diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss index 90a57363..32f6d855 100644 --- a/app/assets/stylesheets/sections/header.scss +++ b/app/assets/stylesheets/sections/header.scss @@ -39,15 +39,15 @@ header { h1 { width:90px; - background: url('logo_dark.png') no-repeat 0px -3px; + background: url('logo_dark.png') no-repeat 0px 2px; float:left; - margin-left:5px; + margin-left:2px; font-size:30px; line-height:48px; font-weight:normal; color:$style_color; text-shadow: 0 1px 1px #FFF; - padding-left:50px; + padding-left:45px; height:40px; font-family: 'Korolev', sans-serif; } @@ -98,7 +98,7 @@ header { background-position: 10px; padding-left:25px; font-size: 13px; - @include border-radius(2px); + @include border-radius(3px); border:1px solid #c6c6c6; box-shadow:none; &:focus { @@ -123,7 +123,7 @@ header { display: block; cursor: pointer; img { - @include border-radius(2px); + @include border-radius(3px); right: 5px; position: absolute; width: 28px; diff --git a/app/assets/stylesheets/sections/themes.scss b/app/assets/stylesheets/sections/themes.scss new file mode 100644 index 00000000..62dd27d0 --- /dev/null +++ b/app/assets/stylesheets/sections/themes.scss @@ -0,0 +1,53 @@ +.themes_opts { + padding-left:20px; + + label { + width:175px; + margin-right:40px; + + .prev { + @extend .thumbnail; + height:30px; + width:175px; + margin-bottom:10px; + + &.classic { + background: #31363e; + } + + &.default { + background: #f1f1f1; + } + + &.modern { + background: #567; + } + + &.gray { + background: #708090; + } + + &.violet { + background: #657; + } + } + } +} + +.code_highlight_opts { + padding-left:20px; + + label { + width:220px; + margin-right:40px; + + .prev { + @extend .thumbnail; + height:151px; + width:220px; + margin-bottom:10px; + } + } +} + + diff --git a/app/assets/stylesheets/themes/ui_color.scss b/app/assets/stylesheets/themes/ui_color.scss new file mode 100644 index 00000000..4497892d --- /dev/null +++ b/app/assets/stylesheets/themes/ui_color.scss @@ -0,0 +1,68 @@ +/** + * This file represent some UI that can be changed + * during web app restyle or theme select. + * + * Next items should be placed there + * - link colors + * - header restyles + * + */ +.ui_color { + + /* + * Application Header + * + */ + header { + + &.navbar-gitlab { + .navbar-inner { + background: #657; + border-bottom: 1px solid #AAA; + + .nav > li > a { + color: #fff; + text-shadow: 0 1px 0 #111; + } + } + } + + .search { + float: right; + margin-right: 45px; + .search-input { + border: 1px solid #aaa; + background-color: #D2D5DA; + background-color: rgba(255, 255, 255, 0.5); + + &:focus { + background-color: white; + } + } + } + .search-input::-webkit-input-placeholder { + color: #666; + } + .app_logo { + a { + h1 { + background: url('logo_white.png') no-repeat 0px 2px; + color:#fff; + text-shadow: 0 1px 1px #111; + } + } + .separator { + display:none; + } + + } + .project_name { + color:#fff; + text-shadow: 0 1px 1px #111; + } + } + /* + * End of Application Header + * + */ +} diff --git a/app/assets/stylesheets/themes/ui_gray.scss b/app/assets/stylesheets/themes/ui_gray.scss new file mode 100644 index 00000000..5ee2b0dd --- /dev/null +++ b/app/assets/stylesheets/themes/ui_gray.scss @@ -0,0 +1,68 @@ +/** + * This file represent some UI that can be changed + * during web app restyle or theme select. + * + * Next items should be placed there + * - link colors + * - header restyles + * + */ +.ui_gray { + + /* + * Application Header + * + */ + header { + + &.navbar-gitlab { + .navbar-inner { + background: #708090; + border-bottom: 1px solid #AAA; + + .nav > li > a { + color: #fff; + text-shadow: 0 1px 0 #111; + } + } + } + + .search { + float: right; + margin-right: 45px; + .search-input { + border: 1px solid #aaa; + background-color: #D2D5DA; + background-color: rgba(255, 255, 255, 0.5); + + &:focus { + background-color: white; + } + } + } + .search-input::-webkit-input-placeholder { + color: #666; + } + .app_logo { + a { + h1 { + background: url('logo_white.png') no-repeat 0px 2px; + color:#fff; + text-shadow: 0 1px 1px #111; + } + } + .separator { + display:none; + } + + } + .project_name { + color:#fff; + text-shadow: 0 1px 1px #111; + } + } + /* + * End of Application Header + * + */ +} diff --git a/app/assets/stylesheets/themes/ui_mars.scss b/app/assets/stylesheets/themes/ui_mars.scss index 3773e61c..a9d21241 100644 --- a/app/assets/stylesheets/themes/ui_mars.scss +++ b/app/assets/stylesheets/themes/ui_mars.scss @@ -46,7 +46,7 @@ .app_logo { a { h1 { - background: url('logo_white.png') no-repeat 0px -3px; + background: url('logo_white.png') no-repeat 0px 2px; color:#eee; text-shadow: 0 1px 1px #111; } diff --git a/app/assets/stylesheets/themes/ui_modern.scss b/app/assets/stylesheets/themes/ui_modern.scss index 73445ec6..0bb14cdd 100644 --- a/app/assets/stylesheets/themes/ui_modern.scss +++ b/app/assets/stylesheets/themes/ui_modern.scss @@ -17,11 +17,11 @@ &.navbar-gitlab { .navbar-inner { - background: #333; - border-bottom: 1px solid #111; + background: #567; + border-bottom: 1px solid #AAA; .nav > li > a { - color: #eee; + color: #fff; text-shadow: 0 1px 0 #111; } } @@ -31,7 +31,7 @@ float: right; margin-right: 45px; .search-input { - border: 1px solid rgba(0, 0, 0, 0.7); + border: 1px solid #aaa; background-color: #D2D5DA; background-color: rgba(255, 255, 255, 0.5); @@ -46,8 +46,8 @@ .app_logo { a { h1 { - background: url('logo_white.png') no-repeat 0px -3px; - color:#eee; + background: url('logo_white.png') no-repeat 0px 2px; + color:#fff; text-shadow: 0 1px 1px #111; } } @@ -57,7 +57,7 @@ } .project_name { - color:#eee; + color:#fff; text-shadow: 0 1px 1px #111; } } diff --git a/app/views/profile/design.html.haml b/app/views/profile/design.html.haml index 4eace607..5099ea5d 100644 --- a/app/views/profile/design.html.haml +++ b/app/views/profile/design.html.haml @@ -3,28 +3,35 @@ %legend Application theme .themes_opts = label_tag do - .prev - = image_tag "gitlab_default.png" + .prev.default = f.radio_button :theme_id, 1 Default = label_tag do - .prev - = image_tag "gitlab_classic.png" + .prev.classic = f.radio_button :theme_id, 2 Classic = label_tag do - .prev - = image_tag "gitlab_modern.png" + .prev.modern = f.radio_button :theme_id, 3 Modern + + = label_tag do + .prev.gray + = f.radio_button :theme_id, 4 + SlateGray + + = label_tag do + .prev.violet + = f.radio_button :theme_id, 5 + Violet %br .clearfix %fieldset %legend Code review - .themes_opts + .code_highlight_opts = label_tag do .prev = image_tag "white.png" diff --git a/lib/gitlab/theme.rb b/lib/gitlab/theme.rb index 6e2be765..7f833867 100644 --- a/lib/gitlab/theme.rb +++ b/lib/gitlab/theme.rb @@ -1,10 +1,12 @@ module Gitlab class Theme def self.css_class_by_id(id) - themes = { + themes = { 1 => "ui_basic", 2 => "ui_mars", - 3 => "ui_modern" + 3 => "ui_modern", + 4 => "ui_gray", + 5 => "ui_color" } id ||= 1 From 1de0ea28b957068bff7d5a5eaac82956b7529560 Mon Sep 17 00:00:00 2001 From: Koen Punt Date: Wed, 21 Nov 2012 18:25:32 +0100 Subject: [PATCH 180/187] added bg for transparent images added width and height below images in diff --- app/assets/images/trans_bg.gif | Bin 0 -> 58 bytes app/assets/stylesheets/sections/commits.scss | 5 ++++- app/views/commit/show.html.haml | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 app/assets/images/trans_bg.gif diff --git a/app/assets/images/trans_bg.gif b/app/assets/images/trans_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..c7e98e044f578204f9c1ebdefcb05f4b2baaea32 GIT binary patch literal 58 zcmZ?wbhEHbQxZ@ literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/sections/commits.scss b/app/assets/stylesheets/sections/commits.scss index 440bfed7..9cce5bd0 100644 --- a/app/assets/stylesheets/sections/commits.scss +++ b/app/assets/stylesheets/sections/commits.scss @@ -133,9 +133,12 @@ .image { display: inline-block; margin:50px; - padding:1px; max-width:400px; + img{ + background: url('trans_bg.gif'); + } + &.diff_removed { img{ border: 1px solid #C00; diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml index d12fff96..432d55b1 100644 --- a/app/views/commit/show.html.haml +++ b/app/views/commit/show.html.haml @@ -7,4 +7,19 @@ :javascript $(function(){ PerLineNotes.init(); + var w, h; + $('.diff_file').each(function(){ + $('.image.diff_removed img', this).on('load', $.proxy(function(event){ + var w = event.currentTarget.naturalWidth + , h = event.currentTarget.naturalHeight; + $('.image.diff_removed .image-info', this).append(' | W: ' + w + 'px | H: ' + h + 'px'); + }, this)); + $('.image.diff_added img', this).on('load', $.proxy(function(event){ + var w = event.currentTarget.naturalWidth + , h = event.currentTarget.naturalHeight; + $('.image.diff_added .image-info', this).append(' | W: ' + w + 'px | H: ' + h + 'px'); + }, this)); + + }); + }); From 1cda62465f60adf5abbcde443fbb1cb1e402a407 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 21 Nov 2012 20:02:03 +0100 Subject: [PATCH 181/187] Fix GFM JS code style --- .../javascripts/gfm_auto_complete.js.coffee | 52 ++++++++++--------- .../layouts/_init_auto_complete.html.haml | 8 +-- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 6c0c8886..9e7c3c89 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -1,47 +1,51 @@ # Creates the variables for setting up GFM auto-completion +window.GitLab ?= {} +window.GitLab.AutoComplete ?= {} + # Emoji data = [] template = "
  • ${name} ${name}
  • " -window.autocompleteEmoji = {data, template} +window.GitLab.AutoComplete.Emoji = {data, template} # Team Members url = ''; params = {private_token: '', page: 1} -window.autocompleteMembers = {data, url, params} +window.GitLab.AutoComplete.Members = {data, url, params} # Add GFM auto-completion to all input fields, that accept GFM input. window.setupGfmAutoComplete = -> - $input = $('.js-gfm-input') + input = $('.js-gfm-input') # Emoji - $input.atWho ':', - data: autocompleteEmoji.data, - tpl: autocompleteEmoji.template + input.atWho ':', + data: GitLab.AutoComplete.Emoji.data, + tpl: GitLab.AutoComplete.Emoji.template # Team Members - $input.atWho '@', (query, callback) -> + input.atWho '@', (query, callback) -> (getMoreMembers = -> - $.getJSON(autocompleteMembers.url, autocompleteMembers.params).success (members) -> - # pick the data we need - newMembersData = $.map members, (m) -> m.name + $.getJSON(GitLab.AutoComplete.Members.url, GitLab.AutoComplete.Members.params) + .success (members) -> + # pick the data we need + newMembersData = $.map(members, (m) -> m.name ) - # add the new page of data to the rest - $.merge autocompleteMembers.data, newMembersData + # add the new page of data to the rest + $.merge(GitLab.AutoComplete.Members.data, newMembersData) - # show the pop-up with a copy of the current data - callback autocompleteMembers.data[..] + # show the pop-up with a copy of the current data + callback(GitLab.AutoComplete.Members.data[..]) - # 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() + # are we past the last page? + if newMembersData.length is 0 + # set static data and stop callbacks + input.atWho '@', + data: GitLab.AutoComplete.Members.data + callback: null + else + # get next page + getMoreMembers() # so the next request gets the next page - autocompleteMembers.params.page += 1 + GitLab.AutoComplete.Members.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 9eadc18c..225c378f 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() { - autocompleteMembers.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; - autocompleteMembers.params.private_token = "#{current_user.private_token}"; + GitLab.AutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; + GitLab.AutoComplete.Members.params.private_token = "#{current_user.private_token}"; - autocompleteEmoji.data = #{raw emoji_autocomplete_source}; + GitLab.AutoComplete.Emoji.data = #{raw emoji_autocomplete_source}; // convert the list so that the items have the right format for completion - autocompleteEmoji.data = $.map(autocompleteEmoji.data, function(value) { + GitLab.AutoComplete.Emoji.data = $.map(GitLab.AutoComplete.Emoji.data, function(value) { return { name: value, insert: value+':', From 3e800c3bb1b835cd17e32eedd8816bc17f6317e4 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 21 Nov 2012 20:23:19 +0100 Subject: [PATCH 182/187] Refactor GFM JS naming and access --- .../javascripts/gfm_auto_complete.js.coffee | 23 ++++++++++--------- app/assets/javascripts/issues.js | 4 ++-- .../layouts/_init_auto_complete.html.haml | 10 ++++---- app/views/notes/_create_common_note.js.haml | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 9e7c3c89..ffc4c409 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -1,51 +1,52 @@ # Creates the variables for setting up GFM auto-completion window.GitLab ?= {} -window.GitLab.AutoComplete ?= {} +GitLab.GfmAutoComplete ?= {} # Emoji data = [] template = "
  • ${name} ${name}
  • " -window.GitLab.AutoComplete.Emoji = {data, template} +GitLab.GfmAutoComplete.Emoji = {data, template} # Team Members +data = [] url = ''; params = {private_token: '', page: 1} -window.GitLab.AutoComplete.Members = {data, url, params} +GitLab.GfmAutoComplete.Members = {data, url, params} # Add GFM auto-completion to all input fields, that accept GFM input. -window.setupGfmAutoComplete = -> +GitLab.GfmAutoComplete.setup = -> input = $('.js-gfm-input') # Emoji input.atWho ':', - data: GitLab.AutoComplete.Emoji.data, - tpl: GitLab.AutoComplete.Emoji.template + data: GitLab.GfmAutoComplete.Emoji.data, + tpl: GitLab.GfmAutoComplete.Emoji.template # Team Members input.atWho '@', (query, callback) -> (getMoreMembers = -> - $.getJSON(GitLab.AutoComplete.Members.url, GitLab.AutoComplete.Members.params) + $.getJSON(GitLab.GfmAutoComplete.Members.url, GitLab.GfmAutoComplete.Members.params) .success (members) -> # pick the data we need newMembersData = $.map(members, (m) -> m.name ) # add the new page of data to the rest - $.merge(GitLab.AutoComplete.Members.data, newMembersData) + $.merge(GitLab.GfmAutoComplete.Members.data, newMembersData) # show the pop-up with a copy of the current data - callback(GitLab.AutoComplete.Members.data[..]) + callback(GitLab.GfmAutoComplete.Members.data[..]) # are we past the last page? if newMembersData.length is 0 # set static data and stop callbacks input.atWho '@', - data: GitLab.AutoComplete.Members.data + data: GitLab.GfmAutoComplete.Members.data callback: null else # get next page getMoreMembers() # so the next request gets the next page - GitLab.AutoComplete.Members.params.page += 1 + GitLab.GfmAutoComplete.Members.params.page += 1 ).call() diff --git a/app/assets/javascripts/issues.js b/app/assets/javascripts/issues.js index 55db72c3..e2fe1075 100644 --- a/app/assets/javascripts/issues.js +++ b/app/assets/javascripts/issues.js @@ -5,7 +5,7 @@ function switchToNewIssue(){ $("#new_issue_dialog").show("fade", { direction: "right" }, 150); $('.top-tabs .add_new').hide(); disableButtonIfEmptyField("#issue_title", ".save-btn"); - setupGfmAutoComplete(); + GitLab.GfmAutoComplete.setup(); }); } @@ -16,7 +16,7 @@ function switchToEditIssue(){ $("#edit_issue_dialog").show("fade", { direction: "right" }, 150); $('.add_new').hide(); disableButtonIfEmptyField("#issue_title", ".save-btn"); - setupGfmAutoComplete(); + GitLab.GfmAutoComplete.setup(); }); } diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml index 225c378f..502f289e 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() { - GitLab.AutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; - GitLab.AutoComplete.Members.params.private_token = "#{current_user.private_token}"; + GitLab.GfmAutoComplete.Members.url = "#{ "/api/v2/projects/#{@project.code}/members" if @project }"; + GitLab.GfmAutoComplete.Members.params.private_token = "#{current_user.private_token}"; - GitLab.AutoComplete.Emoji.data = #{raw emoji_autocomplete_source}; + GitLab.GfmAutoComplete.Emoji.data = #{raw emoji_autocomplete_source}; // convert the list so that the items have the right format for completion - GitLab.AutoComplete.Emoji.data = $.map(GitLab.AutoComplete.Emoji.data, function(value) { + GitLab.GfmAutoComplete.Emoji.data = $.map(GitLab.GfmAutoComplete.Emoji.data, function(value) { return { name: value, insert: value+':', @@ -13,5 +13,5 @@ } }); - setupGfmAutoComplete(); + GitLab.GfmAutoComplete.setup(); }); diff --git a/app/views/notes/_create_common_note.js.haml b/app/views/notes/_create_common_note.js.haml index e7df64c4..a96cc7b3 100644 --- a/app/views/notes/_create_common_note.js.haml +++ b/app/views/notes/_create_common_note.js.haml @@ -10,5 +10,5 @@ - else :plain $(".note-form-holder").replaceWith("#{escape_javascript(render 'form')}"); - setupGfmAutoComplete(); + GitLab.GfmAutoComplete.setup(); From d7ce2c5c0736de54478d96e8d11b3b9dc4fcb5e2 Mon Sep 17 00:00:00 2001 From: Riyad Preukschas Date: Wed, 21 Nov 2012 20:26:37 +0100 Subject: [PATCH 183/187] Fix rendering template for invalid notes --- app/views/notes/_create_common_note.js.haml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/notes/_create_common_note.js.haml b/app/views/notes/_create_common_note.js.haml index a96cc7b3..217c9080 100644 --- a/app/views/notes/_create_common_note.js.haml +++ b/app/views/notes/_create_common_note.js.haml @@ -9,6 +9,5 @@ - else :plain - $(".note-form-holder").replaceWith("#{escape_javascript(render 'form')}"); - + $(".note-form-holder").replaceWith("#{escape_javascript(render 'notes/common_form')}"); GitLab.GfmAutoComplete.setup(); From 30a66c065a14be05f05099118938fb20c8989b3e Mon Sep 17 00:00:00 2001 From: Robert Speicher Date: Wed, 21 Nov 2012 15:01:40 -0500 Subject: [PATCH 184/187] Improve user feedback on the Profile > Design page - Header changes immediately without a page reload - Lets the user know that we actually saved their setting when changed --- app/assets/javascripts/profile.js.coffee | 10 +++++++++ app/assets/stylesheets/sections/themes.scss | 7 +++++++ app/controllers/profile_controller.rb | 6 +++++- app/views/profile/design.html.haml | 23 +++++++++++---------- app/views/profile/update.js.erb | 9 ++++++++ features/profile/profile.feature | 13 ++++++++++++ features/steps/profile/profile.rb | 17 +++++++++++++++ 7 files changed, 73 insertions(+), 12 deletions(-) create mode 100644 app/assets/javascripts/profile.js.coffee create mode 100644 app/views/profile/update.js.erb diff --git a/app/assets/javascripts/profile.js.coffee b/app/assets/javascripts/profile.js.coffee new file mode 100644 index 00000000..e536afad --- /dev/null +++ b/app/assets/javascripts/profile.js.coffee @@ -0,0 +1,10 @@ +$ -> + $('.edit_user .application-theme input, .edit_user .code-preview-theme input').click -> + # Hide any previous submission feedback + $('.edit_user .update-feedback').hide() + + # Submit the form + $('.edit_user').submit() + + # Go up the hierarchy and show the corresponding submission feedback element + $(@).closest('fieldset').find('.update-feedback').show('highlight', {color: '#DFF0D8'}, 500) diff --git a/app/assets/stylesheets/sections/themes.scss b/app/assets/stylesheets/sections/themes.scss index 62dd27d0..2d121519 100644 --- a/app/assets/stylesheets/sections/themes.scss +++ b/app/assets/stylesheets/sections/themes.scss @@ -1,3 +1,10 @@ +.application-theme, .code-preview-theme { + .update-feedback { + color: #468847; + float: right; + } +} + .themes_opts { padding-left:20px; diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb index 38cfa896..5f8b11fd 100644 --- a/app/controllers/profile_controller.rb +++ b/app/controllers/profile_controller.rb @@ -9,7 +9,11 @@ class ProfileController < ApplicationController def update @user.update_attributes(params[:user]) - redirect_to :back + + respond_to do |format| + format.html { redirect_to :back } + format.js + end end def token diff --git a/app/views/profile/design.html.haml b/app/views/profile/design.html.haml index 5099ea5d..502cca42 100644 --- a/app/views/profile/design.html.haml +++ b/app/views/profile/design.html.haml @@ -1,6 +1,10 @@ = form_for @user, url: profile_update_path, remote: true, method: :put do |f| - %fieldset - %legend Application theme + %fieldset.application-theme + %legend + Application theme + .update-feedback.hide + %i.icon-ok + Saved .themes_opts = label_tag do .prev.default @@ -29,8 +33,12 @@ %br .clearfix - %fieldset - %legend Code review + %fieldset.code-preview-theme + %legend + Code preview theme + .update-feedback.hide + %i.icon-ok + Saved .code_highlight_opts = label_tag do .prev @@ -42,10 +50,3 @@ = image_tag "dark.png" = f.radio_button :dark_scheme, true Dark code preview - -:javascript - $(function(){ - $(".edit_user input").bind("click", function() { - $(".edit_user").submit(); - }); - }) diff --git a/app/views/profile/update.js.erb b/app/views/profile/update.js.erb new file mode 100644 index 00000000..04b5cf48 --- /dev/null +++ b/app/views/profile/update.js.erb @@ -0,0 +1,9 @@ +// Remove body class for any previous theme, re-add current one +$('body').removeClass('ui_basic ui_mars ui_modern ui_gray ui_color') +$('body').addClass('<%= app_theme %>') + +// Re-render the header to reflect the new theme +$('header').html('<%= escape_javascript(render("layouts/head_panel", title: "Profile")) %>') + +// Re-initialize header tooltips +$('.has_bottom_tooltip').tooltip({placement: 'bottom'}) diff --git a/features/profile/profile.feature b/features/profile/profile.feature index a98988b8..95b85a9f 100644 --- a/features/profile/profile.feature +++ b/features/profile/profile.feature @@ -30,3 +30,16 @@ Feature: Profile Given I have activity When I visit profile history page Then I should see my activity + + @javascript + Scenario: I change my application theme + Given I visit profile design page + When I change my application theme + Then I should see the theme change immediately + And I should receive feedback that the changes were saved + + @javascript + Scenario: I change my code preview theme + Given I visit profile design page + When I change my code preview theme + Then I should receive feedback that the changes were saved diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb index 151182f6..b6833f2b 100644 --- a/features/steps/profile/profile.rb +++ b/features/steps/profile/profile.rb @@ -59,4 +59,21 @@ class Profile < Spinach::FeatureSteps Then 'I should see my activity' do page.should have_content "#{current_user.name} closed issue" end + + When "I change my application theme" do + choose "Violet" + end + + When "I change my code preview theme" do + choose "Dark code preview" + end + + Then "I should see the theme change immediately" do + page.should have_selector('body.ui_color') + page.should_not have_selector('body.ui_basic') + end + + Then "I should receive feedback that the changes were saved" do + page.should have_content("Saved") + end end From 71ff619973d52c22e49303883aaa77801be378c7 Mon Sep 17 00:00:00 2001 From: Gosuke Miyashita Date: Thu, 22 Nov 2012 10:38:56 +0900 Subject: [PATCH 185/187] Fix hash key settings["gitlab_version"] to settings[:gitlab_version] In backup_create, backup information hash is using symbol as its key. But in backup_restore, string key is used and it returns empty value. --- lib/tasks/gitlab/backup.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/gitlab/backup.rake b/lib/tasks/gitlab/backup.rake index 06d7cb65..17a0e336 100644 --- a/lib/tasks/gitlab/backup.rake +++ b/lib/tasks/gitlab/backup.rake @@ -85,11 +85,11 @@ namespace :gitlab do ENV["VERSION"] = "#{settings["db_version"]}" if settings["db_version"].to_i > 0 # restoring mismatching backups can lead to unexpected problems - if settings["gitlab_version"] != %x{git rev-parse HEAD}.gsub(/\n/,"") + if settings[:gitlab_version] != %x{git rev-parse HEAD}.gsub(/\n/,"") puts "gitlab_version mismatch:".red puts " Your current HEAD differs from the HEAD in the backup!".red puts " Please switch to the following revision and try again:".red - puts " revision: #{settings["gitlab_version"]}".red + puts " revision: #{settings[:gitlab_version]}".red exit 1 end From 65327cfc081030a3c7e4df978c2a346dd71895ab Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 22 Nov 2012 12:24:46 +0200 Subject: [PATCH 186/187] Rewrite hooks shell script --- lib/support/rewrite-hooks.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100755 lib/support/rewrite-hooks.sh diff --git a/lib/support/rewrite-hooks.sh b/lib/support/rewrite-hooks.sh new file mode 100755 index 00000000..6688785a --- /dev/null +++ b/lib/support/rewrite-hooks.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +src="/home/git/repositories" + +for dir in `ls "$src/"` +do + if [ -d "$src/$dir" ]; then + + if [ "$dir" = "gitolite-admin.git" ] + then + continue + fi + + project_hook="$src/$dir/hooks/post-receive" + gitolite_hook="/home/git/.gitolite/hooks/common/post-receive" + + ln -s -f $gitolite_hook $project_hook + fi +done From ced242a2d09b65494ae8752b882fa4beed8b58c5 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 22 Nov 2012 12:45:16 +0200 Subject: [PATCH 187/187] Up to 3.1.0 --- ROADMAP.md | 1 + VERSION | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index 465342f8..295a5244 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -5,6 +5,7 @@ * Help page for service tasks like repos import, backup etc * Hide last push widget after following link * Add comment events +* gitolite namespaces for projects per user/group. It will allow us same project names for different users ### Issues diff --git a/VERSION b/VERSION index 1c452795..fd2a0186 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.1.0pre +3.1.0